@stonecrop/nuxt 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 +79 -34
- package/dist/module.json +1 -1
- package/dist/runtime/app/composables/useStonecropRegistry.d.ts +40 -38
- package/dist/runtime/app/composables/useStonecropRegistry.js +31 -11
- package/dist/runtime/app/composables/useStonecropSetup.d.ts +108 -0
- package/dist/runtime/app/composables/useStonecropSetup.js +100 -0
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -102,20 +102,26 @@ The module picks up this file and, if `pageComponent` is configured, registers a
|
|
|
102
102
|
|
|
103
103
|
### Wire Up Your Data Client
|
|
104
104
|
|
|
105
|
-
After installing the module, add a client-side plugin to connect your data transport.
|
|
105
|
+
After installing the module, add a client-side plugin to connect your data transport. Use `useStonecropSetup()` in plugins — it's designed for the initialization context where Stonecrop may not be fully ready yet:
|
|
106
106
|
|
|
107
107
|
```typescript
|
|
108
108
|
// app/plugins/stonecrop.client.ts
|
|
109
109
|
import { StonecropClient } from '@stonecrop/graphql-client'
|
|
110
110
|
|
|
111
111
|
export default defineNuxtPlugin(() => {
|
|
112
|
+
const { registerClient, registerMeta } = useStonecropSetup()
|
|
113
|
+
|
|
112
114
|
const client = new StonecropClient({ endpoint: '/graphql' })
|
|
113
|
-
const { setMeta, setFetchRecord, setFetchRecords } = useStonecropRegistry()
|
|
114
115
|
|
|
115
|
-
//
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
116
|
+
// Register the data client for record fetching
|
|
117
|
+
registerClient(client)
|
|
118
|
+
|
|
119
|
+
// Configure metadata fetching for lazy-loaded doctypes
|
|
120
|
+
// Called by useStonecrop() when it needs doctype metadata
|
|
121
|
+
registerMeta(({ segments }) => {
|
|
122
|
+
const doctype = segments[0] // e.g., "task" from /task/123
|
|
123
|
+
return client.getMeta({ doctype })
|
|
124
|
+
})
|
|
119
125
|
})
|
|
120
126
|
```
|
|
121
127
|
|
|
@@ -321,48 +327,87 @@ The module auto-registers:
|
|
|
321
327
|
- **Self-Documenting**: Schemas serve as data model documentation
|
|
322
328
|
- **Easy Updates**: Change schema, UI updates automatically
|
|
323
329
|
|
|
324
|
-
## `
|
|
325
|
-
|
|
326
|
-
The `@stonecrop/nuxt` runtime plugin installs `StonecropPlugin` with a router but no data transport, because data clients (GraphQL, tRPC, REST) are application-defined and cannot be serialised through `nuxt.config.ts` module options.
|
|
330
|
+
## `useStonecropSetup()` — Configuring the Framework in Plugins
|
|
327
331
|
|
|
328
|
-
`
|
|
332
|
+
When you need to configure Stonecrop during Nuxt plugin initialization (before components mount), use `useStonecropSetup()`. This composable is designed specifically for the plugin context and returns values that may be `undefined` if Stonecrop hasn't finished initializing.
|
|
329
333
|
|
|
330
334
|
```typescript
|
|
331
335
|
// app/plugins/stonecrop.client.ts
|
|
336
|
+
import { StonecropClient } from '@stonecrop/graphql-client'
|
|
337
|
+
|
|
332
338
|
export default defineNuxtPlugin(() => {
|
|
333
|
-
const {
|
|
339
|
+
const { isReady, registerClient, registerMeta, registerDoctype } = useStonecropSetup()
|
|
334
340
|
|
|
335
|
-
//
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
const meta = await $fetch(`/api/doctypes/${doctype}`)
|
|
341
|
-
return meta
|
|
342
|
-
})
|
|
341
|
+
// Check if Stonecrop is ready (module plugins run before project plugins)
|
|
342
|
+
if (!isReady) {
|
|
343
|
+
console.warn('Stonecrop not ready - ensure @stonecrop/nuxt module is installed')
|
|
344
|
+
return
|
|
345
|
+
}
|
|
343
346
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
347
|
+
const client = new StonecropClient({ endpoint: '/graphql' })
|
|
348
|
+
|
|
349
|
+
// Register the data client
|
|
350
|
+
registerClient(client)
|
|
348
351
|
|
|
349
|
-
//
|
|
350
|
-
|
|
351
|
-
|
|
352
|
+
// Configure metadata fetching for lazy-loaded doctypes
|
|
353
|
+
registerMeta(({ segments }) => {
|
|
354
|
+
const doctype = segments[0]
|
|
355
|
+
return client.getMeta({ doctype })
|
|
352
356
|
})
|
|
357
|
+
|
|
358
|
+
// Optionally pre-load doctypes into the Registry
|
|
359
|
+
const planDoctype = Doctype.fromObject({ name: 'plan', fields: [...] })
|
|
360
|
+
registerDoctype(planDoctype)
|
|
353
361
|
})
|
|
354
362
|
```
|
|
355
363
|
|
|
356
|
-
|
|
364
|
+
### `useStonecropSetup()` vs `useStonecropRegistry()`
|
|
365
|
+
|
|
366
|
+
| Context | Use | Behavior |
|
|
367
|
+
|---------|-----|----------|
|
|
368
|
+
| **Plugin/initialization** | `useStonecropSetup()` | Returns values that may be `undefined`; provides `isReady` check |
|
|
369
|
+
| **Component/runtime** | `useStonecropRegistry()` | Throws if Stonecrop isn't initialized (expected to be ready) |
|
|
370
|
+
|
|
371
|
+
### `useStonecropSetup()` API
|
|
372
|
+
|
|
373
|
+
| Property/Method | Type | Description |
|
|
374
|
+
|-----------------|------|-------------|
|
|
375
|
+
| `registry` | `Registry \| undefined` | The Registry instance (undefined if not ready) |
|
|
376
|
+
| `stonecrop` | `Stonecrop \| undefined` | The Stonecrop instance (undefined if not ready) |
|
|
377
|
+
| `isReady` | `boolean` | `true` when both registry and stonecrop are available |
|
|
378
|
+
| `registerClient(client)` | `(client: DataClient) => void` | Set the data client for record fetching. Throws if stonecrop not available. |
|
|
379
|
+
| `getClient()` | `() => DataClient \| undefined` | Get the currently configured client. |
|
|
380
|
+
| `registerMeta(fn)` | `(fn: (ctx) => Doctype) => void` | Set the `getMeta` function on the Registry. Throws if registry not available. |
|
|
381
|
+
| `registerDoctype(doctype)` | `(doctype: Doctype) => void` | Pre-load a doctype into the Registry. Throws if registry not available. |
|
|
382
|
+
| `dispatchAction(...)` | `Promise<{ success, data, error }>` | Dispatch an action via the configured client. |
|
|
383
|
+
|
|
384
|
+
## `useStonecropRegistry()` — Using the Framework in Components
|
|
385
|
+
|
|
386
|
+
`useStonecropRegistry()` is for component/runtime context where the framework is expected to be fully initialized. Use it in components to access the configured registry and stonecrop instances.
|
|
387
|
+
|
|
388
|
+
```typescript
|
|
389
|
+
// In a component or composable
|
|
390
|
+
const { registry, stonecrop, dispatchAction } = useStonecropRegistry()
|
|
391
|
+
|
|
392
|
+
// Access doctype metadata
|
|
393
|
+
const plan = registry.getDoctype('plan')
|
|
394
|
+
|
|
395
|
+
// Dispatch actions
|
|
396
|
+
await dispatchAction({ name: 'plan' }, 'SUBMIT', [recordId])
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
**Note**: If called before Stonecrop is initialized (e.g., in a plugin), this throws with guidance to use `useStonecropSetup()` instead.
|
|
357
400
|
|
|
358
|
-
### API
|
|
401
|
+
### `useStonecropRegistry()` API
|
|
359
402
|
|
|
360
|
-
| Method |
|
|
361
|
-
|
|
362
|
-
| `
|
|
363
|
-
| `
|
|
364
|
-
| `
|
|
365
|
-
| `
|
|
403
|
+
| Property/Method | Type | Description |
|
|
404
|
+
|-----------------|------|-------------|
|
|
405
|
+
| `registry` | `Registry` | The Registry instance for doctype management. |
|
|
406
|
+
| `stonecrop` | `Stonecrop` | The Stonecrop instance for HST and operation log access. Throws if not initialized. |
|
|
407
|
+
| `setMeta(fn)` | `(fn: (ctx) => Doctype \| Promise<Doctype>) => void` | Sets the `getMeta` function on the Registry. Called by `useStonecrop()` to lazy-load doctype metadata for the current route. `ctx` = `{ path, segments }`. |
|
|
408
|
+
| `setClient(client)` | `(client: DataClient) => void` | Set the data client for record fetching. Throws if stonecrop not available. |
|
|
409
|
+
| `getClient()` | `() => DataClient \| undefined` | Get the currently configured client. |
|
|
410
|
+
| `dispatchAction(doctype, action, args)` | `Promise<{ success, data, error }>` | Dispatch an action via the configured client. Returns error if doctype not found in registry. |
|
|
366
411
|
|
|
367
412
|
## Advanced Features
|
|
368
413
|
|
package/dist/module.json
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
|
-
import type { DataClient
|
|
2
|
-
import type { RouteContext } from '@stonecrop/stonecrop';
|
|
1
|
+
import type { DataClient } from '@stonecrop/schema';
|
|
2
|
+
import type { Doctype, Registry, RouteContext, Stonecrop } from '@stonecrop/stonecrop';
|
|
3
3
|
/**
|
|
4
|
-
* Provides a stable, documented API for accessing
|
|
5
|
-
* Registry instance
|
|
4
|
+
* Provides a stable, documented API for accessing the configured Stonecrop
|
|
5
|
+
* Registry instance in components and composables.
|
|
6
|
+
*
|
|
7
|
+
* ## When to Use This vs useStonecropSetup()
|
|
8
|
+
*
|
|
9
|
+
* - **`useStonecropRegistry()`** - Call in components or composables to use the configured
|
|
10
|
+
* framework. Throws if Stonecrop isn't initialized (expected to be ready at this point).
|
|
11
|
+
*
|
|
12
|
+
* - **`useStonecropSetup()`** - Call in Nuxt plugins to configure clients, metadata functions,
|
|
13
|
+
* and pre-load doctypes. Returns values that may be `undefined` if Stonecrop isn't ready yet.
|
|
6
14
|
*
|
|
7
15
|
* ## Why This Composable Exists
|
|
8
16
|
*
|
|
@@ -12,9 +20,8 @@ import type { RouteContext } from '@stonecrop/stonecrop';
|
|
|
12
20
|
* - **@stonecrop/graphql-client**: Reference `DataClient` implementation using GraphQL
|
|
13
21
|
* - **@stonecrop/nuxt**: Nuxt integration that bootstraps the Registry and Stonecrop instances
|
|
14
22
|
*
|
|
15
|
-
* This composable bridges Nuxt's plugin lifecycle with Stonecrop's registry,
|
|
16
|
-
*
|
|
17
|
-
* framework is mounted.
|
|
23
|
+
* This composable bridges Nuxt's plugin lifecycle with Stonecrop's registry, providing
|
|
24
|
+
* a clean API for components to interact with the configured framework.
|
|
18
25
|
*
|
|
19
26
|
* ## RouteContext vs DoctypeContext
|
|
20
27
|
*
|
|
@@ -24,8 +31,8 @@ import type { RouteContext } from '@stonecrop/stonecrop';
|
|
|
24
31
|
* - **DoctypeContext** (`{ doctype, recordId? }`): Semantic doctype context. Used by the
|
|
25
32
|
* data layer to identify "what we're working with" (e.g., `{ doctype: 'Plan', recordId: '123' }`).
|
|
26
33
|
*
|
|
27
|
-
* Your `setMeta` implementation bridges these:
|
|
28
|
-
* segments and pass `DoctypeContext` to your data client.
|
|
34
|
+
* Your `setMeta` implementation (configured via `useStonecropSetup()`) bridges these:
|
|
35
|
+
* extract doctype/recordId from the route segments and pass `DoctypeContext` to your data client.
|
|
29
36
|
*
|
|
30
37
|
* ## Data Flow
|
|
31
38
|
*
|
|
@@ -34,49 +41,42 @@ import type { RouteContext } from '@stonecrop/stonecrop';
|
|
|
34
41
|
* ↓
|
|
35
42
|
* RouteContext ({ path: '/plan/123', segments: ['plan', '123'] })
|
|
36
43
|
* ↓
|
|
37
|
-
* getMeta (
|
|
44
|
+
* getMeta (configured in plugin via useStonecropSetup)
|
|
38
45
|
* ↓
|
|
39
46
|
* DoctypeContext ({ doctype: 'Plan', recordId: '123' })
|
|
40
47
|
* ↓
|
|
41
|
-
* DataClient.getMeta() →
|
|
48
|
+
* DataClient.getMeta() → Doctype
|
|
42
49
|
* ```
|
|
43
50
|
*
|
|
44
51
|
* @example
|
|
45
52
|
* ```ts
|
|
46
|
-
* //
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* setClient(client)
|
|
55
|
-
*
|
|
56
|
-
* // Bridge RouteContext → DoctypeContext for metadata fetching
|
|
57
|
-
* setMeta(({ segments }) => {
|
|
58
|
-
* const doctype = segments[0] // e.g. "plan" → doctype "Plan"
|
|
59
|
-
* return client.getMeta({ doctype }) // client expects DoctypeContext
|
|
60
|
-
* })
|
|
61
|
-
* })
|
|
53
|
+
* // In a component or composable
|
|
54
|
+
* const { registry, stonecrop, dispatchAction } = useStonecropRegistry()
|
|
55
|
+
*
|
|
56
|
+
* // Access the registry
|
|
57
|
+
* const plan = registry.getDoctype('plan')
|
|
58
|
+
*
|
|
59
|
+
* // Dispatch an action
|
|
60
|
+
* await dispatchAction({ name: 'plan' }, 'SUBMIT', [recordId])
|
|
62
61
|
* ```
|
|
63
62
|
*
|
|
64
63
|
* @public
|
|
65
64
|
*/
|
|
66
65
|
export declare function useStonecropRegistry(): {
|
|
67
66
|
/**
|
|
68
|
-
* The
|
|
69
|
-
*
|
|
67
|
+
* The Registry instance for doctype management.
|
|
68
|
+
* Use this to access doctype metadata, resolve schemas, etc.
|
|
69
|
+
*/
|
|
70
|
+
registry: Registry;
|
|
71
|
+
/**
|
|
72
|
+
* The Stonecrop instance for HST and operation log access.
|
|
70
73
|
*/
|
|
71
|
-
|
|
72
|
-
getMeta?: (routeContext: RouteContext) => DoctypeMeta | Promise<DoctypeMeta>;
|
|
73
|
-
};
|
|
74
|
+
readonly stonecrop: Stonecrop;
|
|
74
75
|
/**
|
|
75
76
|
* Set the data client on the Stonecrop instance.
|
|
76
77
|
* Required before fetching records or dispatching actions.
|
|
77
78
|
*
|
|
78
79
|
* @param client - DataClient implementation (e.g., StonecropClient from \@stonecrop/graphql-client)
|
|
79
|
-
*
|
|
80
80
|
* @throws Error if Stonecrop instance is not available
|
|
81
81
|
*
|
|
82
82
|
* @example
|
|
@@ -95,7 +95,9 @@ export declare function useStonecropRegistry(): {
|
|
|
95
95
|
* Dispatch an action to the server via the configured data client.
|
|
96
96
|
* All state changes flow through this single mutation endpoint.
|
|
97
97
|
*
|
|
98
|
-
* @param doctype - Doctype reference
|
|
98
|
+
* @param doctype - Doctype reference object with `name` and optional `slug` properties
|
|
99
|
+
* @param doctype.name - Doctype name (e.g., 'plan')
|
|
100
|
+
* @param doctype.slug - Optional doctype slug if it differs from the name (e.g., 'project-plan')
|
|
99
101
|
* @param action - Action name to execute (e.g., 'SUBMIT', 'APPROVE', 'save')
|
|
100
102
|
* @param args - Action arguments (typically record ID and/or form data)
|
|
101
103
|
* @returns Action result with success status, response data, and any error
|
|
@@ -103,10 +105,10 @@ export declare function useStonecropRegistry(): {
|
|
|
103
105
|
* @example
|
|
104
106
|
* ```ts
|
|
105
107
|
* // Save a record
|
|
106
|
-
* const result = await dispatchAction(
|
|
108
|
+
* const result = await dispatchAction({ name: 'plan' }, 'save', [{ id: recordId, data: formData }])
|
|
107
109
|
*
|
|
108
110
|
* // Submit for approval
|
|
109
|
-
* const result = await dispatchAction(
|
|
111
|
+
* const result = await dispatchAction({ name: 'plan' }, 'SUBMIT', [recordId])
|
|
110
112
|
* ```
|
|
111
113
|
*/
|
|
112
114
|
dispatchAction(doctype: {
|
|
@@ -135,7 +137,7 @@ export declare function useStonecropRegistry(): {
|
|
|
135
137
|
* })
|
|
136
138
|
* ```
|
|
137
139
|
*
|
|
138
|
-
* @param fn - Function that receives RouteContext and returns
|
|
140
|
+
* @param fn - Function that receives RouteContext and returns Doctype.
|
|
139
141
|
*/
|
|
140
|
-
setMeta(fn: (routeContext: RouteContext) =>
|
|
142
|
+
setMeta(fn: (routeContext: RouteContext) => Doctype | Promise<Doctype>): void;
|
|
141
143
|
};
|
|
@@ -4,22 +4,32 @@ export function useStonecropRegistry() {
|
|
|
4
4
|
const registry = nuxtApp.$registry;
|
|
5
5
|
if (!registry) {
|
|
6
6
|
throw new Error(
|
|
7
|
-
"[useStonecropRegistry] The Stonecrop Registry is not available. Ensure @stonecrop/nuxt is installed
|
|
7
|
+
"[useStonecropRegistry] The Stonecrop Registry is not available. Ensure @stonecrop/nuxt is installed.\n\nIf you are calling this from a Nuxt plugin, use useStonecropSetup() instead, which is designed for the plugin initialization context."
|
|
8
8
|
);
|
|
9
9
|
}
|
|
10
10
|
const stonecrop = nuxtApp.$stonecrop;
|
|
11
11
|
return {
|
|
12
12
|
/**
|
|
13
|
-
* The
|
|
14
|
-
*
|
|
13
|
+
* The Registry instance for doctype management.
|
|
14
|
+
* Use this to access doctype metadata, resolve schemas, etc.
|
|
15
15
|
*/
|
|
16
16
|
registry,
|
|
17
|
+
/**
|
|
18
|
+
* The Stonecrop instance for HST and operation log access.
|
|
19
|
+
*/
|
|
20
|
+
get stonecrop() {
|
|
21
|
+
if (!stonecrop) {
|
|
22
|
+
throw new Error(
|
|
23
|
+
"[useStonecropRegistry] Stonecrop instance is not available. Ensure @stonecrop/nuxt is installed.\n\nIf you are calling this from a Nuxt plugin, use useStonecropSetup() instead."
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
return stonecrop;
|
|
27
|
+
},
|
|
17
28
|
/**
|
|
18
29
|
* Set the data client on the Stonecrop instance.
|
|
19
30
|
* Required before fetching records or dispatching actions.
|
|
20
31
|
*
|
|
21
32
|
* @param client - DataClient implementation (e.g., StonecropClient from \@stonecrop/graphql-client)
|
|
22
|
-
*
|
|
23
33
|
* @throws Error if Stonecrop instance is not available
|
|
24
34
|
*
|
|
25
35
|
* @example
|
|
@@ -31,7 +41,7 @@ export function useStonecropRegistry() {
|
|
|
31
41
|
setClient(client) {
|
|
32
42
|
if (!stonecrop) {
|
|
33
43
|
throw new Error(
|
|
34
|
-
"[useStonecropRegistry] Stonecrop instance is not available. Ensure @stonecrop/nuxt is installed
|
|
44
|
+
"[useStonecropRegistry] Stonecrop instance is not available. Ensure @stonecrop/nuxt is installed.\n\nIf you are calling this from a Nuxt plugin, use useStonecropSetup() instead."
|
|
35
45
|
);
|
|
36
46
|
}
|
|
37
47
|
stonecrop.setClient(client);
|
|
@@ -47,7 +57,9 @@ export function useStonecropRegistry() {
|
|
|
47
57
|
* Dispatch an action to the server via the configured data client.
|
|
48
58
|
* All state changes flow through this single mutation endpoint.
|
|
49
59
|
*
|
|
50
|
-
* @param doctype - Doctype reference
|
|
60
|
+
* @param doctype - Doctype reference object with `name` and optional `slug` properties
|
|
61
|
+
* @param doctype.name - Doctype name (e.g., 'plan')
|
|
62
|
+
* @param doctype.slug - Optional doctype slug if it differs from the name (e.g., 'project-plan')
|
|
51
63
|
* @param action - Action name to execute (e.g., 'SUBMIT', 'APPROVE', 'save')
|
|
52
64
|
* @param args - Action arguments (typically record ID and/or form data)
|
|
53
65
|
* @returns Action result with success status, response data, and any error
|
|
@@ -55,21 +67,29 @@ export function useStonecropRegistry() {
|
|
|
55
67
|
* @example
|
|
56
68
|
* ```ts
|
|
57
69
|
* // Save a record
|
|
58
|
-
* const result = await dispatchAction(
|
|
70
|
+
* const result = await dispatchAction({ name: 'plan' }, 'save', [{ id: recordId, data: formData }])
|
|
59
71
|
*
|
|
60
72
|
* // Submit for approval
|
|
61
|
-
* const result = await dispatchAction(
|
|
73
|
+
* const result = await dispatchAction({ name: 'plan' }, 'SUBMIT', [recordId])
|
|
62
74
|
* ```
|
|
63
75
|
*/
|
|
64
76
|
dispatchAction(doctype, action, args) {
|
|
65
77
|
if (!stonecrop) {
|
|
66
78
|
return Promise.reject(
|
|
67
79
|
new Error(
|
|
68
|
-
"[useStonecropRegistry] Stonecrop instance is not available. Ensure @stonecrop/nuxt is installed
|
|
80
|
+
"[useStonecropRegistry] Stonecrop instance is not available. Ensure @stonecrop/nuxt is installed.\n\nIf you are calling this from a Nuxt plugin, use useStonecropSetup() instead."
|
|
69
81
|
)
|
|
70
82
|
);
|
|
71
83
|
}
|
|
72
|
-
|
|
84
|
+
const meta = registry.getDoctype(doctype.slug || doctype.name.toLowerCase());
|
|
85
|
+
if (!meta) {
|
|
86
|
+
return Promise.resolve({
|
|
87
|
+
success: false,
|
|
88
|
+
data: null,
|
|
89
|
+
error: `Doctype '${doctype.name}' not found in registry`
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
return stonecrop.dispatchAction(meta, action, args);
|
|
73
93
|
},
|
|
74
94
|
/**
|
|
75
95
|
* Set the `getMeta` function on the Registry.
|
|
@@ -89,7 +109,7 @@ export function useStonecropRegistry() {
|
|
|
89
109
|
* })
|
|
90
110
|
* ```
|
|
91
111
|
*
|
|
92
|
-
* @param fn - Function that receives RouteContext and returns
|
|
112
|
+
* @param fn - Function that receives RouteContext and returns Doctype.
|
|
93
113
|
*/
|
|
94
114
|
setMeta(fn) {
|
|
95
115
|
registry.getMeta = fn;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type { DataClient } from '@stonecrop/schema';
|
|
2
|
+
import type { Doctype, Registry, RouteContext, Stonecrop } from '@stonecrop/stonecrop';
|
|
3
|
+
/**
|
|
4
|
+
* Composable for Stonecrop initialization in Nuxt plugins.
|
|
5
|
+
*
|
|
6
|
+
* Use this during the plugin/initialization phase to configure the framework
|
|
7
|
+
* before components mount. For component/runtime usage, use `useStonecropRegistry()` instead.
|
|
8
|
+
*
|
|
9
|
+
* ## When to Use This vs useStonecropRegistry()
|
|
10
|
+
*
|
|
11
|
+
* - **`useStonecropSetup()`** - Call in Nuxt plugins to configure clients, metadata functions,
|
|
12
|
+
* and pre-load doctypes. Returns values that may be `undefined` if Stonecrop isn't ready yet.
|
|
13
|
+
*
|
|
14
|
+
* - **`useStonecropRegistry()`** - Call in components or composables to use the configured
|
|
15
|
+
* framework. Throws if Stonecrop isn't initialized (expected to be ready at this point).
|
|
16
|
+
*
|
|
17
|
+
* ## Example
|
|
18
|
+
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* // app/plugins/stonecrop.client.ts
|
|
21
|
+
* import { StonecropClient } from '@stonecrop/graphql-client'
|
|
22
|
+
*
|
|
23
|
+
* export default defineNuxtPlugin(() => {
|
|
24
|
+
* const { registerClient, registerMeta, registerDoctype } = useStonecropSetup()
|
|
25
|
+
*
|
|
26
|
+
* const client = new StonecropClient({ endpoint: '/graphql' })
|
|
27
|
+
* registerClient(client)
|
|
28
|
+
*
|
|
29
|
+
* // Configure metadata fetching for lazy-loaded doctypes
|
|
30
|
+
* registerMeta(({ segments }) => {
|
|
31
|
+
* const doctype = segments[0]
|
|
32
|
+
* return client.getMeta({ doctype })
|
|
33
|
+
* })
|
|
34
|
+
*
|
|
35
|
+
* // Optionally pre-load doctypes
|
|
36
|
+
* const plan = Doctype.fromObject({ name: 'plan', fields: [...] })
|
|
37
|
+
* registerDoctype(plan)
|
|
38
|
+
* })
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @public
|
|
42
|
+
*/
|
|
43
|
+
export declare function useStonecropSetup(): {
|
|
44
|
+
/**
|
|
45
|
+
* The Registry instance.
|
|
46
|
+
* Returns `undefined` if the @stonecrop/nuxt plugin hasn't run yet.
|
|
47
|
+
*/
|
|
48
|
+
readonly registry: Registry | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* The Stonecrop instance.
|
|
51
|
+
* Returns `undefined` if the @stonecrop/nuxt plugin hasn't run yet.
|
|
52
|
+
*/
|
|
53
|
+
readonly stonecrop: Stonecrop | undefined;
|
|
54
|
+
/**
|
|
55
|
+
* Check if Stonecrop is ready for configuration.
|
|
56
|
+
* Returns `true` when both Registry and Stonecrop instances are available.
|
|
57
|
+
*/
|
|
58
|
+
readonly isReady: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Register the data client on the Stonecrop instance.
|
|
61
|
+
* Required before fetching records or dispatching actions.
|
|
62
|
+
*
|
|
63
|
+
* @param client - DataClient implementation (e.g., StonecropClient from \@stonecrop/graphql-client)
|
|
64
|
+
* @throws Error if the Stonecrop plugin is not installed
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```ts
|
|
68
|
+
* const client = new StonecropClient({ endpoint: '/graphql' })
|
|
69
|
+
* registerClient(client)
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
registerClient(client: DataClient): void;
|
|
73
|
+
/**
|
|
74
|
+
* Set the `getMeta` function on the Registry.
|
|
75
|
+
* Called by `useStonecrop()` to lazy-load doctype metadata for the current route.
|
|
76
|
+
*
|
|
77
|
+
* You must bridge `RouteContext` → `DoctypeContext`:
|
|
78
|
+
* - Extract doctype name from `segments` (e.g., `segments[0]`)
|
|
79
|
+
* - Extract record ID from `segments` if present (e.g., `segments[1]`)
|
|
80
|
+
* - Pass `DoctypeContext` to your data client
|
|
81
|
+
*
|
|
82
|
+
* @param fn - Function that receives RouteContext and returns Doctype
|
|
83
|
+
* @throws Error if the Registry is not available
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```ts
|
|
87
|
+
* registerMeta(({ segments }) => {
|
|
88
|
+
* const doctype = segments[0] // /plan/123 → 'plan'
|
|
89
|
+
* return client.getMeta({ doctype })
|
|
90
|
+
* })
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
registerMeta(fn: (routeContext: RouteContext) => Doctype | Promise<Doctype>): void;
|
|
94
|
+
/**
|
|
95
|
+
* Load a doctype into the Registry.
|
|
96
|
+
* Convenience method that calls `registry.addDoctype()` if available.
|
|
97
|
+
*
|
|
98
|
+
* @param doctype - The Doctype instance to register
|
|
99
|
+
* @throws Error if the Registry is not available
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```ts
|
|
103
|
+
* const plan = Doctype.fromObject({ name: 'plan', fields: [...] })
|
|
104
|
+
* registerDoctype(plan)
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
registerDoctype(doctype: Doctype): void;
|
|
108
|
+
};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { useNuxtApp } from "nuxt/app";
|
|
2
|
+
export function useStonecropSetup() {
|
|
3
|
+
const nuxtApp = useNuxtApp();
|
|
4
|
+
return {
|
|
5
|
+
/**
|
|
6
|
+
* The Registry instance.
|
|
7
|
+
* Returns `undefined` if the @stonecrop/nuxt plugin hasn't run yet.
|
|
8
|
+
*/
|
|
9
|
+
get registry() {
|
|
10
|
+
return nuxtApp.$registry;
|
|
11
|
+
},
|
|
12
|
+
/**
|
|
13
|
+
* The Stonecrop instance.
|
|
14
|
+
* Returns `undefined` if the @stonecrop/nuxt plugin hasn't run yet.
|
|
15
|
+
*/
|
|
16
|
+
get stonecrop() {
|
|
17
|
+
return nuxtApp.$stonecrop;
|
|
18
|
+
},
|
|
19
|
+
/**
|
|
20
|
+
* Check if Stonecrop is ready for configuration.
|
|
21
|
+
* Returns `true` when both Registry and Stonecrop instances are available.
|
|
22
|
+
*/
|
|
23
|
+
get isReady() {
|
|
24
|
+
return !!(nuxtApp.$registry && nuxtApp.$stonecrop);
|
|
25
|
+
},
|
|
26
|
+
/**
|
|
27
|
+
* Register the data client on the Stonecrop instance.
|
|
28
|
+
* Required before fetching records or dispatching actions.
|
|
29
|
+
*
|
|
30
|
+
* @param client - DataClient implementation (e.g., StonecropClient from \@stonecrop/graphql-client)
|
|
31
|
+
* @throws Error if the Stonecrop plugin is not installed
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* const client = new StonecropClient({ endpoint: '/graphql' })
|
|
36
|
+
* registerClient(client)
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
registerClient(client) {
|
|
40
|
+
const stonecrop = nuxtApp.$stonecrop;
|
|
41
|
+
if (!stonecrop) {
|
|
42
|
+
throw new Error(
|
|
43
|
+
"[useStonecropSetup] Stonecrop instance not available. Ensure the @stonecrop/nuxt module is installed and its plugin has run before calling this."
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
stonecrop.setClient(client);
|
|
47
|
+
},
|
|
48
|
+
/**
|
|
49
|
+
* Set the `getMeta` function on the Registry.
|
|
50
|
+
* Called by `useStonecrop()` to lazy-load doctype metadata for the current route.
|
|
51
|
+
*
|
|
52
|
+
* You must bridge `RouteContext` → `DoctypeContext`:
|
|
53
|
+
* - Extract doctype name from `segments` (e.g., `segments[0]`)
|
|
54
|
+
* - Extract record ID from `segments` if present (e.g., `segments[1]`)
|
|
55
|
+
* - Pass `DoctypeContext` to your data client
|
|
56
|
+
*
|
|
57
|
+
* @param fn - Function that receives RouteContext and returns Doctype
|
|
58
|
+
* @throws Error if the Registry is not available
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```ts
|
|
62
|
+
* registerMeta(({ segments }) => {
|
|
63
|
+
* const doctype = segments[0] // /plan/123 → 'plan'
|
|
64
|
+
* return client.getMeta({ doctype })
|
|
65
|
+
* })
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
registerMeta(fn) {
|
|
69
|
+
const registry = nuxtApp.$registry;
|
|
70
|
+
if (!registry) {
|
|
71
|
+
throw new Error(
|
|
72
|
+
"[useStonecropSetup] Registry not available. Ensure the @stonecrop/nuxt module is installed and its plugin has run before calling this."
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
registry.getMeta = fn;
|
|
76
|
+
},
|
|
77
|
+
/**
|
|
78
|
+
* Load a doctype into the Registry.
|
|
79
|
+
* Convenience method that calls `registry.addDoctype()` if available.
|
|
80
|
+
*
|
|
81
|
+
* @param doctype - The Doctype instance to register
|
|
82
|
+
* @throws Error if the Registry is not available
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```ts
|
|
86
|
+
* const plan = Doctype.fromObject({ name: 'plan', fields: [...] })
|
|
87
|
+
* registerDoctype(plan)
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
registerDoctype(doctype) {
|
|
91
|
+
const registry = nuxtApp.$registry;
|
|
92
|
+
if (!registry) {
|
|
93
|
+
throw new Error(
|
|
94
|
+
"[useStonecropSetup] Registry not available. Ensure the @stonecrop/nuxt module is installed and its plugin has run before calling this."
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
registry.addDoctype(doctype);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stonecrop/nuxt",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.6",
|
|
4
4
|
"description": "Nuxt module for Stonecrop",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -44,14 +44,14 @@
|
|
|
44
44
|
"jiti": "^2.4.2",
|
|
45
45
|
"pathe": "^2.0.3",
|
|
46
46
|
"prompts": "^2.4.2",
|
|
47
|
-
"@stonecrop/atable": "0.10.
|
|
48
|
-
"@stonecrop/aform": "0.10.
|
|
49
|
-
"@stonecrop/
|
|
50
|
-
"@stonecrop/
|
|
51
|
-
"@stonecrop/
|
|
52
|
-
"@stonecrop/
|
|
53
|
-
"@stonecrop/schema": "0.10.
|
|
54
|
-
"@stonecrop/stonecrop": "0.10.
|
|
47
|
+
"@stonecrop/atable": "0.10.6",
|
|
48
|
+
"@stonecrop/aform": "0.10.6",
|
|
49
|
+
"@stonecrop/casl-middleware": "0.10.6",
|
|
50
|
+
"@stonecrop/graphql-middleware": "0.10.6",
|
|
51
|
+
"@stonecrop/node-editor": "0.10.6",
|
|
52
|
+
"@stonecrop/nuxt-grafserv": "0.10.6",
|
|
53
|
+
"@stonecrop/schema": "0.10.6",
|
|
54
|
+
"@stonecrop/stonecrop": "0.10.6"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@eslint/js": "^9.39.2",
|