Forceget Components
A Visual Studio Code extension that scaffolds Forceget-specific Angular components directly from the Explorer context menu. It generates a fully wired list-page component — TypeScript class, HTML template, and SCSS file — and automatically registers the component in the nearest module and routing file, all in a single step.
Overview
Forceget projects share a common UI layer built on top of the @forceget/base-theme library. Every list page follows the same structure: a <forceget-table> template bound to a BaseService, a dataQuery pagination object, listOfColumns, actions, and optional Excel export. Writing this boilerplate by hand is repetitive and error-prone.
This extension encodes that pattern and lets developers generate a complete, correctly wired component in seconds via a guided wizard.
Features
- One-command scaffold — right-click any folder in the Explorer and select Create List Page or Create Service to start the wizard.
- v3 Excel-like list pages — Create List Page (v3 Excel Table) generates a list page using the
version="v3" Excel-like table, with inline add-row, row editing, and delete automatically wired to the service's CRUD methods.
- PostgreSQL DDL generation — generates a
CREATE TABLE script from a C# entity extending ForcegetBaseEntity, with standard base columns and type mapping. Available in VS Code and as a standalone CLI (forceget-sql) for Rider.
- Service discovery — automatically scans the workspace for
.service.ts files that extend BaseService and presents them in a picker.
- Method detection — parses the selected service file and detects methods that accept
take/skip pagination parameters, pre-filling the method picker.
- Excel export support — if the service exposes an
exportExcel* method, the generated component and template include the export wiring automatically.
- Routing registration — finds the nearest
*-routing.module.ts file and inserts the new route with path, component, title, and apiUrl from the environment.
- Module registration — finds the nearest
pages.module.ts (or any non-routing .module.ts) and adds the component to the declarations array.
- Diagnostics — scans all components for
getIsLoading binding mismatches and reports broken references directly in the Problems panel.
- Remove unused imports — right-click a UI project folder (or run the command) to strip unused imports from every
.ts file under it in one pass, using the editor's own TypeScript language service.
- License gate — the extension is protected by a license key to restrict usage to authorised Forceget team members.
Download
Download the extension from Visual Studio Marketplace.
Installation
Via Visual Studio Marketplace
- Open VS Code.
- Go to the Extensions panel (
Cmd+Shift+X / Ctrl+Shift+X).
- Search for Forceget Components.
- Click Install.
Via VSIX
- Open the Command Palette (
Cmd+Shift+P / Ctrl+Shift+P).
- Run Extensions: Install from VSIX…
- Select the
.vsix file.
- Reload VS Code when prompted.
On first use you will be asked for your Forceget license key. Enter it once and it is stored locally — you will not be asked again.
Usage
Create a List Page
- In the Explorer panel, right-click the folder where the new component should live (e.g.
src/app/pages/products).
- Select Create List Page from the context menu.
- Follow the wizard:
| Step |
What to provide |
| Component name |
kebab-case name, e.g. product-list |
| Service |
pick from the list of detected BaseService subclasses |
| Fetch method |
pick the method that returns paginated data (take + skip) |
| Page URL |
route path, defaults to <name>/list |
- The extension creates three files inside a new sub-folder:
products/
└── product-list/
├── product-list.component.ts
├── product-list.component.html
└── product-list.component.scss
- The routing and module files in the parent folder are updated automatically. If either file is not found, a warning is shown and you can register the component manually.
Create a List Page (v3 Excel Table)
Generates a list page that uses the Excel-like v3 variant of <forceget-table> (version="v3" — green header, full gridlines, compact font), introduced in @forceget/base-theme. The reference implementation is the daily-requested-report-manuel-quote/list page in offer-web.
- In the Explorer panel, right-click the folder where the new component should live.
- Select Create List Page (v3 Excel Table) from the context menu.
- Follow the same wizard as Create List Page (component name, service, fetch method, page URL).
In addition to the standard list-page wiring, the generator inspects the selected service and automatically wires CRUD features when matching methods are found:
| Service method pattern |
Generated feature |
add* / create* / insert* |
Excel add-row ([showExcelAddRow], [(excelAddRowData)], (excelAddRowSubmit)) — new records are entered directly in the bottom row of the table |
update* / upsert* / edit* |
Inline row editing — the Edit action calls table.startRowEdit(), and (rowEditSubmit) posts the change |
delete* / remove* |
Delete action wired to the service, with success notification and refetch |
Features whose methods are not found are simply omitted. The completion message lists exactly which methods were wired. Routing and module registration work identically to Create List Page.
Create an Expand List Page
Generates an expandable list page component where each row can be expanded to reveal a nested detail panel.
- In the Explorer panel, right-click the folder where the new component should live.
- Select Create Expand List Page from the context menu.
- Follow the same wizard as Create List Page:
| Step |
What to provide |
| Component name |
kebab-case name, e.g. order-expand-list |
| Service |
pick from the list of detected BaseService subclasses |
| Fetch method |
pick the method that returns paginated data (take + skip) |
| Page URL |
route path, defaults to <name>/list |
- The extension creates three files inside a new sub-folder and registers the component in the nearest routing and module files, identical to Create List Page.
Create a Service
- In the Explorer panel, right-click the folder where the new service should live (e.g.
src/app/services).
- Select Create Service from the context menu.
- Follow the wizard:
| Step |
What to provide |
| Service name |
kebab-case name without the service suffix, e.g. product |
| Controller name |
ASP.NET controller name as it appears in the route, e.g. Product |
| Methods |
toggle the methods to generate — all five are pre-selected |
Available methods:
| Method |
Generated as |
Description |
getAll |
getAllAsync |
Paginated GET with take, skip, orderBy |
add |
addAsync |
POST — create a new record |
update |
updateAsync |
POST — update an existing record |
delete |
deleteAsync |
POST — delete a record |
exportExcel |
exportExcel |
Exports the list to CSV via exportViaExcel |
- The extension creates a single file in the selected folder:
services/
└── product.service.ts
The generated service extends BaseService, sets baseUrl to ${environment.apiUrl}/<ControllerName>, and wires each selected method to the corresponding endpoint under that base URL.
Generate Service from C# Controller
Reads an existing C# controller file from the backend project and generates a ready-to-use Angular service — no need to copy route paths or method names by hand.
- Run Forceget: Generate Service from C# Controller from the Command Palette, or right-click any folder in the Explorer and choose the same option.
- A file picker opens — select the
.cs controller file from your backend project.
- Select the target folder inside your Angular project where the service file should be saved.
The extension inspects the controller and produces a <controller-name>.service.ts file with the following content:
- The
baseUrl is derived from the controller's [Route] attribute with [controller] resolved to the actual controller name.
- If the controller extends
BaseController<T>, the four standard methods are included automatically: getAllAsync, addAsync, updateAsync, deleteAsync.
- Every explicit HTTP action (
[HttpGet], [HttpPost], [HttpPut], [HttpDelete]) declared in the controller body becomes a corresponding service method.
- Actions whose name contains
ExportExcel are wired to exportViaExcel automatically.
The generated file is saved to the selected folder and opened in the editor immediately.
Scaffold a C# Entity (Repository + Service + Controller)
Generates a full backend stack (Repository, Service, Controller) for an existing entity in a Clean/Onion-architecture C# solution and registers the new services in the corresponding *DependencyInjection.cs files.
- Open the C# solution in VS Code/Cursor.
- Run Forceget: Scaffold C# Entity (Repository + Service + Controller) from the Command Palette.
- Follow the wizard:
| Step |
What to provide |
| Project group |
auto-detected from .csproj files matching <Name>.Core, <Name>.DataAccess, <Name>.Application, <Name>.API. If multiple groups exist, pick one. |
| Entity |
pick a .cs class from <Name>.Core/Entities/ |
The extension creates:
<Name>.DataAccess/Repositories/I<Entity>Repository.cs
<Name>.DataAccess/Repositories/Impl/<Entity>Repository.cs
<Name>.Application/Services/I<Entity>Service.cs
<Name>.Application/Services/Impl/<Entity>Service.cs
<Name>.API/Controllers/<Entity>Controller.cs
The generated classes follow the BaseRepository<T> / BaseService<T> / BaseController<T> chain. The controller ships with a stub ExportExcel endpoint pre-wired against GetAllGenericAsync.
The extension also updates:
<Name>.DataAccess/DataAccessDependencyInjection.cs — appends services.AddScoped<I<Entity>Repository, <Entity>Repository>(); inside AddRepositories.
<Name>.Application/ApplicationDependencyInjection.cs — appends services.AddScoped<I<Entity>Service, <Entity>Service>(); inside AddServices (before return services;).
Standalone CLI (for JetBrains Rider, terminal, CI)
The same generator ships as a Node.js CLI so it can be invoked from outside VS Code/Cursor — most notably from JetBrains Rider via its External Tools feature.
After installing the extension's .vsix (or building the package from source) the CLI is exposed as forceget-scaffold. To use it standalone:
# from anywhere — auto-detects projects in cwd
npx forceget-scaffold
# or pass an explicit root
npx forceget-scaffold --root /path/to/solution
The CLI is fully interactive: it lists project groups, then entities, then writes the same five files and updates the same two DI files as the VS Code command.
Setting up Rider External Tools:
Open Rider. Go to Settings → Tools → External Tools.
Click + to add a new tool.
Configure:
| Field |
Value |
| Name |
Forceget: Scaffold C# Entity |
| Program |
node (or the absolute path to your Node binary, e.g. /usr/local/bin/node) |
| Arguments |
/absolute/path/to/forceget-extension/out/cli/csharpScaffold.js --root $ProjectFileDir$ |
| Working directory |
$ProjectFileDir$ |
| Open console for tool output |
✓ (checked) |
Click OK. The tool is now available under Tools → External Tools → Forceget: Scaffold C# Entity, and can be bound to a keyboard shortcut via Settings → Keymap → External Tools.
When triggered, Rider opens the Run console where the CLI runs interactively. Pick the project group and entity by typing the number; the generated files are written directly to disk and picked up by Rider's file watcher automatically.
Tip: if you publish this extension on the Open VSX Registry, the CLI's logic is fully reusable — both the VS Code/Cursor command and the Rider External Tool share the same core module under src/csharpScaffold/.
Generate PostgreSQL CREATE TABLE Script
Generates a ready-to-run PostgreSQL CREATE TABLE script from a C# entity that extends ForcegetBaseEntity. Useful when the table is created manually rather than through EF migrations.
In VS Code/Cursor:
- Right-click the entity's
.cs file in the Explorer and select Generate PostgreSQL CREATE TABLE Script — or run it from the Command Palette, which scans the workspace for entities under any Entities/ folder and shows a picker.
- The SQL is written to the Forceget SQL output channel and copied to the clipboard.
What is generated:
- The table name is the lowercased entity name.
- The standard
ForcegetBaseEntity columns are always emitted first:
id serial
primary key,
refid uuid not null
unique,
createdby uuid not null,
createdon timestamp(6) not null,
updatedby uuid,
updatedon timestamp(6),
deletedby uuid,
deletedon timestamp(6),
datastatus smallint default 0 not null
- The remaining properties are mapped by C# type:
| C# type |
PostgreSQL type |
int / short / long |
integer / smallint / bigint |
decimal |
numeric(18,2) |
double / float |
double precision / real |
bool |
boolean |
string |
text |
DateTime |
timestamp(6) |
DateTimeOffset |
timestamp(6) with time zone |
DateOnly / TimeOnly / TimeSpan |
date / time / interval |
Guid |
uuid |
byte[] |
bytea |
| enum types |
smallint (stored as the numeric value — 0, 1, 2, …; enum declarations are auto-discovered by scanning the solution's .cs files) |
- Nullable types (
int?, string?, …) become nullable columns; non-nullable types get not null.
- Navigation properties and collections (
List<T>, ICollection<T>, custom class types) are skipped and listed in a trailing SQL comment.
Standalone CLI (for JetBrains Rider, terminal, CI)
The generator also ships as a CLI, forceget-sql, sharing the same core module (src/postgresSql/) as the VS Code command.
# direct — print SQL for a specific entity file
npx forceget-sql path/to/Entity.cs
# interactive — scan cwd (or --root <dir>) for entities and pick one
npx forceget-sql
npx forceget-sql --root /path/to/solution
Setting up Rider External Tools:
Open Rider. Go to Settings → Tools → External Tools.
Click + to add a new tool.
Configure:
| Field |
Value |
| Name |
Forceget: Generate PostgreSQL SQL |
| Program |
node (or the absolute path to your Node binary) |
| Arguments |
/absolute/path/to/forceget-extension/out/cli/generateSql.js $FilePath$ |
| Working directory |
$ProjectFileDir$ |
| Open console for tool output |
✓ (checked) |
Click OK. With an entity file open, run Tools → External Tools → Forceget: Generate PostgreSQL SQL — the SQL is printed directly to Rider's Run console. It can also be bound to a keyboard shortcut via Settings → Keymap → External Tools.
Omitting $FilePath$ (or using --root $ProjectFileDir$ instead) starts the interactive mode, which lists every ForcegetBaseEntity entity found in the solution.
Run Diagnostics
The extension continuously validates the wiring between components and their services. Two ways to trigger it:
- On save — whenever a
*.component.ts file is saved, diagnostics run automatically for that file.
- On demand — open the Command Palette (
Cmd+Shift+P / Ctrl+Shift+P) and run Forceget: Run Diagnostics to scan the entire workspace at once.
What is checked:
| Check |
Severity |
Description |
getIsLoading method mismatch |
Error |
The method name passed to getLoading('...') does not exist in the bound service |
| Service file not found |
Warning |
The service class referenced in the component constructor cannot be located in the workspace |
Issues appear as inline squiggles on the getIsLoading line and are listed in the Problems panel (Cmd+Shift+M / Ctrl+Shift+M). Clicking an entry navigates directly to the affected line.
Quick Fix:
When an error is reported, a lightbulb appears on the affected line. Press Ctrl+. (Cmd+. on Mac) to open the quick-fix menu — it lists all valid loading keys found in the bound service. Selecting one replaces the wrong key in-place and saves the file automatically, re-running diagnostics immediately.
Remove Unused Imports (UI Project)
Strips unused imports from every .ts file in a UI project in one pass. Two ways to trigger it:
- Right-click a folder in the Explorer and select Forceget: Remove Unused Imports (UI Project) — the clicked folder is used as the target.
- On demand — open the Command Palette (
Cmd+Shift+P / Ctrl+Shift+P) and run Forceget: Remove Unused Imports (UI Project), then choose the project folder.
How it works:
- After a confirmation prompt, the extension scans the selected folder for
.ts files, skipping node_modules, dist, out, .git, and *.d.ts.
- For each file it applies the editor's built-in TypeScript source actions —
source.removeUnusedImports (removal only, no reordering) and falls back to source.organizeImports when the former is unavailable.
- Modified files are saved automatically. Progress is shown in a cancellable notification, and a summary reports how many files were cleaned.
Because it relies on the editor's own TypeScript language service, results match what VS Code's "Organize Imports" produces — side-effect imports (e.g. import './polyfills') and imports referenced anywhere in the file (decorators, templates' imports/declarations arrays, types) are preserved.
Requirements
- Visual Studio Code 1.85 or newer.
- An Angular workspace that uses
@forceget/base-theme and the BaseService pattern.
- A valid Forceget license key.
License
Internal Forceget Software. Distribution outside the Forceget organisation is not permitted.