npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@cwtools/model-mapper

v0.1.2

Published

Vue Resource Library

Downloads

124

Readme

@cwtools/model-mapper

Vue 3 resource UI library for model-driven tables, forms, details, media helpers, and offcanvas workflows.

Install

npm install @cwtools/model-mapper

Required peer dependencies:

  • vue
  • axios
  • bootstrap

Quick start

1) Provide required services in app bootstrap

import { createApp } from 'vue'
import App from './App.vue'
import {
  AppStateKey,
  ResourcesServiceKey,
  PopServiceKey,
  LoggerServiceKey,
  PrinterServiceKey,
  CellsRegistry,
  FormRegistry,
  Pop,
  Printer,
  type IPopService,
} from '@cwtools/model-mapper'

import { createAppState } from './AppState'
import { ResourceService } from './services/ResourceService'
import { logger } from './services/Logger'

const app = createApp(App)
const appState = createAppState()

CellsRegistry.registerDefaults()
FormRegistry.registerDefaults()

app.provide(AppStateKey, appState)
app.provide(ResourcesServiceKey, new ResourceService(appState))
app.provide(PrinterServiceKey, Printer)
app.provide(LoggerServiceKey, logger)
app.provide(PopServiceKey, Pop as unknown as IPopService)

app.mount('#app')

2) Define and register models

import { ResourceModel, registerModel, type FormGroup, type TableColumn } from '@cwtools/model-mapper'

export class Product extends ResourceModel {
  static resourceName = 'products'
  static displayName = 'Products'
  static singularName = 'Product'
  static abbreviation = 'PRD'
  static icon = 'mdi-package-variant-closed'
  static color = 'primary'

  static get tableColumnsView(): TableColumn[] {
    return [
      { key: 'name', label: 'Name' },
      { key: 'price', label: 'Price', type: 'currency' },
    ]
  }

  static get formView(): FormGroup[] {
    return [
      {
        label: 'Details',
        inputs: [
          { key: 'name', type: 'text', label: 'Name', required: true },
          { key: 'price', type: 'number', label: 'Price' },
        ],
      },
    ]
  }

  static get smallDetailsView(): TableColumn[] {
    return [{ key: 'name', label: 'Name' }]
  }

  static Instantiate(data: any) {
    return new Product(data)
  }
}

registerModel(Product)

3) Render layout + offcanvas manager

<script setup lang="ts">
import { ResourceLayout, OffcanvasManager } from '@cwtools/model-mapper/components'
import { Product } from '@/models/Product'
</script>

<template>
  <ResourceLayout :instance-type="Product" />
  <OffcanvasManager />
</template>

Optional: context-aware offcanvas tabs

By default, offcanvas tabs use one shared state and one storage key per host. If your app supports context switching (for example, business/tenant/workspace changes), you can opt in to context-aware tab persistence.

import { offcanvasService } from '@cwtools/model-mapper/services/OffcanvasService.js'

offcanvasService.enableContextSwitching?.(true)
offcanvasService.switchContext?.(activeContextId)

When context switching is enabled:

  • tabs are persisted per context key
  • changing context restores tabs for that context only
  • apps without context switching remain unchanged (no migration required)

Optional cleanup helpers:

offcanvasService.clearPersistedTabs?.() // clears current context
offcanvasService.clearPersistedTabs?.('some-context-id')

Common imports

From package root:

  • Core types and model APIs (ResourceModel, FormInput, TableColumn, etc.)
  • Tokens and composables (AppStateKey, useAppState, useResourceService, ...)
  • Registries (registerModel, registerComponent, CellsRegistry, FormRegistry)

From component export path:

import { ResourceLayout, OffcanvasManager, ResourceDetails } from '@cwtools/model-mapper/components'

Media components are also exported from the root package and @cwtools/model-mapper/components.

Local development in this monorepo

From repo root:

npm --prefix studio_manager run sync:model-mapper

This will:

  1. Build studio_manager/lib
  2. Refresh studio_manager/example-app
  3. Refresh tenant-store

VS Code task available: Sync Model Mapper Local.

Releasing in this monorepo

One-command release helper

npm --prefix studio_manager run release:model-mapper -- patch
# or minor / major / explicit version
# npm --prefix studio_manager run release:model-mapper -- 1.2.3

Behavior:

  • Requires clean git working tree
  • Bumps studio_manager/lib/package.json version
  • Commits version files
  • Creates git tag: model-mapper-v<version>
  • Pushes commit + tag (unless --no-push)

VS Code tasks available:

  • Release Model Mapper (patch)
  • Release Model Mapper (minor)
  • Release Model Mapper (major)

Publish workflow

GitHub Actions workflow: Publish Model Mapper

Triggers:

  • Manual dispatch
  • Push tag matching model-mapper-v*

Required secret:

  • NPM_TOKEN with publish rights for @cwtools/model-mapper

Notes

  • Package is ESM ("type": "module").
  • Type declarations are emitted to dist/types during build.
  • The package publishes dist artifacts only.