Skip to content

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:

  1. Calculates the output package path under Platform/Web/packages/.generated/carrot-api-client-{api}-vue
  2. Computes an ActionMap - a dictionary mapping each scaffold model to the controller actions that return it with Get or Reference CQRS roles
  3. Ensures src/stores directory exists
  4. 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:

  1. Registers each identity with a resolver function
  2. Maps identity properties to the corresponding controller action parameters
  3. 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 composable

Integration 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

DependencyKind
Carrot.Data.Scaffold.Compilersproject (scaffold compiler framework)

Build

bash
dotnet build

Targets 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 state

Installing 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 ActionMap drives 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.

Carrot