Appearance
Carrot.Data.Scaffold.Compilers.Modules.VueJsLibrary
net
Scaffold compiler module that generates Vue.js store libraries for state management, producing per-model ApiTypeStore classes that bind to generated API client endpoints.
Installation
xml
<ProjectReference Include="..\Carrot.Data.Scaffold.Compilers.Modules.VueJsLibrary\Carrot.Data.Scaffold.Compilers.Modules.VueJsLibrary.csproj" />Architecture
Compiler Module
ScaffoldCompilerVueJsLibrary extends ScaffoldCompilerModule<ScaffoldApi, ScaffoldCompilerVueJsLibraryOptions>. For each API, it:
- Calculates the output package path under
Platform/Web/packages/.generated/carrot-api-client-{api}-vue - Computes an
ActionMap- a dictionary mapping each scaffold model to the controller actions that return it with Get or Reference CQRS roles - Ensures
src/storesdirectory exists - Registers renderers for root files, src files, and per-model stores (only for models that appear in the action map)
ActionMap Calculation
The ActionMap is the key intelligence in this module. It scans all controller actions targeting the current API, filters to those with Get or Reference response CQRS roles, resolves their response payload types back to scaffold models, and groups by model. This determines which models get stores and which actions bind to them.
csharp
// Simplified: model -> [actions that return it as Get/Reference]
Dictionary<ScaffoldApiGraphModel, IReadOnlyList<ScaffoldApiGraphControllerAction>>Store Generation
Each model that appears in the ActionMap gets a full store package under src/stores/{ModelPlural}/:
- Store class - extends
ApiTypeStore<TModelGet>with:- Primary key resolution from model properties (single or composite)
- Reference resolver registration (mapping Reference models to primary keys)
- Identity resolver registration (for alternate lookup keys)
- Controller action interfaces defining typed methods per bound action
- Action bindings - connect store actions to the TypeScript API client's endpoint methods, including parameter passing for search/sort/pagination
- Create function - factory function to instantiate the store with its client and action bindings
- Install function - DI registration for the store
- Use composable -
use{Model}Store()Vue composable for accessing the store
Identity Resolution
Models can declare identities (alternate keys beyond the primary key). The store generator:
- Registers each identity with a resolver function
- Maps identity properties to the corresponding controller action parameters
- Throws specific exceptions for ambiguous matches, missing matches, or multiple identity conflicts
Directory Structure
carrot-api-client-{api}-vue/
package.json
tsconfig.json
src/
index.ts
install.ts
provide.ts
use.ts
stores/
{ModelPlural}/
{Model}ApiTypeStore.ts # Store class + controller interfaces
{Model}ApiTypeStore.actions.ts # Action bindings
{Model}ApiTypeStore.create.ts # Factory function
{Model}ApiTypeStore.install.ts # DI registration
{Model}ApiTypeStore.use.ts # Vue composableIntegration with TypescriptClient
The Vue store library imports types and the client class from the corresponding @carrot/api-client-{api} package (generated by TypescriptClient). The two modules are designed to be used together.
Dependencies
| Dependency | Kind |
|---|---|
Carrot.Data.Scaffold.Compilers | project (scaffold compiler framework) |
Build
bash
dotnet buildTargets net10.0.
Usage Guide
Generate Vue.js store libraries that provide reactive state management backed by generated API clients.
Getting Started
Register the VueJsLibrary module on a scaffold compiler (alongside the TypescriptClient module it depends on):
csharp
IScaffoldCompiler compiler = scaffold.CreateCompiler()
.AddModuleTypescriptClient()
.AddModuleVueJsLibrary();Then compile:
csharp
IScaffoldCompilerResult result = compiler.Compile();The generated packages are output to Platform/Web/packages/.generated/carrot-api-client-{api}-vue/.
Common Patterns
Using a Generated Store
typescript
import { useUserStore } from '@carrot/api-client-platform-vue';
// In a Vue component setup()
const userStore = useUserStore();
// Store maintains reactive state keyed by primary key
const user = userStore.get('user-id-123');Store Action Bindings
Each store exposes typed actions that call through to the API client:
typescript
// Sync a single entity (returns ApiTypeStoreSyncResult)
const result = await userStore.actions.users.getUser(userId, {
// ApiTypeStoreControllerActionOptions
});
// Sync a list (returns ApiTypeStoreSyncListResult)
const listResult = await userStore.actions.users.getUsers(
{ text: 'search' }, // search
{ sortBy: 'name' }, // sort
{ page: 1 }, // pagination
);Identity Resolution
Models with alternate identities (e.g. lookup by email or slug in addition to primary key) have identity resolvers registered automatically:
typescript
import { User_Identity } from '@carrot/api-client-platform';
// Resolve by alternate identity
const user = userStore.resolveByIdentity(User_Identity.Email, 'jane@example.com');Reference Resolution
Reference models (lightweight read projections) are automatically mapped to their full Get models via the store's reference resolver:
typescript
// The store knows how to map a UserReference to its primary key
// and find the corresponding UserGet in its reactive stateInstalling the Store Plugin
typescript
import { install } from '@carrot/api-client-platform-vue';
// In your Vue app setup
app.use(install(client));Tips
- Stores are per-model, not per-controller - a single store may bind actions from multiple controllers if they return the same model.
- Only models with Get/Reference actions get stores - if a model only appears in Create/Update responses, it won't have a generated store.
- The
ActionMapdrives everything - if you're missing a store, check that your controller action has a Get or Reference CQRS role on its response. - Use alongside TypescriptClient - the Vue store imports from the
@carrot/api-client-{api}package, so both modules must be compiled together. - Primary key resolution supports composite keys - multi-property keys are serialized as
${prop1}|${prop2}template literals.