Skip to content

Conversation

@Its4Nik
Copy link
Owner

@Its4Nik Its4Nik commented Oct 9, 2025

This PR is to track the development of the Plugin Handler and Plugins in general.

ToDo:

  • Test Plugins via adding Stack functionality

Summary by Sourcery

Add a full plugin management layer and extend database and theming support across the DockStat monorepo, refactor sqlite-wrapper for JSON handling, update documentation, and standardize dependency versions

New Features:

  • Introduce a new @dockstat/plugin-handler package to register, load, execute, update, and manage backend/frontend plugins
  • Integrate PluginHandler into the server startup sequence and expose getPluginHandler in the ServerInstance API
  • Add nav_links to DB_config and load dynamic navigation links in the client Nav component via a new API route

Enhancements:

  • Refactor sqlite-wrapper to unify JSON column configuration with JsonColumnConfig, add debug logging in query builders, and overhaul TableOptions
  • Enrich sqlite-wrapper README with core features, type-safety guarantees, safety-first design, and change license to MPL-2.0
  • Bump and standardize dependency versions across workspaces (TypeScript ^5.9.3, React Router 7.9.3, sqlite-wrapper latest, etc.)
  • Refactor ThemeHandler to use createTable, expose getThemeTable, and adjust import paths throughout the server code

Documentation:

  • Update sqlite-wrapper README with usage patterns and feature descriptions
  • Add a basic README for @dockstat/plugin-handler

Chores:

  • Add install-deps.sh script to automate dependency installation across workspaces
  • Introduce ExactlyOne utility type in typings/helpers

Its4Nik and others added 5 commits October 1, 2025 18:14
This commit improves the handling of JSON columns within the sqlite-wrapper. It refactors the table creation process to accept a `jsonConfig` option, enabling automatic JSON serialization/deserialization for specified columns.

- Adds `jsonConfig` to the `createTable` options, allowing specification of JSON columns.
- Updates `transformRowToDb` to automatically serialize JSON columns before insertion/update.
- Improves logging for debugging purposes.
- Updates the example in the README to reflect the changes.
Updates the README with more detailed features, switches to MPL-2.0 license and bumps package version to 1.2.7.
This commit introduces plugin support to DockStat, allowing for extending functionality through external plugins. It also enhances theme capabilities and improves code organization.

- Implemented PluginHandler for managing plugins, including registration, updates, and deletion.
- Added database table for storing plugin metadata and configurations.
- Enhanced ThemeHandler to provide access to the theme table.
- Updated dependencies and scripts for building plugins.
- Moved and renamed existing plugin handler to prevent naming collisions

The `pluginHandler` now handles registration, updates, and deletions of plugins. It also creates a plugin table, for storing information about plugins, such as version number, the plugin component, and plugin settings.

BREAKING CHANGE: The original plugin handler was renamed to prevent naming collisions when new packages are built.
This commit introduces a comprehensive plugin handling system, enabling dynamic loading, management, and execution of plugins within the dockstat application.

The key features include:

- Plugin Registry: The core functionality is encapsulated in the PluginHandler class, responsible for registering, loading, updating, and deleting plugins.
- Plugin API: introduces typings for plugin metadata, API, config and actions.
- Dynamic Execution: Support for executing plugin actions and routes, allowing for dynamic interaction with plugins.

BREAKING CHANGE: The plugin backend api has been changed
This commit removes the `bun.lock` file.  This file is no longer needed and is being removed to cleanup the codebase.

The `bun.lock` file tracked the versions of dependencies used in the project.
This is being moved to another file.
@Its4Nik Its4Nik self-assigned this Oct 9, 2025
@Its4Nik Its4Nik added this to DockStat Oct 9, 2025
@Its4Nik Its4Nik added the enhancement New feature or request label Oct 9, 2025
@sourcery-ai
Copy link

sourcery-ai bot commented Oct 9, 2025

Reviewer's Guide

This PR introduces a new plugin framework, refactors and strengthens the SQLite wrapper, updates application startup and dependency management, and adapts UI routing and context to support dynamic nav links and theming.

Class diagram for the new Plugin framework

classDiagram
  class PluginHandler {
    -DB: DB
    -pluginTable: QueryBuilder<PLUGIN.PluginTable>
    -loadedPlugins: Map<string, PLUGIN.PluginRegistry>
    +getPlugins()
    +getLoadedPlugins()
    +loadPlugin(pluginData: PLUGIN.PluginTable)
    +loadAllPlugins()
    +executeAction(pluginName: string, actionName: string, ...)
    +executeRoute(pluginName: string, routeName: string, ...)
    +registerPlugin(data: PLUGIN.PluginTable)
    +updatePlugin(id: number)
    +deletePlugin(id: number)
    +unloadPlugin(pluginName: string)
    +getPluginInstance(pluginName: string)
    +isPluginLoaded(pluginName: string)
    +writeFrontendComponent(data: PLUGIN.PluginTable)
  }

  class Plugin {
    +meta: PLUGIN.PluginMeta
    +table: QueryBuilder<T> | null
    +config: PLUGIN.Config<T, A>
    +backendActions: A
    +constructor(meta, config, actions, db)
  }

  PluginHandler --> "*" Plugin
  PluginHandler --> "1" QueryBuilder
  Plugin --> "1" QueryBuilder
  PluginHandler --> "1" DB

  class PLUGIN.PluginTable {
    id: number
    meta: PluginMeta
    plugin: { backendConfig, backendActions, frontendConfig }
  }

  class PLUGIN.PluginRegistry {
    instance: PluginInstance
    routes: Record<string, { method: string; actions: string[] }>
  }

  class PLUGIN.PluginMeta {
    name: string
    author: { name: string; website?: string; email?: string }
    version: string
    tags: string[]
    repository: string
    path: string
  }

  class PLUGIN.Config {
    table?: { name: string; jsonColumns: JsonColumnConfig<T>; columns: Record<string, ColumnDefinition> }
    routes: Record<string, BackendRoute<Extract<keyof A, string>>>
  }
Loading

File-Level Changes

Change Details Files
Add plugin support infrastructure
  • Define PluginTable, PluginMeta, DBActions and Config types in typings
  • Create @dockstat/plugin-handler package with handler, builder and utils
  • Integrate PluginHandler into ServerInstance startup and expose plugin APIs
packages/typings/src/plugins.ts
packages/plugin-handler/src/index.ts
packages/plugin-handler/src/pluginBuilder/index.ts
packages/plugin-handler/src/utils.ts
apps/dockstat/app/.server/index.ts
Enhance sqlite-wrapper API and type safety
  • Change jsonConfig to a typed JsonColumnConfig and wire it through createTable/table
  • Add debug logging in BaseQueryBuilder.transformRowToDb and InsertQueryBuilder
  • Refactor reset() indentation and simplify table/query builder signatures
packages/sqlite-wrapper/types.ts
packages/sqlite-wrapper/index.ts
packages/sqlite-wrapper/query-builder/base.ts
packages/sqlite-wrapper/query-builder/insert.ts
packages/sqlite-wrapper/README.md
Refactor theme and config table handling
  • Switch ThemeHandler to use createTable and expose getThemeTable()
  • Include nav_links in DB_config and initialize JSON columns accordingly
  • Update DockStatDB to create and manage config table with JSON fields
apps/dockstat/app/.server/src/theme/themeHandler.ts
packages/db/index.ts
packages/typings/src/database.ts
Revise application routing and UI context
  • Introduce Body/Layout components with dynamic nav_links loader
  • Pass nav_links into Nav component and update NavCards layout
  • Use React Router outlet context to share theme state
apps/dockstat/app/root.tsx
apps/dockstat/app/components/ui/Nav.tsx
apps/dockstat/app/components/ui/NavCards.tsx
apps/dockstat/app/routes/api.v1.conf.tsx
apps/dockstat/app/routes/api.v1.conf.navlinks.tsx
Update startup scripts and error handling
  • Add install-deps.sh to standardize bun install/update across workspaces
  • Exit process on startup errors in utils.startUp
  • Adjust injectVariables spacing and helper signatures
install-deps.sh
apps/dockstat/app/.server/src/utils.ts
Bump versions and dependencies across packages
  • Upgrade sqlite-wrapper, typings, logger, plugin-handler and others to latest versions
  • Align React Router and Bun peer dependencies
  • Switch workspace links to explicit versions where needed
package.json
apps/dockstat/package.json
packages/sqlite-wrapper/package.json
packages/typings/package.json
packages/logger/package.json
packages/db/package.json
packages/docker-client/package.json
packages/plugin-handler/package.json

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai bot changed the title @sourcery-ai Add Plugin Handler and Enhance SQLite Wrapper Oct 9, 2025
Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey there - I've reviewed your changes - here's some feedback:

  • Dependencies across packages are inconsistently pinned (mixing workspace:* and specific versions/latest); unify to a single strategy to avoid version mismatches in the monorepo.
  • The custom '~/.server' import alias is used alongside relative paths throughout the codebase; standardize and document your path mappings in tsconfig to keep imports consistent and clear.
  • PluginHandler has several similar try/catch blocks for load/update operations—extract a shared error-handling helper to DRY up those methods and improve maintainability.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Dependencies across packages are inconsistently pinned (mixing workspace:* and specific versions/latest); unify to a single strategy to avoid version mismatches in the monorepo.
- The custom '~/.server' import alias is used alongside relative paths throughout the codebase; standardize and document your path mappings in tsconfig to keep imports consistent and clear.
- PluginHandler has several similar try/catch blocks for load/update operations—extract a shared error-handling helper to DRY up those methods and improve maintainability.

## Individual Comments

### Comment 1
<location> `apps/dockstat/app/components/layout/Background.tsx:10-12` </location>
<code_context>
+import type { THEME } from "@dockstat/typings";
+
+export default function Background(theme: THEME.ThemeTable) {
+  if (theme.config.bg.useEffect) {
+    switch (theme.config.bg.effect) {
</code_context>

<issue_to_address>
**suggestion (bug_risk):** Background component does not return anything if useEffect is false.

Returning undefined may cause rendering problems. Explicitly return null or a fallback element for better clarity and stability.

```suggestion
  }
  return null;
}
```
</issue_to_address>

### Comment 2
<location> `apps/dockstat/app/components/layout/Background.tsx:7` </location>
<code_context>
+  if (theme.config.bg.useEffect) {
+    switch (theme.config.bg.effect) {
+      case "linear-gradient": {
+        return <LinearBG direction={theme.config.bg.linearGradientDirection} />
+      }
+    }
</code_context>

<issue_to_address>
**issue (bug_risk):** LinearBG is called without the required 'colors' prop.

Only 'direction' is passed to LinearBG; omitting 'colors' may lead to runtime errors or incorrect rendering.
</issue_to_address>

### Comment 3
<location> `packages/plugin-handler/src/utils.ts:33-34` </location>
<code_context>
+  }
+
+  logger.debug(`Checking if ${meta.name} has at least one plugin definition`)
+  const hasBackend = !!plugin.backendConfig
+  const hasFrontend = !!plugin.component
+  if (hasBackend && hasFrontend) {
+    errors.push("No Plugin definition found")
</code_context>

<issue_to_address>
**issue (bug_risk):** Logic for plugin definition presence is inverted.

The error is triggered when both backend and frontend are present, which contradicts the message. Please update the condition to correctly detect missing plugin definitions.
</issue_to_address>

### Comment 4
<location> `packages/plugin-handler/src/index.ts:257-261` </location>
<code_context>
+    return this.loadedPlugins.has(pluginName);
+  }
+
+  private writeFrontendComponent(data: PLUGIN.PluginTable) {
+    try {
+      if (!data.plugin.frontendConfig) {
</code_context>

<issue_to_address>
**suggestion (bug_risk):** writeFrontendComponent uses Bun.file.write with a string, which may not work as intended.

Bun.file.write may not create the file if it doesn't exist. Consider using Bun.write or ensure file creation before writing.

```suggestion
      const componentPath = this.getComponentPath(`${data.meta.name}-component`);
      Bun.write(componentPath, JSON.stringify(data.plugin.frontendConfig));
```
</issue_to_address>

### Comment 5
<location> `packages/typings/src/plugins.ts:41` </location>
<code_context>
+ * ctx.params is provided for route parameters / body if you want to pass them through.
+ * The action may return any R (synchronous or Promise).
+ */
+type BackendActionFn<T extends Record<string, unknown>, R = unknown> = (ctx: {
+  table: QueryBuilder<T> | null;
+  db: DB;
</code_context>

<issue_to_address>
**issue (complexity):** Consider simplifying type definitions by removing unnecessary generics and using direct key references.

```suggestion
// 1. Drop the extra “R” generic from BackendActionFn (it can always be `unknown`/inferred)
– type BackendActionFn<T extends Record<string, unknown>, R = unknown> = (ctx: { … }) => Promise<R> | R
+ type BackendActionFn<T extends Record<string, unknown>> =
+   (ctx: {
+      table: QueryBuilder<T> | null;
+      db: DB;
+      params?: Record<string, unknown>;
+      previousAction: unknown;
+    }) => Promise<unknown> | unknown;

// 2. Use plain `keyof A` for the route’s action names instead of `Extract<…>`
– type BackendRoute<ActionKeys> = {
–   method: "GET" | "POST";
–   actions: ActionKeys[];
– }
+ type BackendRoute<A extends DBActions<any>> = {
+   method: "GET" | "POST";
+   actions: (keyof A)[];
+ }

// 3. Wire up Config to the simpler BackendRoute<A> to remove one level of `Extract<…>`
– export type Config<
–   T extends Record<string, unknown>,
–   A extends DBActions<T>,
– > = {
–   table?: { … };
–   routes: Record<string, BackendRoute<Extract<keyof A, string>>>;
– }
+ export type Config<T extends Record<string, unknown>, A extends DBActions<T>> = {
+   table?: {
+     name: string;
+     jsonColumns: JsonColumnConfig<T>;
+     columns: Record<string, ColumnDefinition>;
+   };
+   routes: Record<string, BackendRoute<A>>;
+ }
```

These changes keep the same guarantees but:

- Remove the unused `R` generic on `BackendActionFn`.
- Use `(keyof A)[]` directly instead of `Extract<keyof A, string>`.
- Simplify the `Config` type to refer to `BackendRoute<A>` directly.
</issue_to_address>

### Comment 6
<location> `packages/plugin-handler/src/index.ts:7` </location>
<code_context>
+import Plugin from "./pluginBuilder";
+import { buildPluginLink, logger, validatePlugin } from "./utils";
+
+class PluginHandler {
+  private DB: DB;
+  private pluginTable: QueryBuilder<PLUGIN.PluginTable>;
</code_context>

<issue_to_address>
**issue (complexity):** Consider refactoring PluginHandler by extracting plugin loading, execution, frontend writing, and error logging into separate modules to improve maintainability.

Here are a few small refactors you can apply so that PluginHandler stops growing into a 250-line “God class”:

1. Extract the plugin loading logic into its own service (e.g. PluginLoader)  
2. Extract execution (`executeAction`/`executeRoute`) into a PluginExecutor  
3. Move frontend‐file I/O into a FrontendWriter  
4. Centralize the error‐logging boilerplate with a small helper

----  
### 1) New file: `pluginLoader.ts`
```ts
import { logger } from "./utils";
export class PluginLoader {
  constructor(
    private DB: DB,
    private registry: Map<string, PLUGIN.PluginRegistry>
  ) {}

  async load(pluginData: PLUGIN.PluginTable): Promise<PLUGIN.PluginInstance> {
    return withErrorLogging(`loadPlugin ${pluginData.meta.name}`, async () => {
      const { backendConfig, backendActions } = pluginData.plugin;
      if (!backendConfig || !backendActions) {
        throw new Error(`…no backend configuration`);
      }
      const plugin = new Plugin(pluginData.meta, backendConfig, backendActions, this.DB);
      this.registry.set(pluginData.meta.name, {
        instance: plugin,
        routes: backendConfig.routes || {},
      });
      logger.debug(`Loaded plugin: ${pluginData.meta.name}`);
      return plugin;
    });
  }

  async loadAll(allData: PLUGIN.PluginTable[]) {
    const results = await Promise.allSettled(allData.map(d => this.load(d)));
    const failed = results.filter(r => r.status === "rejected").length;
    if (failed) logger.warn(`Failed to load ${failed} plugins`);
    return { loaded: allData.length - failed, failed };
  }
}
```

### 2) New file: `pluginExecutor.ts`
```ts
export class PluginExecutor {
  constructor(private registry: Map<string, PLUGIN.PluginRegistry>, private DB: DB) {}

  async executeAction(name: string, action: string, params?, prev?): Promise<unknown> {
    const reg = this.registry.get(name);
    if (!reg) throw new Error(`${name} not loaded`);
    const fn = reg.instance.backendActions[action];
    if (!fn) throw new Error(`${action} not found`);
    return fn({ db: this.DB, table: reg.instance.table, params, previousAction: prev });
  }

  async executeRoute(name: string, route: string, params?): Promise<unknown[]> {
    const reg = this.registry.get(name);
    if (!reg) throw new Error(`${name} not loaded`);
    const plan = reg.routes[route];
    if (!plan) throw new Error(`${route} not found`);
    const out: unknown[] = [];
    let prev;
    for (const act of plan.actions) {
      prev = await this.executeAction(name, act, params, prev);
      out.push(prev);
    }
    return out;
  }
}
```

### 3) New file: `frontendWriter.ts`
```ts
export class FrontendWriter {
  constructor(private getPath: (n: string) => string, private logger: typeof logger) {}

  write(data: PLUGIN.PluginTable) {
    if (!data.plugin.frontendConfig) {
      this.logger.debug(`No Frontend for ${data.meta.name}`);
      return;
    }
    const path = this.getPath(`${data.meta.name}-component`);
    Bun.file(path).write(JSON.stringify(data.plugin.frontendConfig));
  }
}
```

### 4) Small helper for error logging
```ts
// utils/errorWrapper.ts
import { logger } from "./utils";
export async function withErrorLogging<T>(ctx: string, fn: () => Promise<T>): Promise<T> {
  try { return await fn(); }
  catch (err) {
    logger.error(`Error in ${ctx}: ${err}`);
    throw err;
  }
}
```

Then in your original `PluginHandler` simply instantiate and delegate:

```ts
export default class PluginHandler {
  private loaded = new Map<string, PLUGIN.PluginRegistry>();
  private loader = new PluginLoader(this.DB, this.loaded);
  private executor = new PluginExecutor(this.loaded, this.DB);
  private writer  = new FrontendWriter(this.getComponentPath, logger);

  async loadPlugin(d)      { return this.loader.load(d) }
  async loadAllPlugins()   { return this.loader.loadAll(this.getPlugins()) }
  executeAction(n,a,p,pr)  { return this.executor.executeAction(n,a,p,pr) }
  executeRoute(n,r,p)      { return this.executor.executeRoute(n,r,p) }
  registerPlugin(d) {
    const rec = this.pluginTable.insertAndGet(d);
    this.loader.load(rec);
    this.writer.write(rec);
    return rec;
  }
  // …etc
}
```

This keeps all functionality intact but splits responsibilities into focused, testable modules and removes repeated try/catch blocks.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines 10 to 12
}
return;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): Background component does not return anything if useEffect is false.

Returning undefined may cause rendering problems. Explicitly return null or a fallback element for better clarity and stability.

Suggested change
}
return;
}
}
return null;
}

if (theme.config.bg.useEffect) {
switch (theme.config.bg.effect) {
case "linear-gradient": {
return <LinearBG direction={theme.config.bg.linearGradientDirection} />
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): LinearBG is called without the required 'colors' prop.

Only 'direction' is passed to LinearBG; omitting 'colors' may lead to runtime errors or incorrect rendering.

Comment on lines 257 to 261
const file = Bun.file(
this.getComponentPath(`${data.meta.name}-component`)
);

file.write(JSON.stringify(data.plugin.frontendConfig));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): writeFrontendComponent uses Bun.file.write with a string, which may not work as intended.

Bun.file.write may not create the file if it doesn't exist. Consider using Bun.write or ensure file creation before writing.

Suggested change
const file = Bun.file(
this.getComponentPath(`${data.meta.name}-component`)
);
file.write(JSON.stringify(data.plugin.frontendConfig));
const componentPath = this.getComponentPath(`${data.meta.name}-component`);
Bun.write(componentPath, JSON.stringify(data.plugin.frontendConfig));

* ctx.params is provided for route parameters / body if you want to pass them through.
* The action may return any R (synchronous or Promise).
*/
type BackendActionFn<T extends Record<string, unknown>, R = unknown> = (ctx: {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (complexity): Consider simplifying type definitions by removing unnecessary generics and using direct key references.

Suggested change
type BackendActionFn<T extends Record<string, unknown>, R = unknown> = (ctx: {
// 1. Drop the extra “R” generic from BackendActionFn (it can always be `unknown`/inferred)
type BackendActionFn<T extends Record<string, unknown>, R = unknown> = (ctx: { }) => Promise<R> | R
+ type BackendActionFn<T extends Record<string, unknown>> =
+ (ctx: {
+ table: QueryBuilder<T> | null;
+ db: DB;
+ params?: Record<string, unknown>;
+ previousAction: unknown;
+ }) => Promise<unknown> | unknown;
// 2. Use plain `keyof A` for the route’s action names instead of `Extract<…>`
type BackendRoute<ActionKeys> = {
method: "GET" | "POST";
actions: ActionKeys[];
}
+ type BackendRoute<A extends DBActions<any>> = {
+ method: "GET" | "POST";
+ actions: (keyof A)[];
+ }
// 3. Wire up Config to the simpler BackendRoute<A> to remove one level of `Extract<…>`
export type Config<
T extends Record<string, unknown>,
A extends DBActions<T>,
> = {
table?: { };
routes: Record<string, BackendRoute<Extract<keyof A, string>>>;
}
+ export type Config<T extends Record<string, unknown>, A extends DBActions<T>> = {
+ table?: {
+ name: string;
+ jsonColumns: JsonColumnConfig<T>;
+ columns: Record<string, ColumnDefinition>;
+ };
+ routes: Record<string, BackendRoute<A>>;
+ }

These changes keep the same guarantees but:

  • Remove the unused R generic on BackendActionFn.
  • Use (keyof A)[] directly instead of Extract<keyof A, string>.
  • Simplify the Config type to refer to BackendRoute<A> directly.

This commit introduces several enhancements to the create table functionality, including comprehensive type-safe column definitions using TableSchema, support for table constraints (PRIMARY KEY, UNIQUE, CHECK, FOREIGN KEY), and the ability to add table comments as metadata. Additionally, the commit includes bug fixes and improvements.

- Implemented comprehensive type-safe column definitions using TableSchema
- Added support for table constraints (PRIMARY KEY, UNIQUE, CHECK, FOREIGN KEY)
- Added ability to add table comments as metadata
- Improved error handling and validation for column definitions
- Fixed issue with AUTOINCREMENT usage validation
- Added utility functions for building SQL column definitions and table constraints
This commit adds the basic scaffolding for the dockstore app.
It also includes the installation of js-yaml and associated types
and the sqlite-wrapper for local plugin data persistence.
Some files from DockStacks were removed and the app code was added

Body:

- Created a simple index.ts file for the dockstore app.
- Added a .gitignore file.
- Added placeholder dependencies.
- Updated package.json with updated dependencies and metadata for local plugin data persistence.
- Removed files related to DockStacks templates and themes.
- Added dockstacks plugin scaffolding
The `writeStackToDisk` function call was removed from the insertStack action. This function was responsible for writing the stack configuration to disk, but this functionality is no longer required.
@github-advanced-security
Copy link

This pull request sets up GitHub code scanning for this repository. Once the scans have completed and the checks have passed, the analysis results for this pull request branch will appear on this overview. Once you merge this pull request, the 'Security' tab will show more code scanning analysis results (for example, for the default branch). Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results. For more information about GitHub code scanning, check out the documentation.

Its4Nik and others added 10 commits October 12, 2025 05:28
This commit introduces the dockstack deployment endpoint, enabling dynamic deployment of Docker Compose stacks via API calls.

- Adds .gitignore for ignoring node_modules, build artifacts, logs and other non-essential files.
- Adds README.md for basic usage
- Implements the `/dockstack/deploy/:id/:name` endpoint to handle stack deployments.
- Includes file handling functions to write YAML configuration files.
- Introduces a logger for the dockstack module for better traceability and error handling.
- Includes a sample Elysia app with the dockstack endpoint integrated.
- Adds a tsconfig.json file with compiler options configured for the project.
This commit refactors the dockstack deployment process, introduces an authentication plugin, and includes several improvements to logging and configuration.

The following changes were made:

-   Replaced the deprecated `bun.lock` file with `package.json` dependencies
-   Implemented a new Docker Compose file writing mechanism with variable parsing.
-   Added an authentication plugin to secure API endpoints.
-   Introduced more detailed logging for debugging and operational insights.
-   Add the ability to delete Dockstacks
-   Add Openapi integration
This commit refactors the logger to support hierarchical logging using a Logger class. The Logger class allows for the creation of child loggers with a parent-child relationship, enabling more granular control over logging output. The logging format is updated to include the logger's prefix and a hierarchy of parent prefixes.
This commit introduces a plugin architecture for DockStore, allowing for extensible functionality through plugins, themes, and stacks. It includes initial implementations for processing and building plugins, themes, and stacks, generating a manifest file, and updating the README with plugin details.

The following changes were made:

- Added .gitignore entry for .dist directory
- Updated README to include DockStore description and plugin information
- Implemented plugin architecture in index.ts to process plugins, themes, and stacks
- Added utility functions for manifest processing and file system operations
- Introduced a build process for plugins using Bun.build
- Created new components including the actions and supporting files for the docknode-plugin and dockstacks plugin
- Added a manifest.json file to showcase sample plugin metadata
- Updated package.json with new dependencies
- Created a util function for rendering markdown from manifest.json
This commit updates the dependencies in the dockstat package.json file. It also adds the elysia-react-router dependency.
This commit introduces the core functionality of the docknode application. It includes:

- Dockerfile and .dockerignore for containerization
- Environment type definitions
- Updated package.json with build script and dependencies
- Builder script for production builds
- Authentication model and adapter
- Dockstack handler with instance UUID generation
- Removed the old auth handler (replaced with elysia-basic-auth)
- Updated index.ts to include the auth plugin
- Includes a basic test call

This commit lays the foundation for deploying and managing docker stacks with authentication.
This commit adds the docknode application to the bun.lock file, including its dependencies and development dependencies. It also updates various dependencies for other applications and includes an override for elysia to version 1.4.12. Finally, it updates the typings for the plugin action handler.
This commit introduces Elysia as the backend framework for the DockStat API and includes restructuring the server for better modularity and scalability.

The following changes were made:

-   Integrated Elysia for API routing and middleware management.
-   Created adapter routes using Elysia to handle Docker host configurations.
-   Refactored the .server/index.ts to prepare for Elysia integration.
-   Updated dependencies for elysia and react-router.
-   Minor edits to docstrings and README.md

This change sets the foundation for future API enhancements and plugin support.
This commit includes several changes to the docknode application:

- Updates .dockerignore to exclude unnecessary files and directories.
- Modifies the Dockerfile to improve build process and use bun.
- Updates environment type definitions and builders.
- Updates dockstack handler and its dependencies.
- Removes unused or deprecated files related to archive data, front end, and docker setup

The changes aim to improve code organization, reduce Docker image size, improve handling environment variables and auth

Fixes: None
This commit introduces significant changes to modernize the DockStat application, focusing on server-side logic, API structure, and component architecture.

- 🗑️ Removed outdated server-side logic and legacy routing mechanisms.
- ✨ Introduced an Elysia-based API layer with OpenAPI documentation.
- 📝 Implemented API handlers and consolidated data handling.
- ♻️ Refactored server-side code for improved modularity and maintainability.
- 🔥 Removed deprecated UI components and streamlined styling.
- 🚀 Implemented updated dependency structure
- ✅ Simplified routing setup

These changes enhance the application's performance, scalability, and maintainability.
This commit fixes an issue where the file and line number reported by the logger were incorrect in certain environments.

The fix involves:

- Allowing the `DOCKSTAT_LOGGER_FULL_FILE_PATH` environment variable to influence how the caller information is derived.
- Using the correct depth when extracting the line number from the stack trace.
- Adding support for logger chaining using "@" as a separator

This ensures that the logger reports the correct file and line number, even when source maps are used or when the code is run in a production environment.

Also incremented the package version to 1.0.1.
This commit introduces a new template for building React Router v7 applications with an ElysiaJS backend.

The template includes:

-   Dockerfile and `.dockerignore` for containerization
-   `.gitignore` for excluding files
-   README.md with project overview and instructions
-   ElysiaJS server setup with WebSocket example
-   React Router setup with example routes
-   Tailwind CSS configuration
-   Type safety and build configurations

This template aims to provide a modern and efficient full-stack development experience with type safety and speed.
This commit updates the package name, description, keywords, and files included in the template package. It also corrects the installation instruction in the README file to point to the correct GitHub repository URL. Finally, it adds a thank you message with a link to the repository upon installation.
Removes a misleading note about WebSocket support.
🐛 Fix(dockstat): Implement config updates and API request IDs

This commit addresses several issues and introduces new features:

- **elysia:**  Updates the elysia version in docknode's package.json
- **Database Updates:** Implements database config updates for dockstat, allowing modifications to the DockStatConfigTable and returning a comprehensive response including update status and the new configuration.
- **API Request IDs:** Adds request IDs to API requests, improving traceability and debugging.
- **Database Initialization:** Provides a more robust database initialization process with comprehensive default settings.
- **Logger Context:** Adds request IDs to logger calls for better context.
```
This commit introduces several enhancements to the API, including:

- Adds API documentation through OpenAPI and Scalar.
- Implements request logging for debugging and monitoring.
- Introduces a new endpoint to retrieve DockStat configuration.
- Improves the way RequestIDs are handled and passed between the App and API
- Removes `welcome.tsx`

These changes aim to provide a more robust and well-documented API for DockStat.

- Introduces Elysia Plugins and Handlers for enhanced organization
Its4Nik and others added 17 commits October 23, 2025 23:16
…encies

This commit introduces the `PluginHandler` class in `@dockstat/plugin-handler` and updates the dependencies to use workspace references.

The `PluginHandler` class is responsible for managing plugins and interacting with the database and logger. It initializes a new `Logger` instance and uses `DB` and `QueryBuilder` classes from `@dockstat/sqlite-wrapper`.

The `@dockstat/plugin-handler` package's dependencies are updated to use `workspace:*` for `@dockstat/logger` and `@dockstat/sqlite-wrapper`. This ensures that the package uses the latest versions of these dependencies from the workspace.

The `bun.lock` file is updated to reflect the changes in the package dependencies. Additionally, the `@dockstat/typings` package is updated to export plugin-related types.
This commit introduces a PluginHandler class to manage and interact with plugins. The handler provides functionality for saving, deleting, loading, and unloading plugins from a database. It also includes a mechanism for triggering actions on loaded plugins based on Docker events.

Key changes:

- Created `PluginHandler` class with methods for managing plugins.
- Implemented database interaction for plugin persistence.
- Added event triggering mechanism to invoke plugin actions.
- Introduced `definePlugin` helper function.
- Updated typings to reflect new plugin structure
This commit refactors the plugin handler and updates its dependencies.

- Updates the @dockstat/plugin-handler dependency on @dockstat/logger to use workspace:* instead of latest.
- Removes redundant logger dependency from bun.lock.
- Updates plugin handler index.ts file
- Exports more plugin types from typings
The plugin types were moved to the plugins.ts file. This commit removes the duplicated types from the _types.ts file.
This commit refactors the plugin handler and SQLite wrapper to improve functionality and maintainability.

- Updates .gitignore to include .test-setup and exclude backup files.
- Modifies PluginHandler to include tags, function column handling, and event triggering.
- Deletes unused builder.ts file.
- Updates test plugin example.
- Enhances SQLite wrapper for better JSON and function column management.
- Updates typings for plugins to include ID and refined table definitions.

These changes enhance the plugin system's flexibility and robustness.
This commit introduces functionality for parsing and transforming JSON and MODULE columns in the query builder.  It enhances data handling for both fetching (transformRowFromDb, transformRowsFromDb) and inserting/updating (transformRowToDb) operations.

- Added logic to parse JSON columns when fetching data from the database, handling potential parsing errors gracefully.
- Implemented support for MODULE columns, utilizing Bun.Transpiler to transform and compile function strings into object URLs for dynamic importing.
- Updated the transformRowToDb method to serialize JSON columns before insertion/update.
- Added comprehensive logging for debugging and monitoring the transformation processes.
- Modified types to work with both JSON and Transpiler
This commit introduces a plugin system with database integration, allowing for dynamic loading and unloading of plugins.

- Implemented a new `PluginHandler` class in `@dockstat/plugin-handler` to manage plugin loading, unloading, and event triggering.
- Added a new API endpoint `/plugins` in `apps/dockstat/app/.server/api/plugins/index.ts` to fetch all plugins from the database.
- Modified the database schema to include a `plugins` table with necessary metadata like name, version, manifest, author, and event hooks.
- Updated `DockStatDB` to include a reference to the `pluginTable` QueryBuilder.
- Modified `sqlite-wrapper` to include module support.
feat(dockstat): Upgrade Bun runtime and enhance plugin handling

This commit upgrades the Bun runtime from 1.2.20 to 1.3.1. It also includes enhancements to plugin handling within DockStat, including adding routes for plugin status, installation, deletion, and custom routes. API documentation has been kept up to date through scalar openapi for consistency

```
… structure

Adds plugin management API endpoints for installing, deleting, and activating plugins. Introduces bundling for dockstore plugins and improves logging for API requests. Adds DockStore route to React Router.

- Implements plugin bundling via `bun` to `apps/dockstore`
- Enhances API for plugin management:
  - Adds routes in Elysia for retrieving, installing, deleting, and activating plugins.
  - Adds proxy route
  - Adds handlers for saving, deleting, loading, and handling routes for plugins.
  - Adds manifest URL installation for plugins.
- Improves API logging for requests and responses.
- Adds new `DockStore` route to `app/routes.ts`
- Adds `tags` and `detail` to the `database` route
- Enhances DB with default config

This commit restructures the plugin system, provides functionalities to manage plugins, improve the plugin loading/installation experience, API route management, and enhances logging for API requests.
This commit updates dependencies in `package.json` and `bun.lock` to their latest versions. It also adds `bunfig.toml` files to various packages and apps to configure bun with `linker = "isolated"`

The `install-deps.sh` script was removed.
This commit introduces a new `ui` package that contains reusable UI components built with React, TypeScript, and Vite. This package will be used across multiple applications within the monorepo to maintain a consistent look and feel.

The following components are included:
- Badge
- Button
- Card
- Checkbox
- CheckboxGroup
- Divider
- HoverBubble
- Input
- Link
- Modal
- Table
- Toggle

These components provide basic building blocks for creating user interfaces, including styling with tailwindcss.

🔥 Remove CI/CD pipelines and images

This commit removes the old CI/CD pipelines.
It also removes images from the .github directory that are no longer needed.
Adds a theme provider using tailwind's @theme directive
Updates component styles to use theme variables for consistent theming.
Updates dependencies.
Removes react logo from packages/ui/src/assets
This commit updates the `@biomejs/biome` dependency from version 1.9.4 to 2.3.3.
This includes updating the `bun.lock` and `package.json` files to reflect the new version.
A new `biome.json` file has been added to the `packages/ui` directory with linting, formatting, and assist configurations.
The `eslint.config.js` file has been removed from the `packages/ui` directory.
A new `DockStat2-06.png` file has been added to the `packages/ui/public` directory.
Several component updates and new components has been added to the `packages/ui/src/components` directory.
A new `Intro.stories.tsx` file has been added to the `packages/ui/src/stories` directory.
A new `Slider.stories.tsx` file has been added to the `packages/ui/src/stories` directory.
A new `Welcome.stories.tsx` file has been added to the `packages/ui/src/stories` directory.
The `tailwind.css` file has been updated with slider styling and animations.
Several welcome components have been added to the `packages/ui/src/welcome` directory.
The intro screen animation has been tweaked to improve the floating stripes and logo appearance. Also added a message property to the Intro screen to show a message in the Card.
This commit introduces a Plugin Store UI in the dockstat app, leveraging components from the `@dockstat/ui` package.  It also fixes an issue where the default config was not correctly written to the DB.

- Updates the app's styling to use Tailwind CSS from the `@dockstat/ui` package, and removes unused CSS.
- Implements DockStore component that fetches repos and installed plugins from the API to display plugin installation options.
- Adds basic utility for pulling repository data from Github
- Includes new dev tool configs
This commit introduces the Extension Browser, allowing users to browse, install, and uninstall extensions. It includes:

- New server actions for handling extension installation and uninstallation.
- New server loaders for fetching extension data.
- API endpoints for retrieving remote plugin manifests.
- Parsers for different repository types (currently only GitHub).
- UI components for displaying and interacting with extensions.
- Updated the DockStore route to use the new Extension Browser.

This also introduces a new react component @dockstat/ui ExtensionBrowser, and small changes to the db typings.
This commit introduces a new `/repo/manifest` endpoint to fetch a repository's manifest file (manifest.yml) and updates the `/plugin/manifest` endpoint to accept a plugin name parameter.  It also introduces the logic to retrieve and display a plugins metadata from various repositories in the Dockstore route.

The following changes were made:

- Added `getRepoManifest` function to fetch and parse the repository manifest file.
- Modified the `/extensions/plugin/manifest` endpoint to expect a plugin name in the params.
- Implemented API calls and logic to fetch and display plugin metadata in the Dockstore route, dynamically retrieving plugins from configured repositories.
- Fixed a schema error in the plugin get all endpoint.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants