@veap/plugins 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +131 -2
  3. package/dist/actions/index.d.ts +1 -0
  4. package/dist/actions/index.js +1 -0
  5. package/dist/actions/plugin.actions.d.ts +6 -0
  6. package/dist/actions/plugin.actions.js +60 -0
  7. package/dist/actions.d.ts +1 -0
  8. package/dist/actions.js +1 -0
  9. package/dist/cli/add.d.ts +4 -0
  10. package/dist/cli/add.js +191 -0
  11. package/dist/cli/eject.d.ts +2 -0
  12. package/dist/cli/eject.js +136 -0
  13. package/dist/cli/generate-plugin.d.ts +3 -0
  14. package/dist/cli/generate-plugin.js +48 -0
  15. package/dist/cli/index.d.ts +6 -0
  16. package/dist/cli/index.js +6 -0
  17. package/dist/cli/package-manager.d.ts +14 -0
  18. package/dist/cli/package-manager.js +62 -0
  19. package/dist/cli/stubs.d.ts +16 -0
  20. package/dist/cli/stubs.js +42 -0
  21. package/dist/cli/utils.d.ts +3 -0
  22. package/dist/cli/utils.js +164 -0
  23. package/dist/client.d.ts +6 -0
  24. package/dist/client.js +8 -0
  25. package/dist/common/context.d.ts +26 -0
  26. package/dist/common/context.js +26 -0
  27. package/dist/common/events.d.ts +19 -0
  28. package/dist/common/events.js +26 -0
  29. package/dist/common/index.d.ts +3 -0
  30. package/dist/common/index.js +3 -0
  31. package/dist/common/types.d.ts +195 -0
  32. package/dist/common/types.js +40 -0
  33. package/dist/index.d.ts +5 -0
  34. package/dist/index.js +5 -0
  35. package/dist/migrations/0001_create_plugins_tables.d.ts +4 -0
  36. package/dist/migrations/0001_create_plugins_tables.js +29 -0
  37. package/dist/migrations/index.d.ts +4 -0
  38. package/dist/migrations/index.js +7 -0
  39. package/dist/models/SystemPlugin.d.ts +19 -0
  40. package/dist/models/SystemPlugin.js +14 -0
  41. package/dist/models/SystemUserWidget.d.ts +19 -0
  42. package/dist/models/SystemUserWidget.js +17 -0
  43. package/dist/models/index.d.ts +2 -0
  44. package/dist/models/index.js +2 -0
  45. package/dist/models.d.ts +1 -0
  46. package/dist/models.js +1 -0
  47. package/dist/navigation/breadcrumbs.d.ts +2 -0
  48. package/dist/navigation/breadcrumbs.js +84 -0
  49. package/dist/navigation/index.d.ts +2 -0
  50. package/dist/navigation/index.js +2 -0
  51. package/dist/navigation/navigation.service.d.ts +27 -0
  52. package/dist/navigation/navigation.service.js +183 -0
  53. package/dist/providers/index.d.ts +1 -0
  54. package/dist/providers/index.js +1 -0
  55. package/dist/providers/plugins.provider.d.ts +20 -0
  56. package/dist/providers/plugins.provider.js +142 -0
  57. package/dist/registry/contracts.d.ts +72 -0
  58. package/dist/registry/contracts.js +4 -0
  59. package/dist/registry/facade.d.ts +45 -0
  60. package/dist/registry/facade.js +49 -0
  61. package/dist/registry/index.d.ts +5 -0
  62. package/dist/registry/index.js +5 -0
  63. package/dist/registry/migration-runner.d.ts +8 -0
  64. package/dist/registry/migration-runner.js +12 -0
  65. package/dist/registry/plugin.repository.d.ts +19 -0
  66. package/dist/registry/plugin.repository.js +74 -0
  67. package/dist/registry/registry.service.d.ts +69 -0
  68. package/dist/registry/registry.service.js +535 -0
  69. package/dist/router/discovery.d.ts +27 -0
  70. package/dist/router/discovery.js +37 -0
  71. package/dist/router/handler.d.ts +6 -0
  72. package/dist/router/handler.js +40 -0
  73. package/dist/router/index.d.ts +13 -0
  74. package/dist/router/index.js +13 -0
  75. package/dist/router/matcher.d.ts +5 -0
  76. package/dist/router/matcher.js +32 -0
  77. package/dist/router/middlewares.d.ts +25 -0
  78. package/dist/router/middlewares.js +119 -0
  79. package/dist/router/react/error-boundary.d.ts +30 -0
  80. package/dist/router/react/error-boundary.js +68 -0
  81. package/dist/router/react/index.d.ts +4 -0
  82. package/dist/router/react/index.js +4 -0
  83. package/dist/router/react/renderer.d.ts +13 -0
  84. package/dist/router/react/renderer.js +159 -0
  85. package/dist/router/react/soft-navigation.d.ts +4 -0
  86. package/dist/router/react/soft-navigation.js +34 -0
  87. package/dist/router/react/with-router.d.ts +22 -0
  88. package/dist/router/react/with-router.js +19 -0
  89. package/dist/router/route-tree.d.ts +177 -0
  90. package/dist/router/route-tree.js +633 -0
  91. package/dist/router/router.service.d.ts +25 -0
  92. package/dist/router/router.service.js +127 -0
  93. package/dist/router/scanner.d.ts +4 -0
  94. package/dist/router/scanner.js +337 -0
  95. package/dist/router/utils.d.ts +10 -0
  96. package/dist/router/utils.js +48 -0
  97. package/dist/router.d.ts +6 -0
  98. package/dist/router.js +6 -0
  99. package/dist/server.d.ts +11 -0
  100. package/dist/server.js +17 -0
  101. package/dist/widgets/index.d.ts +8 -0
  102. package/dist/widgets/index.js +8 -0
  103. package/dist/widgets/path-prefix-context.d.ts +5 -0
  104. package/dist/widgets/path-prefix-context.js +9 -0
  105. package/dist/widgets/plugin-extension-point-client.d.ts +15 -0
  106. package/dist/widgets/plugin-extension-point-client.js +44 -0
  107. package/dist/widgets/plugin-extension-point.d.ts +14 -0
  108. package/dist/widgets/plugin-extension-point.js +51 -0
  109. package/dist/widgets/plugin-widget-area-client.d.ts +11 -0
  110. package/dist/widgets/plugin-widget-area-client.js +31 -0
  111. package/dist/widgets/plugin-widget-area.d.ts +10 -0
  112. package/dist/widgets/plugin-widget-area.js +19 -0
  113. package/dist/widgets/use-confirm-action.d.ts +19 -0
  114. package/dist/widgets/use-confirm-action.js +68 -0
  115. package/dist/widgets/widget-composer-client.d.ts +21 -0
  116. package/dist/widgets/widget-composer-client.js +281 -0
  117. package/dist/widgets/widget-composer.d.ts +8 -0
  118. package/dist/widgets/widget-composer.js +28 -0
  119. package/package.json +115 -4
@@ -0,0 +1,72 @@
1
+ import type { IPlugin } from "../common";
2
+ /**
3
+ * Persisted status of a plugin (mirrors the `plugins` table).
4
+ */
5
+ export interface PluginStatusRecord {
6
+ id: string;
7
+ enabled: boolean;
8
+ installed: boolean;
9
+ system: boolean;
10
+ /** Raw JSON string of the plugin config, or `null`. */
11
+ config?: string | null;
12
+ lastStep?: string | null;
13
+ }
14
+ /**
15
+ * Backwards compatibility alias for PluginStatusRecord.
16
+ */
17
+ export type PluginRecord = PluginStatusRecord;
18
+ /**
19
+ * In-memory status overlay kept by the registry between DB syncs.
20
+ */
21
+ export interface PluginRuntimeStatus {
22
+ enabled: boolean;
23
+ installed: boolean;
24
+ lastStep?: string | null;
25
+ }
26
+ /** Payload used when a plugin row does not exist yet and must be created. */
27
+ export interface UpsertPluginStatusRecord {
28
+ enabled?: boolean;
29
+ installed?: boolean;
30
+ lastStep?: string | null;
31
+ }
32
+ /**
33
+ * Plugin status persistence port.
34
+ */
35
+ export interface IPluginRepository {
36
+ /** Returns all persisted plugin statuses. */
37
+ findAll(): Promise<PluginStatusRecord[]>;
38
+ /** Returns the persisted status of a single plugin, or `null`. */
39
+ findById(id: string): Promise<PluginStatusRecord | null>;
40
+ /**
41
+ * Bulk-seeds statuses for newly registered plugins.
42
+ * Existing rows are left alone except that `system` is re-merged.
43
+ */
44
+ seed(values: Array<{
45
+ id: string;
46
+ enabled: boolean;
47
+ installed: boolean;
48
+ system: boolean;
49
+ }>): Promise<void>;
50
+ /**
51
+ * Updates the status of a plugin, creating the row if it does not exist.
52
+ * `system` of the new row is taken from the registered plugin manifest.
53
+ */
54
+ upsertStatus(id: string, update: UpsertPluginStatusRecord, defaults: {
55
+ system: boolean;
56
+ }): Promise<void>;
57
+ /** Stores the raw JSON plugin config. */
58
+ updateConfig(id: string, configJson: string): Promise<void>;
59
+ }
60
+ /** Injection token for the plugin repository port. */
61
+ export declare const PLUGIN_REPOSITORY: unique symbol;
62
+ /**
63
+ * Migration runner port.
64
+ */
65
+ export interface IMigrationRunner {
66
+ run(scope: string, migrations: any[]): Promise<void>;
67
+ rollback(scope: string, migrations: any[]): Promise<void>;
68
+ }
69
+ /** Injection token for the migration runner port. */
70
+ export declare const MIGRATION_RUNNER: unique symbol;
71
+ /** Convenience type re-export so consumers can name the contract. */
72
+ export type { IPlugin };
@@ -0,0 +1,4 @@
1
+ /** Injection token for the plugin repository port. */
2
+ export const PLUGIN_REPOSITORY = Symbol.for("veap:plugins:repository");
3
+ /** Injection token for the migration runner port. */
4
+ export const MIGRATION_RUNNER = Symbol.for("veap:plugins:migration-runner");
@@ -0,0 +1,45 @@
1
+ import type { IPlugin } from "../common";
2
+ /**
3
+ * Module-level helpers over the {@link PluginRegistry}.
4
+ *
5
+ * They read the composition-bound plugins context instead of resolving
6
+ * services from the IoC container themselves.
7
+ */
8
+ export declare const registerPlugins: (plugins: IPlugin[]) => Promise<void>;
9
+ export declare const ensurePluginsInitialized: () => Promise<void>;
10
+ export declare const applyPluginFilters: <T = any>(point: string, data: T,
11
+ /** Optional context (e.g. { userId }) passed to handlers as 2nd argument. */
12
+ context?: any) => Promise<T>;
13
+ export declare const togglePluginState: (id: string, enabled: boolean, context?: any) => Promise<void>;
14
+ export declare const hasPluginHooks: (point: string) => Promise<boolean>;
15
+ export declare const hasPluginExtension: (target: string, point?: string) => Promise<boolean>;
16
+ export declare const getPluginConfig: <T = any>(id: string) => Promise<T | null>;
17
+ export declare const updatePluginConfig: (id: string, config: any) => Promise<void>;
18
+ export declare const getPluginsStatus: () => Promise<{
19
+ enabled: boolean;
20
+ installed: boolean;
21
+ lastStep: string | null;
22
+ id: string;
23
+ name: string;
24
+ version: string;
25
+ description?: string;
26
+ dependencies?: string[];
27
+ extends?: string[];
28
+ system?: boolean;
29
+ hasSetup?: boolean;
30
+ author?: string;
31
+ }[]>;
32
+ export declare const getPluginStatus: (id: string) => Promise<{
33
+ enabled: boolean;
34
+ installed: boolean;
35
+ lastStep: string | null;
36
+ id: string;
37
+ name: string;
38
+ version: string;
39
+ description?: string;
40
+ dependencies?: string[];
41
+ extends?: string[];
42
+ system?: boolean;
43
+ hasSetup?: boolean;
44
+ author?: string;
45
+ } | null>;
@@ -0,0 +1,49 @@
1
+ import { pluginsContext } from "../common";
2
+ /**
3
+ * Module-level helpers over the {@link PluginRegistry}.
4
+ *
5
+ * They read the composition-bound plugins context instead of resolving
6
+ * services from the IoC container themselves.
7
+ */
8
+ export const registerPlugins = async (plugins) => {
9
+ const registry = pluginsContext().registry;
10
+ for (const plugin of plugins)
11
+ registry.register(plugin);
12
+ };
13
+ export const ensurePluginsInitialized = async () => {
14
+ await pluginsContext().registry.init();
15
+ };
16
+ export const applyPluginFilters = async (point, data,
17
+ /** Optional context (e.g. { userId }) passed to handlers as 2nd argument. */
18
+ context) => {
19
+ const hooks = await pluginsContext().registry.getHooks(point);
20
+ let result = data;
21
+ for (const hook of hooks) {
22
+ const fn = hook.handler ?? hook.callback;
23
+ if (typeof fn === "function") {
24
+ result = await fn(result, context);
25
+ }
26
+ }
27
+ return result;
28
+ };
29
+ export const togglePluginState = async (id, enabled, context) => {
30
+ await pluginsContext().registry.togglePlugin(id, enabled, context);
31
+ };
32
+ export const hasPluginHooks = async (point) => {
33
+ return pluginsContext().registry.hasHooks(point);
34
+ };
35
+ export const hasPluginExtension = async (target, point) => {
36
+ return pluginsContext().registry.hasExtension(target, point);
37
+ };
38
+ export const getPluginConfig = async (id) => {
39
+ return pluginsContext().registry.getConfig(id);
40
+ };
41
+ export const updatePluginConfig = async (id, config) => {
42
+ await pluginsContext().registry.updateConfig(id, config);
43
+ };
44
+ export const getPluginsStatus = async () => {
45
+ return pluginsContext().registry.getPluginsStatus();
46
+ };
47
+ export const getPluginStatus = async (id) => {
48
+ return pluginsContext().registry.getPluginStatus(id);
49
+ };
@@ -0,0 +1,5 @@
1
+ export * from "./contracts";
2
+ export * from "./facade";
3
+ export * from "./migration-runner";
4
+ export * from "./plugin.repository";
5
+ export * from "./registry.service";
@@ -0,0 +1,5 @@
1
+ export * from "./contracts";
2
+ export * from "./facade";
3
+ export * from "./migration-runner";
4
+ export * from "./plugin.repository";
5
+ export * from "./registry.service";
@@ -0,0 +1,8 @@
1
+ import type { IMigrationRunner } from "./contracts";
2
+ /**
3
+ * `IMigrationRunner` adapter delegating to the knex-based migration runner.
4
+ */
5
+ export declare class KnexMigrationRunner implements IMigrationRunner {
6
+ run(scope: string, migrations: any[]): Promise<void>;
7
+ rollback(scope: string, migrations: any[]): Promise<void>;
8
+ }
@@ -0,0 +1,12 @@
1
+ import { rollbackMigrations, runMigrations } from "@veap/database";
2
+ /**
3
+ * `IMigrationRunner` adapter delegating to the knex-based migration runner.
4
+ */
5
+ export class KnexMigrationRunner {
6
+ run(scope, migrations) {
7
+ return runMigrations(scope, migrations);
8
+ }
9
+ rollback(scope, migrations) {
10
+ return rollbackMigrations(scope, migrations);
11
+ }
12
+ }
@@ -0,0 +1,19 @@
1
+ import type { IPluginRepository, PluginStatusRecord, UpsertPluginStatusRecord } from "./contracts";
2
+ /**
3
+ * `IPluginRepository` adapter backed by the `SystemPlugin` ActiveRecord model
4
+ * and the raw `plugins` table for bulk seeding.
5
+ */
6
+ export declare class ActiveRecordPluginRepository implements IPluginRepository {
7
+ findAll(): Promise<PluginStatusRecord[]>;
8
+ findById(id: string): Promise<PluginStatusRecord | null>;
9
+ seed(values: Array<{
10
+ id: string;
11
+ enabled: boolean;
12
+ installed: boolean;
13
+ system: boolean;
14
+ }>): Promise<void>;
15
+ upsertStatus(id: string, update: UpsertPluginStatusRecord, defaults: {
16
+ system: boolean;
17
+ }): Promise<void>;
18
+ updateConfig(id: string, configJson: string): Promise<void>;
19
+ }
@@ -0,0 +1,74 @@
1
+ import { SystemPlugin } from "../models/SystemPlugin";
2
+ /**
3
+ * `IPluginRepository` adapter backed by the `SystemPlugin` ActiveRecord model
4
+ * and the raw `plugins` table for bulk seeding.
5
+ */
6
+ export class ActiveRecordPluginRepository {
7
+ async findAll() {
8
+ const rows = await SystemPlugin.all();
9
+ return rows.map((row) => ({
10
+ id: row.id,
11
+ enabled: Boolean(row.enabled),
12
+ installed: Boolean(row.installed),
13
+ system: Boolean(row.system),
14
+ config: row.config ?? null,
15
+ lastStep: row.lastStep ?? null,
16
+ }));
17
+ }
18
+ async findById(id) {
19
+ const row = await SystemPlugin.find(id);
20
+ if (!row)
21
+ return null;
22
+ return {
23
+ id,
24
+ enabled: Boolean(row.enabled),
25
+ installed: Boolean(row.installed),
26
+ system: Boolean(row.system),
27
+ config: row.config ?? null,
28
+ lastStep: row.lastStep ?? null,
29
+ };
30
+ }
31
+ async seed(values) {
32
+ if (values.length === 0)
33
+ return;
34
+ const { getKnex } = await import("@veap/database");
35
+ const knex = getKnex();
36
+ await knex("plugins")
37
+ .insert(values.map((p) => ({
38
+ id: p.id,
39
+ enabled: p.enabled,
40
+ installed: p.installed,
41
+ system: p.system,
42
+ })))
43
+ .onConflict("id")
44
+ .merge(["system"]);
45
+ }
46
+ async upsertStatus(id, update, defaults) {
47
+ const existing = await SystemPlugin.find(id);
48
+ if (existing) {
49
+ if (update.enabled !== undefined)
50
+ existing.setAttribute("enabled", update.enabled);
51
+ if (update.installed !== undefined)
52
+ existing.setAttribute("installed", update.installed);
53
+ if (update.lastStep !== undefined)
54
+ existing.setAttribute("lastStep", update.lastStep);
55
+ existing.setAttribute("updatedAt", new Date());
56
+ await existing.save();
57
+ return;
58
+ }
59
+ await SystemPlugin.create({
60
+ id,
61
+ enabled: update.enabled ?? false,
62
+ installed: update.installed ?? false,
63
+ lastStep: update.lastStep ?? null,
64
+ system: defaults.system,
65
+ updatedAt: new Date(),
66
+ });
67
+ }
68
+ async updateConfig(id, configJson) {
69
+ await SystemPlugin.where("id", id).update({
70
+ config: configJson,
71
+ updatedAt: new Date(),
72
+ });
73
+ }
74
+ }
@@ -0,0 +1,69 @@
1
+ import { type IEventBus, type ILogger } from "@veap/kernel";
2
+ import { type IMigrationRunner, type IPluginRepository } from "./contracts";
3
+ import type { IPlugin } from "../common";
4
+ export declare class PluginRegistry {
5
+ private readonly repository;
6
+ private readonly migrationRunner;
7
+ private readonly logger;
8
+ private readonly eventBus;
9
+ private plugins;
10
+ private pluginStatus;
11
+ private processingPlugins;
12
+ private initPromise;
13
+ private initialized;
14
+ constructor(repository: IPluginRepository, migrationRunner: IMigrationRunner, logger: ILogger, eventBus: IEventBus);
15
+ /** Lookup a plugin by id, falling back to the npm-name form. */
16
+ private findPlugin;
17
+ register(plugin: IPlugin): void;
18
+ private updateStatus;
19
+ private updateStep;
20
+ private sortPlugins;
21
+ init(): Promise<void>;
22
+ getPlugins(): IPlugin[];
23
+ getEnabledPlugins(): IPlugin[];
24
+ getPlugin(id: string): IPlugin | undefined;
25
+ getPluginsStatus(): Promise<{
26
+ enabled: boolean;
27
+ installed: boolean;
28
+ lastStep: string | null;
29
+ id: string;
30
+ name: string;
31
+ version: string;
32
+ description?: string;
33
+ dependencies?: string[];
34
+ extends?: string[];
35
+ system?: boolean;
36
+ hasSetup?: boolean;
37
+ author?: string;
38
+ }[]>;
39
+ getPluginStatus(id: string): Promise<{
40
+ enabled: boolean;
41
+ installed: boolean;
42
+ lastStep: string | null;
43
+ id: string;
44
+ name: string;
45
+ version: string;
46
+ description?: string;
47
+ dependencies?: string[];
48
+ extends?: string[];
49
+ system?: boolean;
50
+ hasSetup?: boolean;
51
+ author?: string;
52
+ } | null>;
53
+ getHooks(point: string): Promise<import("..").PluginHook[]>;
54
+ getExtensions(target: string, point: string, includeDisabled?: boolean, context?: {
55
+ roles?: string[];
56
+ permissions?: string[];
57
+ }): Promise<import("..").PluginExtension[]>;
58
+ getWidgets(area: string, context?: {
59
+ roles?: string[];
60
+ permissions?: string[];
61
+ }): Promise<import("..").PluginWidget[]>;
62
+ private delay;
63
+ togglePlugin(id: string, enabled: boolean, context?: any): Promise<void>;
64
+ hasHooks(point: string): Promise<boolean>;
65
+ hasExtension(target: string, point?: string): Promise<boolean>;
66
+ getConfig<T>(id: string): Promise<T | null>;
67
+ updateConfig(id: string, config: any): Promise<void>;
68
+ }
69
+ export { applyPluginFilters, ensurePluginsInitialized, getPluginConfig, getPluginStatus, getPluginsStatus, hasPluginExtension, hasPluginHooks, registerPlugins, togglePluginState, updatePluginConfig, } from "./facade";