@olenbetong/appframe-vite
v6.2.0
Published
Tools to use and deploy Vite applications to Appframe
Readme
@olenbetong/appframe-vite
Tools to develop and build Vite applications that run inside Appframe articles.
- Provides a Vite plugin you add in
vite.config.*. - Proxies API and static routes to an Appframe server during
pnpm start. - Logs in automatically and refreshes the session on an interval.
- Serves real article HTML from Appframe in dev, but swaps production assets for your local entry.
- Caches i18n strings locally to speed up development loads.
- Shapes production builds to Appframe paths and filenames, with optional React externals.
Installation
pnpm add -D @olenbetong/appframe-viteUsage (Vite)
// vite.config.mjs or vite.config.ts
import appframe from "@olenbetong/appframe-vite";
import { defineConfig } from "vite";
export default defineConfig({
plugins: [appframe()],
});Then run your app:
pnpm --filter <app> startMake sure your Appframe credentials are available as environment variables:
APPFRAME_LOGIN: usernameAPPFRAME_PWD: password
On first run, the plugin logs in, configures Vite’s proxy for Appframe routes, and serves the article HTML with your local entry injected.
Project configuration (package.json)
This package reads package.json.appframe to know what to proxy and how to build.
{
"appframe": {
"article": {
"id": "my-article", // Required
"altNames": ["my-article-dev"] // Optional: alternate root paths
},
"deploy": { "hostname": "dev.obet.no" }, // Default server if proxy not set
"proxy": {
"hostname": "dev.obet.no", // Optional override for dev proxy
"routes": ["^/custom/.*"] // Optional: extra proxied routes
},
"build": {
"externals": true // Map React and ReactDOM to globals
}
}
}What it does (at a glance)
- Dev server
- Proxies Appframe routes (e.g.
/api,/file,/lib, etc.) to the configured hostname. - Performs an initial login and refreshes the session every 5 minutes to prevent 403 errors.
- Serves the real article HTML from Appframe, but removes production assets and injects your local entry (
/src/index.*). - Caches localized strings under
node_modules/.appframe/localizeCache.jsonand injects them into the page to avoid many small HTTP 1.1 requests.
- Proxies Appframe routes (e.g.
- Build
- Enables
manifestandsourcemap. - Writes filenames to Appframe paths, using the article ID, e.g.:
file/article/script/<ARTICLE_ID>/main.[hash].min.jsfile/article/style/<ARTICLE_ID>/style.[hash].min.css
- Optionally treats
reactandreact-domas externals and maps them toReactandReactDOMglobals. - Adds a Rollup visualizer report at
dist/stats.html.
- Enables
- Resolve
- Adds the alias
~/to/src/so imports like~/components/Buttonresolve tosrc/components/Button.
- Adds the alias
CLI — appframe-vite
The package ships a CLI (appframe-vite) alongside the Vite plugin.
generate-types
Generates TypeScript type definitions from the article's data objects and procedures:
appframe-vite generate-typesresources generate
Reads resources.yaml and regenerates all data object / procedure files:
appframe-vite resources generate
# custom config file path:
appframe-vite resources generate --config path/to/resources.yamlresources add
Interactive wizard — prompts for resource, ID, output path, permissions, fields, and more, then appends an entry to resources.yaml and generates the output file:
appframe-vite resources addresources edit [id]
Interactive editor — pre-fills the wizard with the current values from resources.yaml and regenerates the file on save:
appframe-vite resources edit dsAccountGroups
# or without an id (shows a searchable list):
appframe-vite resources editresources.yaml config file
Place resources.yaml at the project root to declare all data objects and procedures for an app. The Vite dev server watches this file and auto-regenerates all output files when it changes.
Example:
dataObjects:
- id: dsAccountGroups
resource: atbv_Accounting_SubsidiaryLedgerGroups
global: true
types: true
maxRecords: -1
expose: true
fields:
- Domain
- SubsidiaryLedgerGroup
- PrimKey
- Description
output: src/data/dsAccountGroups.ts
- id: dsSubsidiaryLedger
resource: atbv_Accounting_SubsidiaryLedger
global: true
types: true
permissions: IUD
output: src/data/dsSubsidiaryLedger.ts
procedures:
- id: procCreateCustomer
resource: astp_Accounting_SubsidiaryLedger_Create
global: true
types: true
expose: true
output: src/data/procCreateCustomer.tsSupported fields per entry:
| Field | Type | Description |
|---|---|---|
| id | string | Variable name used in generated code (e.g. dsAccountGroups) |
| resource | string | Database object ID (e.g. atbv_Accounting_SubsidiaryLedgerGroups) |
| output | string | Output file path relative to project root |
| global | boolean | Use af.data.generateApiDataObject / new af.ProcedureAPI globals |
| types | boolean | Emit TypeScript type definitions |
| permissions | string | Permissions: I = insert, U = update, D = delete (e.g. IUD) |
| maxRecords | number | Max records to fetch (default 50; -1 for all) |
| sortOrder | string \| string[] | Sort order, e.g. Created:Desc or [Created:Desc, Name] |
| master | string | Master data object name (or name:importPath) |
| linkFields | string \| string[] | Fields linking child to master |
| expose | boolean \| string | Expose on af.article.dataObjects / af.article.procedures |
| dynamic | boolean | Enable dynamic loading |
| unique | string | Unique table name for update/delete |
| overrides | string \| string[] | Type overrides, e.g. MyField:string[] |
| distinct | boolean | Fetch distinct rows |
| aggregates | string \| string[] | Aggregate bindings, e.g. Qty:SUM |
| groupBy | string \| string[] | Group-by fields |
| where | string | Initial where clause |
| fields | string \| string[] | Fields to include (all if omitted) |
A top-level server key can override the hostname (defaults to appframe.proxy.hostname from package.json).
@olenbetong/appframe-vite/resources export
Shared code generation utilities for Node.js consumers:
import {
fetchAndGenerate,
buildYamlConfig,
parseYamlConfig,
formatWithBiome,
getCustomImportPath,
type CLIOptions,
} from "@olenbetong/appframe-vite/resources";