@objectstack/metadata 4.0.2 → 4.0.4

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.
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { MetadataFormat, MetadataLoaderContract, MetadataLoadOptions, MetadataLoadResult, MetadataStats, MetadataSaveOptions, MetadataSaveResult, MetadataWatchEvent, MetadataManagerConfig, PackagePublishResult, MetadataHistoryQueryOptions, MetadataHistoryQueryResult, MetadataDiffResult, MetadataHistoryRecord, MetadataHistoryRetentionPolicy } from '@objectstack/spec/system';
2
2
  export { MetadataCollectionInfo, MetadataDiffResult, MetadataExportOptions, MetadataFormat, MetadataHistoryQueryOptions, MetadataHistoryQueryResult, MetadataHistoryRecord, MetadataHistoryRetentionPolicy, MetadataImportOptions, MetadataLoadOptions, MetadataLoadResult, MetadataLoaderContract, MetadataManagerConfig, MetadataSaveOptions, MetadataSaveResult, MetadataStats, MetadataWatchEvent } from '@objectstack/spec/system';
3
- import { IMetadataService, IDataDriver, MetadataWatchCallback, MetadataWatchHandle, MetadataExportOptions, MetadataImportOptions, MetadataImportResult, MetadataTypeInfo, ISchemaDriver } from '@objectstack/spec/contracts';
3
+ import { IMetadataService, IDataDriver, IRealtimeService, MetadataWatchCallback, MetadataWatchHandle, MetadataExportOptions, MetadataImportOptions, MetadataImportResult, MetadataTypeInfo, ISchemaDriver } from '@objectstack/spec/contracts';
4
4
  export { IMetadataService, MetadataImportResult, MetadataTypeInfo, MetadataWatchCallback, MetadataWatchHandle } from '@objectstack/spec/contracts';
5
5
  import { MetadataTypeRegistryEntry, MetadataQuery, MetadataQueryResult, MetadataBulkResult, MetadataOverlay, MetadataValidationResult, MetadataDependency, MetadataPluginConfig } from '@objectstack/spec/kernel';
6
6
  export { MetadataBulkResult, MetadataDependency, MetadataPluginConfig, MetadataPluginManifest, MetadataQuery, MetadataQueryResult, MetadataType, MetadataTypeRegistryEntry, MetadataValidationResult } from '@objectstack/spec/kernel';
@@ -156,6 +156,7 @@ declare class MetadataManager implements IMetadataService {
156
156
  private overlays;
157
157
  private typeRegistry;
158
158
  private dependencies;
159
+ private realtimeService?;
159
160
  constructor(config: MetadataManagerOptions);
160
161
  /**
161
162
  * Set the type registry for metadata type discovery.
@@ -168,13 +169,22 @@ declare class MetadataManager implements IMetadataService {
168
169
  * @param driver - An IDataDriver instance for database operations
169
170
  */
170
171
  setDatabaseDriver(driver: IDataDriver): void;
172
+ /**
173
+ * Set the realtime service for publishing metadata change events.
174
+ * Should be called after kernel resolves the realtime service.
175
+ *
176
+ * @param service - An IRealtimeService instance for event publishing
177
+ */
178
+ setRealtimeService(service: IRealtimeService): void;
171
179
  /**
172
180
  * Register a new metadata loader (data source)
173
181
  */
174
182
  registerLoader(loader: MetadataLoader): void;
175
183
  /**
176
184
  * Register/save a metadata item by type
177
- * Stores in-memory registry and persists to writable loaders (if configured)
185
+ * Stores in-memory registry and persists to database-backed loaders only.
186
+ * FilesystemLoader (protocol 'file:') is read-only for static metadata and
187
+ * should not be written to during runtime registration.
178
188
  */
179
189
  register(type: string, name: string, data: unknown): Promise<void>;
180
190
  /**
@@ -187,7 +197,8 @@ declare class MetadataManager implements IMetadataService {
187
197
  */
188
198
  list(type: string): Promise<unknown[]>;
189
199
  /**
190
- * Unregister/remove a metadata item by type and name
200
+ * Unregister/remove a metadata item by type and name.
201
+ * Deletes from database-backed loaders only (same rationale as register()).
191
202
  */
192
203
  unregister(type: string, name: string): Promise<void>;
193
204
  /**
@@ -876,7 +887,7 @@ declare const SysMetadataObject: Omit<{
876
887
  actions?: {
877
888
  name: string;
878
889
  label: string;
879
- type: "url" | "script" | "modal" | "flow" | "api";
890
+ type: "url" | "flow" | "api" | "script" | "modal";
880
891
  refreshAfter: boolean;
881
892
  objectName?: string | undefined;
882
893
  icon?: string | undefined;
@@ -4557,7 +4568,7 @@ declare const SysMetadataHistoryObject: Omit<{
4557
4568
  actions?: {
4558
4569
  name: string;
4559
4570
  label: string;
4560
- type: "url" | "script" | "modal" | "flow" | "api";
4571
+ type: "url" | "flow" | "api" | "script" | "modal";
4561
4572
  refreshAfter: boolean;
4562
4573
  objectName?: string | undefined;
4563
4574
  icon?: string | undefined;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { MetadataFormat, MetadataLoaderContract, MetadataLoadOptions, MetadataLoadResult, MetadataStats, MetadataSaveOptions, MetadataSaveResult, MetadataWatchEvent, MetadataManagerConfig, PackagePublishResult, MetadataHistoryQueryOptions, MetadataHistoryQueryResult, MetadataDiffResult, MetadataHistoryRecord, MetadataHistoryRetentionPolicy } from '@objectstack/spec/system';
2
2
  export { MetadataCollectionInfo, MetadataDiffResult, MetadataExportOptions, MetadataFormat, MetadataHistoryQueryOptions, MetadataHistoryQueryResult, MetadataHistoryRecord, MetadataHistoryRetentionPolicy, MetadataImportOptions, MetadataLoadOptions, MetadataLoadResult, MetadataLoaderContract, MetadataManagerConfig, MetadataSaveOptions, MetadataSaveResult, MetadataStats, MetadataWatchEvent } from '@objectstack/spec/system';
3
- import { IMetadataService, IDataDriver, MetadataWatchCallback, MetadataWatchHandle, MetadataExportOptions, MetadataImportOptions, MetadataImportResult, MetadataTypeInfo, ISchemaDriver } from '@objectstack/spec/contracts';
3
+ import { IMetadataService, IDataDriver, IRealtimeService, MetadataWatchCallback, MetadataWatchHandle, MetadataExportOptions, MetadataImportOptions, MetadataImportResult, MetadataTypeInfo, ISchemaDriver } from '@objectstack/spec/contracts';
4
4
  export { IMetadataService, MetadataImportResult, MetadataTypeInfo, MetadataWatchCallback, MetadataWatchHandle } from '@objectstack/spec/contracts';
5
5
  import { MetadataTypeRegistryEntry, MetadataQuery, MetadataQueryResult, MetadataBulkResult, MetadataOverlay, MetadataValidationResult, MetadataDependency, MetadataPluginConfig } from '@objectstack/spec/kernel';
6
6
  export { MetadataBulkResult, MetadataDependency, MetadataPluginConfig, MetadataPluginManifest, MetadataQuery, MetadataQueryResult, MetadataType, MetadataTypeRegistryEntry, MetadataValidationResult } from '@objectstack/spec/kernel';
@@ -156,6 +156,7 @@ declare class MetadataManager implements IMetadataService {
156
156
  private overlays;
157
157
  private typeRegistry;
158
158
  private dependencies;
159
+ private realtimeService?;
159
160
  constructor(config: MetadataManagerOptions);
160
161
  /**
161
162
  * Set the type registry for metadata type discovery.
@@ -168,13 +169,22 @@ declare class MetadataManager implements IMetadataService {
168
169
  * @param driver - An IDataDriver instance for database operations
169
170
  */
170
171
  setDatabaseDriver(driver: IDataDriver): void;
172
+ /**
173
+ * Set the realtime service for publishing metadata change events.
174
+ * Should be called after kernel resolves the realtime service.
175
+ *
176
+ * @param service - An IRealtimeService instance for event publishing
177
+ */
178
+ setRealtimeService(service: IRealtimeService): void;
171
179
  /**
172
180
  * Register a new metadata loader (data source)
173
181
  */
174
182
  registerLoader(loader: MetadataLoader): void;
175
183
  /**
176
184
  * Register/save a metadata item by type
177
- * Stores in-memory registry and persists to writable loaders (if configured)
185
+ * Stores in-memory registry and persists to database-backed loaders only.
186
+ * FilesystemLoader (protocol 'file:') is read-only for static metadata and
187
+ * should not be written to during runtime registration.
178
188
  */
179
189
  register(type: string, name: string, data: unknown): Promise<void>;
180
190
  /**
@@ -187,7 +197,8 @@ declare class MetadataManager implements IMetadataService {
187
197
  */
188
198
  list(type: string): Promise<unknown[]>;
189
199
  /**
190
- * Unregister/remove a metadata item by type and name
200
+ * Unregister/remove a metadata item by type and name.
201
+ * Deletes from database-backed loaders only (same rationale as register()).
191
202
  */
192
203
  unregister(type: string, name: string): Promise<void>;
193
204
  /**
@@ -876,7 +887,7 @@ declare const SysMetadataObject: Omit<{
876
887
  actions?: {
877
888
  name: string;
878
889
  label: string;
879
- type: "url" | "script" | "modal" | "flow" | "api";
890
+ type: "url" | "flow" | "api" | "script" | "modal";
880
891
  refreshAfter: boolean;
881
892
  objectName?: string | undefined;
882
893
  icon?: string | undefined;
@@ -4557,7 +4568,7 @@ declare const SysMetadataHistoryObject: Omit<{
4557
4568
  actions?: {
4558
4569
  name: string;
4559
4570
  label: string;
4560
- type: "url" | "script" | "modal" | "flow" | "api";
4571
+ type: "url" | "flow" | "api" | "script" | "modal";
4561
4572
  refreshAfter: boolean;
4562
4573
  objectName?: string | undefined;
4563
4574
  icon?: string | undefined;
package/dist/index.js CHANGED
@@ -1039,6 +1039,16 @@ var MetadataManager = class {
1039
1039
  this.registerLoader(dbLoader);
1040
1040
  this.logger.info("DatabaseLoader configured", { datasource: this.config.datasource, tableName });
1041
1041
  }
1042
+ /**
1043
+ * Set the realtime service for publishing metadata change events.
1044
+ * Should be called after kernel resolves the realtime service.
1045
+ *
1046
+ * @param service - An IRealtimeService instance for event publishing
1047
+ */
1048
+ setRealtimeService(service) {
1049
+ this.realtimeService = service;
1050
+ this.logger.info("RealtimeService configured for metadata events");
1051
+ }
1042
1052
  /**
1043
1053
  * Register a new metadata loader (data source)
1044
1054
  */
@@ -1051,7 +1061,9 @@ var MetadataManager = class {
1051
1061
  // ==========================================
1052
1062
  /**
1053
1063
  * Register/save a metadata item by type
1054
- * Stores in-memory registry and persists to writable loaders (if configured)
1064
+ * Stores in-memory registry and persists to database-backed loaders only.
1065
+ * FilesystemLoader (protocol 'file:') is read-only for static metadata and
1066
+ * should not be written to during runtime registration.
1055
1067
  */
1056
1068
  async register(type, name, data) {
1057
1069
  if (!this.registry.has(type)) {
@@ -1059,10 +1071,29 @@ var MetadataManager = class {
1059
1071
  }
1060
1072
  this.registry.get(type).set(name, data);
1061
1073
  for (const loader of this.loaders.values()) {
1062
- if (loader.save) {
1074
+ if (loader.save && loader.contract.protocol === "datasource:" && loader.contract.capabilities.write) {
1063
1075
  await loader.save(type, name, data);
1064
1076
  }
1065
1077
  }
1078
+ if (this.realtimeService) {
1079
+ const event = {
1080
+ type: `metadata.${type}.created`,
1081
+ object: type,
1082
+ payload: {
1083
+ metadataType: type,
1084
+ name,
1085
+ definition: data,
1086
+ packageId: data?.packageId
1087
+ },
1088
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1089
+ };
1090
+ try {
1091
+ await this.realtimeService.publish(event);
1092
+ this.logger.debug(`Published metadata.${type}.created event`, { name });
1093
+ } catch (error) {
1094
+ this.logger.warn(`Failed to publish metadata event`, { type, name, error });
1095
+ }
1096
+ }
1066
1097
  }
1067
1098
  /**
1068
1099
  * Get a metadata item by type and name.
@@ -1103,7 +1134,8 @@ var MetadataManager = class {
1103
1134
  return Array.from(items.values());
1104
1135
  }
1105
1136
  /**
1106
- * Unregister/remove a metadata item by type and name
1137
+ * Unregister/remove a metadata item by type and name.
1138
+ * Deletes from database-backed loaders only (same rationale as register()).
1107
1139
  */
1108
1140
  async unregister(type, name) {
1109
1141
  const typeStore = this.registry.get(type);
@@ -1114,6 +1146,7 @@ var MetadataManager = class {
1114
1146
  }
1115
1147
  }
1116
1148
  for (const loader of this.loaders.values()) {
1149
+ if (loader.contract.protocol !== "datasource:" || !loader.contract.capabilities.write) continue;
1117
1150
  if (typeof loader.delete === "function") {
1118
1151
  try {
1119
1152
  await loader.delete(type, name);
@@ -1122,6 +1155,23 @@ var MetadataManager = class {
1122
1155
  }
1123
1156
  }
1124
1157
  }
1158
+ if (this.realtimeService) {
1159
+ const event = {
1160
+ type: `metadata.${type}.deleted`,
1161
+ object: type,
1162
+ payload: {
1163
+ metadataType: type,
1164
+ name
1165
+ },
1166
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1167
+ };
1168
+ try {
1169
+ await this.realtimeService.publish(event);
1170
+ this.logger.debug(`Published metadata.${type}.deleted event`, { name });
1171
+ } catch (error) {
1172
+ this.logger.warn(`Failed to publish metadata event`, { type, name, error });
1173
+ }
1174
+ }
1125
1175
  }
1126
1176
  /**
1127
1177
  * Check if a metadata item exists
@@ -2467,6 +2517,7 @@ var MetadataPlugin = class {
2467
2517
  watch: this.options.watch
2468
2518
  });
2469
2519
  ctx.registerService("metadata", this.manager);
2520
+ console.log("[MetadataPlugin] Registered metadata service, has getRegisteredTypes:", typeof this.manager.getRegisteredTypes);
2470
2521
  try {
2471
2522
  ctx.getService("manifest").register({
2472
2523
  id: "com.objectstack.metadata",
@@ -2510,6 +2561,52 @@ var MetadataPlugin = class {
2510
2561
  totalItems: totalLoaded,
2511
2562
  registeredTypes: sortedTypes.length
2512
2563
  });
2564
+ let driverBridged = false;
2565
+ try {
2566
+ const ql = ctx.getService("objectql");
2567
+ if (ql) {
2568
+ const tableName = this.manager["config"]?.tableName ?? "sys_metadata";
2569
+ const driver = ql.getDriverForObject?.(tableName);
2570
+ if (driver) {
2571
+ ctx.logger.info("[MetadataPlugin] Bridging driver to MetadataManager via ObjectQL routing", {
2572
+ tableName,
2573
+ driver: driver.name
2574
+ });
2575
+ this.manager.setDatabaseDriver(driver);
2576
+ driverBridged = true;
2577
+ } else {
2578
+ ctx.logger.debug("[MetadataPlugin] ObjectQL could not resolve driver for metadata table", { tableName });
2579
+ }
2580
+ }
2581
+ } catch {
2582
+ }
2583
+ if (!driverBridged) {
2584
+ try {
2585
+ const services = ctx.getServices();
2586
+ for (const [serviceName, service] of services) {
2587
+ if (serviceName.startsWith("driver.") && service) {
2588
+ ctx.logger.info("[MetadataPlugin] Bridging driver to MetadataManager (fallback: first driver)", {
2589
+ driverService: serviceName
2590
+ });
2591
+ this.manager.setDatabaseDriver(service);
2592
+ break;
2593
+ }
2594
+ }
2595
+ } catch (e) {
2596
+ ctx.logger.debug("[MetadataPlugin] No driver service found", { error: e.message });
2597
+ }
2598
+ }
2599
+ try {
2600
+ const realtimeService = ctx.getService("realtime");
2601
+ if (realtimeService && typeof realtimeService === "object" && "publish" in realtimeService) {
2602
+ ctx.logger.info("[MetadataPlugin] Bridging realtime service to MetadataManager for event publishing");
2603
+ this.manager.setRealtimeService(realtimeService);
2604
+ }
2605
+ } catch (e) {
2606
+ ctx.logger.debug("[MetadataPlugin] No realtime service found \u2014 metadata events will not be published", {
2607
+ error: e.message
2608
+ });
2609
+ }
2513
2610
  };
2514
2611
  this.options = {
2515
2612
  watch: true,