@objectstack/metadata 3.3.0 → 3.3.1
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.cjs +2197 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.js +42 -82
- package/dist/index.js.map +1 -1
- package/dist/node.cjs +2201 -0
- package/dist/node.cjs.map +1 -0
- package/dist/node.d.cts +65 -0
- package/dist/node.d.ts +65 -0
- package/dist/{index.mjs → node.js} +3 -1
- package/package.json +18 -13
- package/.turbo/turbo-build.log +0 -22
- package/CHANGELOG.md +0 -504
- package/ROADMAP.md +0 -224
- package/src/index.ts +0 -68
- package/src/loaders/database-loader.test.ts +0 -559
- package/src/loaders/database-loader.ts +0 -352
- package/src/loaders/filesystem-loader.ts +0 -420
- package/src/loaders/loader-interface.ts +0 -89
- package/src/loaders/memory-loader.ts +0 -103
- package/src/loaders/remote-loader.ts +0 -140
- package/src/metadata-manager.ts +0 -1168
- package/src/metadata-service.test.ts +0 -965
- package/src/metadata.test.ts +0 -431
- package/src/migration/executor.ts +0 -54
- package/src/migration/index.ts +0 -3
- package/src/node-metadata-manager.ts +0 -126
- package/src/node.ts +0 -11
- package/src/objects/sys-metadata.object.ts +0 -188
- package/src/plugin.ts +0 -102
- package/src/serializers/json-serializer.ts +0 -73
- package/src/serializers/serializer-interface.ts +0 -65
- package/src/serializers/serializers.test.ts +0 -74
- package/src/serializers/typescript-serializer.ts +0 -127
- package/src/serializers/yaml-serializer.ts +0 -49
- package/tsconfig.json +0 -9
- package/vitest.config.ts +0 -23
- /package/dist/{index.d.mts → index.d.cts} +0 -0
- /package/dist/{index.mjs.map → node.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/node.ts","../src/metadata-manager.ts","../src/serializers/json-serializer.ts","../src/serializers/yaml-serializer.ts","../src/serializers/typescript-serializer.ts","../src/objects/sys-metadata.object.ts","../src/loaders/database-loader.ts","../src/node-metadata-manager.ts","../src/loaders/filesystem-loader.ts","../src/plugin.ts","../src/loaders/memory-loader.ts","../src/loaders/remote-loader.ts","../src/migration/index.ts","../src/migration/executor.ts"],"sourcesContent":["// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Node.js specific exports for @objectstack/metadata\n */\n\nexport * from './index.js';\nexport { NodeMetadataManager } from './node-metadata-manager.js';\nexport { FilesystemLoader } from './loaders/filesystem-loader.js';\nexport { DatabaseLoader, type DatabaseLoaderOptions } from './loaders/database-loader.js';\nexport { MetadataPlugin } from './plugin.js';\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Metadata Manager\n * \n * Main orchestrator for metadata loading, saving, and persistence.\n * Implements the IMetadataService contract from @objectstack/spec.\n * Browser-compatible (Pure).\n */\n\nimport type {\n MetadataManagerConfig,\n MetadataLoadOptions,\n MetadataSaveOptions,\n MetadataSaveResult,\n MetadataWatchEvent,\n MetadataFormat,\n PackagePublishResult,\n} from '@objectstack/spec/system';\nimport type {\n IMetadataService,\n MetadataWatchCallback,\n MetadataWatchHandle,\n MetadataExportOptions,\n MetadataImportOptions,\n MetadataImportResult,\n MetadataTypeInfo,\n} from '@objectstack/spec/contracts';\nimport type {\n MetadataQuery,\n MetadataQueryResult,\n MetadataValidationResult,\n MetadataBulkResult,\n MetadataDependency,\n MetadataTypeRegistryEntry,\n} from '@objectstack/spec/kernel';\nimport type { MetadataOverlay } from '@objectstack/spec/kernel';\nimport { createLogger, type Logger } from '@objectstack/core';\nimport { JSONSerializer } from './serializers/json-serializer.js';\nimport { YAMLSerializer } from './serializers/yaml-serializer.js';\nimport { TypeScriptSerializer } from './serializers/typescript-serializer.js';\nimport type { MetadataSerializer } from './serializers/serializer-interface.js';\nimport type { IDataDriver } from '@objectstack/spec/contracts';\nimport type { MetadataLoader } from './loaders/loader-interface.js';\nimport { DatabaseLoader } from './loaders/database-loader.js';\n\n/**\n * Watch callback function (legacy)\n */\nexport type WatchCallback = (event: MetadataWatchEvent) => void | Promise<void>;\n\nexport interface MetadataManagerOptions extends MetadataManagerConfig {\n loaders?: MetadataLoader[];\n /** Optional IDataDriver instance. When provided alongside config.datasource, auto-configures DatabaseLoader. */\n driver?: IDataDriver;\n}\n\n/**\n * Main metadata manager class.\n * Implements IMetadataService contract for unified metadata management.\n */\nexport class MetadataManager implements IMetadataService {\n private loaders: Map<string, MetadataLoader> = new Map();\n // Protected so subclasses can access serializers if needed\n protected serializers: Map<MetadataFormat, MetadataSerializer>;\n protected logger: Logger;\n protected watchCallbacks = new Map<string, Set<WatchCallback>>();\n protected config: MetadataManagerOptions;\n\n // In-memory metadata registry: type -> name -> data\n private registry = new Map<string, Map<string, unknown>>();\n\n // Overlay storage: \"type:name:scope\" -> MetadataOverlay\n private overlays = new Map<string, MetadataOverlay>();\n\n // Type registry for metadata type info\n private typeRegistry: MetadataTypeRegistryEntry[] = [];\n\n // Dependency tracking: \"type:name\" -> dependencies\n private dependencies = new Map<string, MetadataDependency[]>();\n\n constructor(config: MetadataManagerOptions) {\n this.config = config;\n this.logger = createLogger({ level: 'info', format: 'pretty' });\n\n // Initialize serializers\n this.serializers = new Map();\n const formats = config.formats || ['typescript', 'json', 'yaml'];\n\n if (formats.includes('json')) {\n this.serializers.set('json', new JSONSerializer());\n }\n if (formats.includes('yaml')) {\n this.serializers.set('yaml', new YAMLSerializer());\n }\n if (formats.includes('typescript')) {\n this.serializers.set('typescript', new TypeScriptSerializer('typescript'));\n }\n if (formats.includes('javascript')) {\n this.serializers.set('javascript', new TypeScriptSerializer('javascript'));\n }\n\n // Initialize Loaders\n if (config.loaders && config.loaders.length > 0) {\n config.loaders.forEach(loader => this.registerLoader(loader));\n }\n\n // Auto-configure DatabaseLoader when datasource + driver are provided\n if (config.datasource && config.driver) {\n this.setDatabaseDriver(config.driver);\n }\n // Note: No default loader in base class. Subclasses (NodeMetadataManager) or caller must provide one.\n }\n\n /**\n * Set the type registry for metadata type discovery.\n */\n setTypeRegistry(entries: MetadataTypeRegistryEntry[]): void {\n this.typeRegistry = entries;\n }\n\n /**\n * Configure and register a DatabaseLoader for database-backed metadata persistence.\n * Can be called at any time to enable database storage (e.g. after kernel resolves the driver).\n *\n * @param driver - An IDataDriver instance for database operations\n */\n setDatabaseDriver(driver: IDataDriver): void {\n const tableName = this.config.tableName ?? 'sys_metadata';\n const dbLoader = new DatabaseLoader({\n driver,\n tableName,\n });\n this.registerLoader(dbLoader);\n this.logger.info('DatabaseLoader configured', { datasource: this.config.datasource, tableName });\n }\n\n /**\n * Register a new metadata loader (data source)\n */\n registerLoader(loader: MetadataLoader) {\n this.loaders.set(loader.contract.name, loader);\n this.logger.info(`Registered metadata loader: ${loader.contract.name} (${loader.contract.protocol})`);\n }\n\n // ==========================================\n // IMetadataService — Core CRUD Operations\n // ==========================================\n\n /**\n * Register/save a metadata item by type\n */\n async register(type: string, name: string, data: unknown): Promise<void> {\n if (!this.registry.has(type)) {\n this.registry.set(type, new Map());\n }\n this.registry.get(type)!.set(name, data);\n }\n\n /**\n * Get a metadata item by type and name.\n * Checks in-memory registry first, then falls back to loaders.\n */\n async get(type: string, name: string): Promise<unknown | undefined> {\n // Check in-memory registry first\n const typeStore = this.registry.get(type);\n if (typeStore?.has(name)) {\n return typeStore.get(name);\n }\n\n // Fallback to loaders\n const result = await this.load(type, name);\n return result ?? undefined;\n }\n\n /**\n * List all metadata items of a given type\n */\n async list(type: string): Promise<unknown[]> {\n const items = new Map<string, unknown>();\n\n // From in-memory registry\n const typeStore = this.registry.get(type);\n if (typeStore) {\n for (const [name, data] of typeStore) {\n items.set(name, data);\n }\n }\n\n // From loaders (deduplicate)\n for (const loader of this.loaders.values()) {\n try {\n const loaderItems = await loader.loadMany(type);\n for (const item of loaderItems) {\n const itemAny = item as any;\n if (itemAny && typeof itemAny.name === 'string' && !items.has(itemAny.name)) {\n items.set(itemAny.name, item);\n }\n }\n } catch (e) {\n this.logger.warn(`Loader ${loader.contract.name} failed to loadMany ${type}`, { error: e });\n }\n }\n\n return Array.from(items.values());\n }\n\n /**\n * Unregister/remove a metadata item by type and name\n */\n async unregister(type: string, name: string): Promise<void> {\n const typeStore = this.registry.get(type);\n if (typeStore) {\n typeStore.delete(name);\n if (typeStore.size === 0) {\n this.registry.delete(type);\n }\n }\n }\n\n /**\n * Check if a metadata item exists\n */\n async exists(type: string, name: string): Promise<boolean> {\n // Check in-memory registry\n if (this.registry.get(type)?.has(name)) {\n return true;\n }\n\n // Check loaders\n for (const loader of this.loaders.values()) {\n if (await loader.exists(type, name)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * List all names of metadata items of a given type\n */\n async listNames(type: string): Promise<string[]> {\n const names = new Set<string>();\n\n // From in-memory registry\n const typeStore = this.registry.get(type);\n if (typeStore) {\n for (const name of typeStore.keys()) {\n names.add(name);\n }\n }\n\n // From loaders\n for (const loader of this.loaders.values()) {\n const result = await loader.list(type);\n result.forEach(item => names.add(item));\n }\n\n return Array.from(names);\n }\n\n /**\n * Convenience: get an object definition by name\n */\n async getObject(name: string): Promise<unknown | undefined> {\n return this.get('object', name);\n }\n\n /**\n * Convenience: list all object definitions\n */\n async listObjects(): Promise<unknown[]> {\n return this.list('object');\n }\n\n // ==========================================\n // Convenience: UI Metadata\n // ==========================================\n\n /**\n * Convenience: get a view definition by name\n */\n async getView(name: string): Promise<unknown | undefined> {\n return this.get('view', name);\n }\n\n /**\n * Convenience: list view definitions, optionally filtered by object\n */\n async listViews(object?: string): Promise<unknown[]> {\n const views = await this.list('view');\n if (object) {\n return views.filter((v: any) => v?.object === object);\n }\n return views;\n }\n\n /**\n * Convenience: get a dashboard definition by name\n */\n async getDashboard(name: string): Promise<unknown | undefined> {\n return this.get('dashboard', name);\n }\n\n /**\n * Convenience: list all dashboard definitions\n */\n async listDashboards(): Promise<unknown[]> {\n return this.list('dashboard');\n }\n\n // ==========================================\n // Package Management\n // ==========================================\n\n /**\n * Unregister all metadata items from a specific package\n */\n async unregisterPackage(packageName: string): Promise<void> {\n for (const [type, typeStore] of this.registry) {\n const toDelete: string[] = [];\n for (const [name, data] of typeStore) {\n const meta = data as any;\n if (meta?.packageId === packageName || meta?.package === packageName) {\n toDelete.push(name);\n }\n }\n for (const name of toDelete) {\n typeStore.delete(name);\n }\n if (typeStore.size === 0) {\n this.registry.delete(type);\n }\n }\n }\n\n /**\n * Publish an entire package:\n * 1. Validate all draft items\n * 2. Snapshot all items in the package (publishedDefinition = clone(metadata))\n * 3. Increment version\n * 4. Set all items state → active\n */\n async publishPackage(packageId: string, options?: {\n changeNote?: string;\n publishedBy?: string;\n validate?: boolean;\n }): Promise<PackagePublishResult> {\n const now = new Date().toISOString();\n const shouldValidate = options?.validate !== false;\n const publishedBy = options?.publishedBy;\n\n // Collect all items belonging to this package\n const packageItems: Array<{ type: string; name: string; data: any }> = [];\n for (const [type, typeStore] of this.registry) {\n for (const [name, data] of typeStore) {\n const meta = data as any;\n if (meta?.packageId === packageId || meta?.package === packageId) {\n packageItems.push({ type, name, data: meta });\n }\n }\n }\n\n if (packageItems.length === 0) {\n return {\n success: false,\n packageId,\n version: 0,\n publishedAt: now,\n itemsPublished: 0,\n validationErrors: [{ type: '', name: '', message: `No metadata items found for package '${packageId}'` }],\n };\n }\n\n // Validation pass\n if (shouldValidate) {\n const validationErrors: Array<{ type: string; name: string; message: string }> = [];\n\n // Schema validation\n for (const item of packageItems) {\n const result = await this.validate(item.type, item.data);\n if (!result.valid && result.errors) {\n for (const err of result.errors) {\n validationErrors.push({\n type: item.type,\n name: item.name,\n message: err.message,\n });\n }\n }\n }\n\n // Dependency validation: referenced items must be in the same package or already published\n const packageItemKeys = new Set(packageItems.map(i => `${i.type}:${i.name}`));\n for (const item of packageItems) {\n const deps = await this.getDependencies(item.type, item.name);\n for (const dep of deps) {\n const depKey = `${dep.targetType}:${dep.targetName}`;\n // Skip if the dependency is within this package\n if (packageItemKeys.has(depKey)) continue;\n // Check if the dependency exists and has been published\n const depItem = await this.get(dep.targetType, dep.targetName);\n if (!depItem) {\n validationErrors.push({\n type: item.type,\n name: item.name,\n message: `Dependency '${dep.targetType}:${dep.targetName}' not found`,\n });\n } else {\n const depMeta = depItem as any;\n if (depMeta.publishedDefinition === undefined && depMeta.state !== 'active') {\n validationErrors.push({\n type: item.type,\n name: item.name,\n message: `Dependency '${dep.targetType}:${dep.targetName}' is not published`,\n });\n }\n }\n }\n }\n\n if (validationErrors.length > 0) {\n return {\n success: false,\n packageId,\n version: 0,\n publishedAt: now,\n itemsPublished: 0,\n validationErrors,\n };\n }\n }\n\n // Determine the next version by finding the max current version across items\n let maxVersion = 0;\n for (const item of packageItems) {\n const v = typeof item.data.version === 'number' ? item.data.version : 0;\n if (v > maxVersion) maxVersion = v;\n }\n const newVersion = maxVersion + 1;\n\n // Snapshot and update all items\n for (const item of packageItems) {\n const updated = {\n ...item.data,\n publishedDefinition: structuredClone(item.data.metadata ?? item.data),\n publishedAt: now,\n publishedBy: publishedBy ?? item.data.publishedBy,\n version: newVersion,\n state: 'active',\n };\n await this.register(item.type, item.name, updated);\n }\n\n return {\n success: true,\n packageId,\n version: newVersion,\n publishedAt: now,\n itemsPublished: packageItems.length,\n };\n }\n\n /**\n * Revert entire package to last published state.\n * Restores all metadata definitions from their published snapshots.\n */\n async revertPackage(packageId: string): Promise<void> {\n const packageItems: Array<{ type: string; name: string; data: any }> = [];\n for (const [type, typeStore] of this.registry) {\n for (const [name, data] of typeStore) {\n const meta = data as any;\n if (meta?.packageId === packageId || meta?.package === packageId) {\n packageItems.push({ type, name, data: meta });\n }\n }\n }\n\n if (packageItems.length === 0) {\n throw new Error(`No metadata items found for package '${packageId}'`);\n }\n\n // Check that at least one item has a published snapshot\n const hasPublished = packageItems.some(item => item.data.publishedDefinition !== undefined);\n if (!hasPublished) {\n throw new Error(`Package '${packageId}' has never been published`);\n }\n\n for (const item of packageItems) {\n if (item.data.publishedDefinition !== undefined) {\n const reverted = {\n ...item.data,\n metadata: structuredClone(item.data.publishedDefinition),\n state: 'active',\n };\n await this.register(item.type, item.name, reverted);\n }\n }\n }\n\n /**\n * Get the published version of any metadata item (for runtime serving).\n * Returns publishedDefinition if exists, else current definition.\n */\n async getPublished(type: string, name: string): Promise<unknown | undefined> {\n const item = await this.get(type, name);\n if (!item) return undefined;\n\n const meta = item as any;\n if (meta.publishedDefinition !== undefined) {\n return meta.publishedDefinition;\n }\n\n // Fall back to current definition (metadata field or the item itself)\n return meta.metadata ?? item;\n }\n\n // ==========================================\n // Query / Search\n // ==========================================\n\n /**\n * Query metadata items with filtering, sorting, and pagination\n */\n async query(query: MetadataQuery): Promise<MetadataQueryResult> {\n const { types, search, page = 1, pageSize = 50, sortBy = 'name', sortOrder = 'asc' } = query;\n\n // Collect all items\n const allItems: Array<{\n type: string;\n name: string;\n namespace?: string;\n label?: string;\n scope?: 'system' | 'platform' | 'user';\n state?: 'draft' | 'active' | 'archived' | 'deprecated';\n packageId?: string;\n updatedAt?: string;\n }> = [];\n\n // Determine which types to scan\n const targetTypes = types && types.length > 0\n ? types\n : Array.from(this.registry.keys());\n\n for (const type of targetTypes) {\n const items = await this.list(type);\n for (const item of items) {\n const meta = item as any;\n allItems.push({\n type,\n name: meta?.name ?? '',\n namespace: meta?.namespace,\n label: meta?.label,\n scope: meta?.scope,\n state: meta?.state,\n packageId: meta?.packageId,\n updatedAt: meta?.updatedAt,\n });\n }\n }\n\n // Apply search filter\n let filtered = allItems;\n if (search) {\n const searchLower = search.toLowerCase();\n filtered = filtered.filter(item =>\n item.name.toLowerCase().includes(searchLower) ||\n (item.label && item.label.toLowerCase().includes(searchLower))\n );\n }\n\n // Apply scope filter\n if (query.scope) {\n filtered = filtered.filter(item => item.scope === query.scope);\n }\n\n // Apply state filter\n if (query.state) {\n filtered = filtered.filter(item => item.state === query.state);\n }\n\n // Apply namespace filter\n if (query.namespaces && query.namespaces.length > 0) {\n filtered = filtered.filter(item => item.namespace && query.namespaces!.includes(item.namespace));\n }\n\n // Apply packageId filter\n if (query.packageId) {\n filtered = filtered.filter(item => item.packageId === query.packageId);\n }\n\n // Apply tags filter\n if (query.tags && query.tags.length > 0) {\n filtered = filtered.filter(item => {\n const meta = item as any;\n return meta?.tags && query.tags!.some((t: string) => meta.tags.includes(t));\n });\n }\n\n // Sort\n filtered.sort((a, b) => {\n const aVal = (a as any)[sortBy] ?? '';\n const bVal = (b as any)[sortBy] ?? '';\n const cmp = String(aVal).localeCompare(String(bVal));\n return sortOrder === 'desc' ? -cmp : cmp;\n });\n\n // Paginate\n const total = filtered.length;\n const start = (page - 1) * pageSize;\n const paged = filtered.slice(start, start + pageSize);\n\n return {\n items: paged,\n total,\n page,\n pageSize,\n };\n }\n\n // ==========================================\n // Bulk Operations\n // ==========================================\n\n /**\n * Register multiple metadata items in a single batch\n */\n async bulkRegister(\n items: Array<{ type: string; name: string; data: unknown }>,\n options?: { continueOnError?: boolean; validate?: boolean }\n ): Promise<MetadataBulkResult> {\n const { continueOnError = false } = options ?? {};\n let succeeded = 0;\n let failed = 0;\n const errors: Array<{ type: string; name: string; error: string }> = [];\n\n for (const item of items) {\n try {\n await this.register(item.type, item.name, item.data);\n succeeded++;\n } catch (e) {\n failed++;\n errors.push({\n type: item.type,\n name: item.name,\n error: e instanceof Error ? e.message : String(e),\n });\n if (!continueOnError) break;\n }\n }\n\n return {\n total: items.length,\n succeeded,\n failed,\n errors: errors.length > 0 ? errors : undefined,\n };\n }\n\n /**\n * Unregister multiple metadata items in a single batch\n */\n async bulkUnregister(items: Array<{ type: string; name: string }>): Promise<MetadataBulkResult> {\n let succeeded = 0;\n let failed = 0;\n const errors: Array<{ type: string; name: string; error: string }> = [];\n\n for (const item of items) {\n try {\n await this.unregister(item.type, item.name);\n succeeded++;\n } catch (e) {\n failed++;\n errors.push({\n type: item.type,\n name: item.name,\n error: e instanceof Error ? e.message : String(e),\n });\n }\n }\n\n return {\n total: items.length,\n succeeded,\n failed,\n errors: errors.length > 0 ? errors : undefined,\n };\n }\n\n // ==========================================\n // Overlay / Customization Management\n // ==========================================\n\n private overlayKey(type: string, name: string, scope: string = 'platform'): string {\n return `${encodeURIComponent(type)}:${encodeURIComponent(name)}:${scope}`;\n }\n\n /**\n * Get the active overlay for a metadata item\n */\n async getOverlay(type: string, name: string, scope?: 'platform' | 'user'): Promise<MetadataOverlay | undefined> {\n return this.overlays.get(this.overlayKey(type, name, scope ?? 'platform'));\n }\n\n /**\n * Save/update an overlay for a metadata item\n */\n async saveOverlay(overlay: MetadataOverlay): Promise<void> {\n const key = this.overlayKey(overlay.baseType, overlay.baseName, overlay.scope);\n this.overlays.set(key, overlay);\n }\n\n /**\n * Remove an overlay, reverting to the base definition\n */\n async removeOverlay(type: string, name: string, scope?: 'platform' | 'user'): Promise<void> {\n this.overlays.delete(this.overlayKey(type, name, scope ?? 'platform'));\n }\n\n /**\n * Get the effective (merged) metadata after applying all overlays.\n * Resolution order: system ← merge(platform) ← merge(user)\n */\n async getEffective(type: string, name: string, context?: {\n userId?: string;\n tenantId?: string;\n roles?: string[];\n permissions?: string[];\n }): Promise<unknown | undefined> {\n const base = await this.get(type, name);\n if (!base) return undefined;\n\n let effective = { ...(base as Record<string, unknown>) };\n\n // Apply platform overlay\n const platformOverlay = await this.getOverlay(type, name, 'platform');\n if (platformOverlay?.active && platformOverlay.patch) {\n effective = { ...effective, ...platformOverlay.patch };\n }\n\n // Apply user overlay (scoped to specific user if context provided)\n if (context?.userId) {\n // Try user-specific key first, then fall back to generic user overlay.\n // The owner check below ensures we never apply another user's overlay.\n const userOverlayKey = this.overlayKey(type, name, 'user') + `:${context.userId}`;\n const userOverlay = this.overlays.get(userOverlayKey) \n ?? await this.getOverlay(type, name, 'user');\n if (userOverlay?.active && userOverlay.patch) {\n // Apply if: overlay has no owner (generic user-level), or owner matches current user\n if (!userOverlay.owner || userOverlay.owner === context.userId) {\n effective = { ...effective, ...userOverlay.patch };\n }\n }\n } else {\n // No user context — only apply user overlays without an owner restriction\n // (owner-scoped overlays require a userId to resolve)\n const userOverlay = await this.getOverlay(type, name, 'user');\n if (userOverlay?.active && userOverlay.patch && !userOverlay.owner) {\n effective = { ...effective, ...userOverlay.patch };\n }\n }\n\n return effective;\n }\n\n // ==========================================\n // Watch / Subscribe (IMetadataService)\n // ==========================================\n\n /**\n * Watch for metadata changes (IMetadataService contract).\n * Returns a handle for unsubscribing.\n */\n watchService(type: string, callback: MetadataWatchCallback): MetadataWatchHandle {\n const wrappedCallback: WatchCallback = (event) => {\n const mappedType = event.type === 'added' ? 'registered'\n : event.type === 'deleted' ? 'unregistered'\n : 'updated';\n callback({\n type: mappedType,\n metadataType: event.metadataType ?? type,\n name: event.name ?? '',\n data: event.data,\n });\n };\n this.addWatchCallback(type, wrappedCallback);\n return {\n unsubscribe: () => this.removeWatchCallback(type, wrappedCallback),\n };\n }\n\n // ==========================================\n // Import / Export\n // ==========================================\n\n /**\n * Export metadata as a portable bundle\n */\n async exportMetadata(options?: MetadataExportOptions): Promise<unknown> {\n const bundle: Record<string, unknown[]> = {};\n const targetTypes = options?.types ?? Array.from(this.registry.keys());\n\n for (const type of targetTypes) {\n const items = await this.list(type);\n if (items.length > 0) {\n bundle[type] = items;\n }\n }\n\n return bundle;\n }\n\n /**\n * Import metadata from a portable bundle\n */\n async importMetadata(data: unknown, options?: MetadataImportOptions): Promise<MetadataImportResult> {\n const {\n conflictResolution = 'skip',\n validate: _validate = true,\n dryRun = false,\n } = options ?? {};\n\n const bundle = data as Record<string, unknown[]>;\n let total = 0;\n let imported = 0;\n let skipped = 0;\n let failed = 0;\n const errors: Array<{ type: string; name: string; error: string }> = [];\n\n for (const [type, items] of Object.entries(bundle)) {\n if (!Array.isArray(items)) continue;\n\n for (const item of items) {\n total++;\n const meta = item as any;\n const name = meta?.name;\n\n if (!name) {\n failed++;\n errors.push({ type, name: '(unknown)', error: 'Item missing name field' });\n continue;\n }\n\n try {\n const itemExists = await this.exists(type, name);\n\n if (itemExists && conflictResolution === 'skip') {\n skipped++;\n continue;\n }\n\n if (!dryRun) {\n if (itemExists && conflictResolution === 'merge') {\n const existing = await this.get(type, name);\n const merged = { ...(existing as any), ...(item as any) };\n await this.register(type, name, merged);\n } else {\n await this.register(type, name, item);\n }\n }\n imported++;\n } catch (e) {\n failed++;\n errors.push({\n type,\n name,\n error: e instanceof Error ? e.message : String(e),\n });\n }\n }\n }\n\n return {\n total,\n imported,\n skipped,\n failed,\n errors: errors.length > 0 ? errors : undefined,\n };\n }\n\n // ==========================================\n // Validation\n // ==========================================\n\n /**\n * Validate a metadata item against its type schema.\n * Returns validation result with errors and warnings.\n */\n async validate(_type: string, data: unknown): Promise<MetadataValidationResult> {\n // Basic structural validation\n if (data === null || data === undefined) {\n return {\n valid: false,\n errors: [{ path: '', message: 'Metadata data cannot be null or undefined' }],\n };\n }\n\n if (typeof data !== 'object') {\n return {\n valid: false,\n errors: [{ path: '', message: 'Metadata data must be an object' }],\n };\n }\n\n const meta = data as any;\n const warnings: Array<{ path: string; message: string }> = [];\n\n if (!meta.name) {\n return {\n valid: false,\n errors: [{ path: 'name', message: 'Metadata item must have a name field' }],\n };\n }\n\n if (!meta.label) {\n warnings.push({ path: 'label', message: 'Missing label field (recommended)' });\n }\n\n return { valid: true, warnings: warnings.length > 0 ? warnings : undefined };\n }\n\n // ==========================================\n // Type Registry\n // ==========================================\n\n /**\n * Get all registered metadata types\n */\n async getRegisteredTypes(): Promise<string[]> {\n const types = new Set<string>();\n\n // From type registry\n for (const entry of this.typeRegistry) {\n types.add(entry.type);\n }\n\n // From in-memory registry (custom types)\n for (const type of this.registry.keys()) {\n types.add(type);\n }\n\n return Array.from(types);\n }\n\n /**\n * Get detailed information about a metadata type\n */\n async getTypeInfo(type: string): Promise<MetadataTypeInfo | undefined> {\n const entry = this.typeRegistry.find(e => e.type === type);\n if (!entry) return undefined;\n\n return {\n type: entry.type,\n label: entry.label,\n description: entry.description,\n filePatterns: entry.filePatterns,\n supportsOverlay: entry.supportsOverlay,\n domain: entry.domain,\n };\n }\n\n // ==========================================\n // Dependency Tracking\n // ==========================================\n\n /**\n * Get metadata items that this item depends on\n */\n async getDependencies(type: string, name: string): Promise<MetadataDependency[]> {\n return this.dependencies.get(`${encodeURIComponent(type)}:${encodeURIComponent(name)}`) ?? [];\n }\n\n /**\n * Get metadata items that depend on this item\n */\n async getDependents(type: string, name: string): Promise<MetadataDependency[]> {\n const dependents: MetadataDependency[] = [];\n for (const deps of this.dependencies.values()) {\n for (const dep of deps) {\n if (dep.targetType === type && dep.targetName === name) {\n dependents.push(dep);\n }\n }\n }\n return dependents;\n }\n\n /**\n * Register a dependency between two metadata items.\n * Used internally to track cross-references.\n * Duplicate dependencies (same source, target, and kind) are ignored.\n */\n addDependency(dep: MetadataDependency): void {\n const key = `${encodeURIComponent(dep.sourceType)}:${encodeURIComponent(dep.sourceName)}`;\n if (!this.dependencies.has(key)) {\n this.dependencies.set(key, []);\n }\n const existing = this.dependencies.get(key)!;\n const isDuplicate = existing.some(\n d => d.targetType === dep.targetType && d.targetName === dep.targetName && d.kind === dep.kind\n );\n if (!isDuplicate) {\n existing.push(dep);\n }\n }\n\n // ==========================================\n // Legacy Loader API (backward compatible)\n // ==========================================\n\n /**\n * Load a single metadata item from loaders.\n * Iterates through registered loaders until found.\n */\n async load<T = any>(\n type: string,\n name: string,\n options?: MetadataLoadOptions\n ): Promise<T | null> {\n for (const loader of this.loaders.values()) {\n try {\n const result = await loader.load(type, name, options);\n if (result.data) {\n return result.data as T;\n }\n } catch (e) {\n this.logger.warn(`Loader ${loader.contract.name} failed to load ${type}:${name}`, { error: e });\n }\n }\n return null;\n }\n\n /**\n * Load multiple metadata items from loaders.\n * Aggregates results from all loaders.\n */\n async loadMany<T = any>(\n type: string,\n options?: MetadataLoadOptions\n ): Promise<T[]> {\n const results: T[] = [];\n\n for (const loader of this.loaders.values()) {\n try {\n const items = await loader.loadMany<T>(type, options);\n for (const item of items) {\n const itemAny = item as any;\n if (itemAny && typeof itemAny.name === 'string') {\n const exists = results.some((r: any) => r && r.name === itemAny.name);\n if (exists) continue;\n }\n results.push(item);\n }\n } catch (e) {\n this.logger.warn(`Loader ${loader.contract.name} failed to loadMany ${type}`, { error: e });\n }\n }\n return results;\n }\n\n /**\n * Save metadata item to a loader\n */\n async save<T = any>(\n type: string,\n name: string,\n data: T,\n options?: MetadataSaveOptions\n ): Promise<MetadataSaveResult> {\n const targetLoader = (options as any)?.loader;\n\n let loader: MetadataLoader | undefined;\n \n if (targetLoader) {\n loader = this.loaders.get(targetLoader);\n if (!loader) {\n throw new Error(`Loader not found: ${targetLoader}`);\n }\n } else {\n for (const l of this.loaders.values()) {\n if (!l.save) continue;\n try {\n if (await l.exists(type, name)) {\n loader = l;\n this.logger.info(`Updating existing metadata in loader: ${l.contract.name}`);\n break;\n }\n } catch (e) {\n // Ignore existence check errors\n }\n }\n\n if (!loader) {\n const fsLoader = this.loaders.get('filesystem');\n if (fsLoader && fsLoader.save) {\n loader = fsLoader;\n }\n }\n\n if (!loader) {\n for (const l of this.loaders.values()) {\n if (l.save) {\n loader = l;\n break;\n }\n }\n }\n }\n\n if (!loader) {\n throw new Error(`No loader available for saving type: ${type}`);\n }\n\n if (!loader.save) {\n throw new Error(`Loader '${loader.contract?.name}' does not support saving`);\n }\n\n return loader.save(type, name, data, options);\n }\n\n /**\n * Register a watch callback for metadata changes\n */\n protected addWatchCallback(type: string, callback: WatchCallback): void {\n if (!this.watchCallbacks.has(type)) {\n this.watchCallbacks.set(type, new Set());\n }\n this.watchCallbacks.get(type)!.add(callback);\n }\n\n /**\n * Remove a watch callback for metadata changes\n */\n protected removeWatchCallback(type: string, callback: WatchCallback): void {\n const callbacks = this.watchCallbacks.get(type);\n if (callbacks) {\n callbacks.delete(callback);\n if (callbacks.size === 0) {\n this.watchCallbacks.delete(type);\n }\n }\n }\n\n /**\n * Stop all watching\n */\n async stopWatching(): Promise<void> {\n // Override in subclass\n }\n\n protected notifyWatchers(type: string, event: MetadataWatchEvent) {\n const callbacks = this.watchCallbacks.get(type);\n if (!callbacks) return;\n \n for (const callback of callbacks) {\n try {\n void callback(event);\n } catch (error) {\n this.logger.error('Watch callback error', undefined, {\n type,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n }\n}\n\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * JSON Metadata Serializer\n * \n * Handles JSON format serialization and deserialization\n */\n\nimport type { z } from 'zod';\nimport type { MetadataFormat } from '@objectstack/spec/system';\nimport type { MetadataSerializer, SerializeOptions } from './serializer-interface.js';\n\nexport class JSONSerializer implements MetadataSerializer {\n serialize<T>(item: T, options?: SerializeOptions): string {\n const { prettify = true, indent = 2, sortKeys = false } = options || {};\n\n if (sortKeys) {\n // Sort keys recursively\n const sorted = this.sortObjectKeys(item);\n return prettify\n ? JSON.stringify(sorted, null, indent)\n : JSON.stringify(sorted);\n }\n\n return prettify\n ? JSON.stringify(item, null, indent)\n : JSON.stringify(item);\n }\n\n deserialize<T>(content: string, schema?: z.ZodSchema): T {\n const parsed = JSON.parse(content);\n\n if (schema) {\n return schema.parse(parsed) as T;\n }\n\n return parsed as T;\n }\n\n getExtension(): string {\n return '.json';\n }\n\n canHandle(format: MetadataFormat): boolean {\n return format === 'json';\n }\n\n getFormat(): MetadataFormat {\n return 'json';\n }\n\n /**\n * Recursively sort object keys\n */\n private sortObjectKeys(obj: any): any {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map(item => this.sortObjectKeys(item));\n }\n\n const sorted: Record<string, any> = {};\n const keys = Object.keys(obj).sort();\n\n for (const key of keys) {\n sorted[key] = this.sortObjectKeys(obj[key]);\n }\n\n return sorted;\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * YAML Metadata Serializer\n * \n * Handles YAML format serialization and deserialization\n */\n\nimport * as yaml from 'js-yaml';\nimport type { z } from 'zod';\nimport type { MetadataFormat } from '@objectstack/spec/system';\nimport type { MetadataSerializer, SerializeOptions } from './serializer-interface.js';\n\nexport class YAMLSerializer implements MetadataSerializer {\n serialize<T>(item: T, options?: SerializeOptions): string {\n const { indent = 2, sortKeys = false } = options || {};\n\n return yaml.dump(item, {\n indent,\n sortKeys,\n lineWidth: -1, // Disable line wrapping\n noRefs: true, // Disable YAML references\n });\n }\n\n deserialize<T>(content: string, schema?: z.ZodSchema): T {\n // Use JSON_SCHEMA to prevent arbitrary code execution\n // This restricts YAML to JSON-compatible types only\n const parsed = yaml.load(content, { schema: yaml.JSON_SCHEMA });\n\n if (schema) {\n return schema.parse(parsed) as T;\n }\n\n return parsed as T;\n }\n\n getExtension(): string {\n return '.yaml';\n }\n\n canHandle(format: MetadataFormat): boolean {\n return format === 'yaml';\n }\n\n getFormat(): MetadataFormat {\n return 'yaml';\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * TypeScript/JavaScript Metadata Serializer\n * \n * Handles TypeScript/JavaScript module format serialization and deserialization\n */\n\nimport type { z } from 'zod';\nimport type { MetadataFormat } from '@objectstack/spec/system';\nimport type { MetadataSerializer, SerializeOptions } from './serializer-interface.js';\n\nexport class TypeScriptSerializer implements MetadataSerializer {\n constructor(private format: 'typescript' | 'javascript' = 'typescript') {}\n\n serialize<T>(item: T, options?: SerializeOptions): string {\n const { prettify = true, indent = 2 } = options || {};\n\n const jsonStr = JSON.stringify(item, null, prettify ? indent : 0);\n \n if (this.format === 'typescript') {\n return `import type { ServiceObject } from '@objectstack/spec/data';\\n\\n` +\n `export const metadata: ServiceObject = ${jsonStr};\\n\\n` +\n `export default metadata;\\n`;\n } else {\n return `export const metadata = ${jsonStr};\\n\\n` +\n `export default metadata;\\n`;\n }\n }\n\n deserialize<T>(content: string, schema?: z.ZodSchema): T {\n // For TypeScript/JavaScript files, we need to extract the exported object\n // Note: This is a simplified parser that works with JSON-like object literals\n // For complex TypeScript with nested objects, consider using a proper TypeScript parser\n \n // Try to find the object literal in various export patterns\n // Pattern 1: export const metadata = {...};\n let objectStart = content.indexOf('export const');\n if (objectStart === -1) {\n // Pattern 2: export default {...};\n objectStart = content.indexOf('export default');\n }\n \n if (objectStart === -1) {\n throw new Error(\n 'Could not parse TypeScript/JavaScript module. ' +\n 'Expected export pattern: \"export const metadata = {...};\" or \"export default {...};\"'\n );\n }\n\n // Find the first opening brace after the export statement\n const braceStart = content.indexOf('{', objectStart);\n if (braceStart === -1) {\n throw new Error('Could not find object literal in export statement');\n }\n\n // Find the matching closing brace by counting braces\n // Handle string literals to avoid counting braces inside strings\n let braceCount = 0;\n let braceEnd = -1;\n let inString = false;\n let stringChar = '';\n \n for (let i = braceStart; i < content.length; i++) {\n const char = content[i];\n const prevChar = i > 0 ? content[i - 1] : '';\n \n // Track string literals (simple handling of \" and ')\n if ((char === '\"' || char === \"'\") && prevChar !== '\\\\') {\n if (!inString) {\n inString = true;\n stringChar = char;\n } else if (char === stringChar) {\n inString = false;\n stringChar = '';\n }\n }\n \n // Count braces only when not inside strings\n if (!inString) {\n if (char === '{') braceCount++;\n if (char === '}') {\n braceCount--;\n if (braceCount === 0) {\n braceEnd = i;\n break;\n }\n }\n }\n }\n\n if (braceEnd === -1) {\n throw new Error('Could not find matching closing brace for object literal');\n }\n\n // Extract the object literal\n const objectLiteral = content.substring(braceStart, braceEnd + 1);\n\n try {\n // Parse as JSON\n const parsed = JSON.parse(objectLiteral);\n\n if (schema) {\n return schema.parse(parsed) as T;\n }\n\n return parsed as T;\n } catch (error) {\n throw new Error(\n `Failed to parse object literal as JSON: ${error instanceof Error ? error.message : String(error)}. ` +\n 'Make sure the TypeScript/JavaScript object uses JSON-compatible syntax (no functions, comments, or trailing commas).'\n );\n }\n }\n\n getExtension(): string {\n return this.format === 'typescript' ? '.ts' : '.js';\n }\n\n canHandle(format: MetadataFormat): boolean {\n return format === 'typescript' || format === 'javascript';\n }\n\n getFormat(): MetadataFormat {\n return this.format;\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { ObjectSchema, Field } from '@objectstack/spec/data';\n\n/**\n * sys_metadata — System Metadata Object\n *\n * Canonical ObjectStack object definition for the metadata persistence table.\n * Stores all platform-scope and user-scope metadata records (Objects, Views,\n * Flows, etc.) using the MetadataRecordSchema envelope.\n *\n * This is a system object (isSystem: true) — protected from deletion and\n * automatically provisioned by the DatabaseLoader on first use.\n *\n * @see MetadataRecordSchema in metadata-persistence.zod.ts\n */\nexport const SysMetadataObject = ObjectSchema.create({\n namespace: 'sys',\n name: 'metadata',\n label: 'System Metadata',\n pluralLabel: 'System Metadata',\n icon: 'settings',\n isSystem: true,\n description: 'Stores platform and user-scope metadata records (objects, views, flows, etc.)',\n\n fields: {\n /** Primary Key (UUID) */\n id: Field.text({\n label: 'ID',\n required: true,\n readonly: true,\n }),\n\n /** Machine name — unique identifier used in code references */\n name: Field.text({\n label: 'Name',\n required: true,\n searchable: true,\n maxLength: 255,\n }),\n\n /** Metadata type (e.g. \"object\", \"view\", \"flow\") */\n type: Field.text({\n label: 'Metadata Type',\n required: true,\n searchable: true,\n maxLength: 100,\n }),\n\n /** Namespace / module grouping (e.g. \"crm\", \"core\") */\n namespace: Field.text({\n label: 'Namespace',\n required: false,\n defaultValue: 'default',\n maxLength: 100,\n }),\n\n /** Package that owns/delivered this metadata */\n package_id: Field.text({\n label: 'Package ID',\n required: false,\n maxLength: 255,\n }),\n\n /** Who manages this record: package, platform, or user */\n managed_by: Field.select(['package', 'platform', 'user'], {\n label: 'Managed By',\n required: false,\n }),\n\n /** Scope: system (code), platform (admin DB), user (personal DB) */\n scope: Field.select(['system', 'platform', 'user'], {\n label: 'Scope',\n required: true,\n defaultValue: 'platform',\n }),\n\n /** JSON payload — the actual metadata configuration */\n metadata: Field.textarea({\n label: 'Metadata',\n required: true,\n description: 'JSON-serialized metadata payload',\n }),\n\n /** Parent metadata name for extension/override */\n extends: Field.text({\n label: 'Extends',\n required: false,\n maxLength: 255,\n }),\n\n /** Merge strategy when extending parent metadata */\n strategy: Field.select(['merge', 'replace'], {\n label: 'Strategy',\n required: false,\n defaultValue: 'merge',\n }),\n\n /** Owner user ID (for user-scope items) */\n owner: Field.text({\n label: 'Owner',\n required: false,\n maxLength: 255,\n }),\n\n /** Lifecycle state */\n state: Field.select(['draft', 'active', 'archived', 'deprecated'], {\n label: 'State',\n required: false,\n defaultValue: 'active',\n }),\n\n /** Tenant ID for multi-tenant isolation */\n tenant_id: Field.text({\n label: 'Tenant ID',\n required: false,\n maxLength: 255,\n }),\n\n /** Version number for optimistic concurrency */\n version: Field.number({\n label: 'Version',\n required: false,\n defaultValue: 1,\n }),\n\n /** Content checksum for change detection */\n checksum: Field.text({\n label: 'Checksum',\n required: false,\n maxLength: 64,\n }),\n\n /** Origin of this metadata record */\n source: Field.select(['filesystem', 'database', 'api', 'migration'], {\n label: 'Source',\n required: false,\n }),\n\n /** Classification tags (JSON array) */\n tags: Field.textarea({\n label: 'Tags',\n required: false,\n description: 'JSON-serialized array of classification tags',\n }),\n\n /** Audit fields */\n created_by: Field.text({\n label: 'Created By',\n required: false,\n readonly: true,\n maxLength: 255,\n }),\n\n created_at: Field.datetime({\n label: 'Created At',\n required: false,\n readonly: true,\n }),\n\n updated_by: Field.text({\n label: 'Updated By',\n required: false,\n maxLength: 255,\n }),\n\n updated_at: Field.datetime({\n label: 'Updated At',\n required: false,\n }),\n },\n\n indexes: [\n { fields: ['type', 'name'], unique: true },\n { fields: ['type', 'scope'] },\n { fields: ['tenant_id'] },\n { fields: ['state'] },\n { fields: ['namespace'] },\n ],\n\n enable: {\n trackHistory: true,\n searchable: false,\n apiEnabled: true,\n apiMethods: ['get', 'list', 'create', 'update', 'delete'],\n trash: false,\n },\n});\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Database Metadata Loader\n *\n * Loads and persists metadata via an IDataDriver instance, enabling\n * database-backed storage for platform and user scoped metadata.\n * Uses the `sys_metadata` table (configurable) following the\n * MetadataRecordSchema envelope defined in @objectstack/spec.\n */\n\nimport type {\n MetadataLoadOptions,\n MetadataLoadResult,\n MetadataStats,\n MetadataLoaderContract,\n MetadataSaveOptions,\n MetadataSaveResult,\n MetadataRecord,\n} from '@objectstack/spec/system';\nimport { SysMetadataObject } from '../objects/sys-metadata.object.js';\nimport type { IDataDriver } from '@objectstack/spec/contracts';\nimport type { MetadataLoader } from './loader-interface.js';\n\n/**\n * Configuration for the DatabaseLoader.\n */\nexport interface DatabaseLoaderOptions {\n /** The IDataDriver instance to use for database operations */\n driver: IDataDriver;\n\n /** The table name to store metadata records (default: 'sys_metadata') */\n tableName?: string;\n\n /** Tenant ID for multi-tenant isolation */\n tenantId?: string;\n}\n\n/**\n * DatabaseLoader — Datasource-backed metadata persistence.\n *\n * Implements the MetadataLoader interface to provide database read/write\n * for metadata records. Uses the MetadataRecordSchema envelope to persist\n * metadata with scope, versioning, and audit fields.\n */\nexport class DatabaseLoader implements MetadataLoader {\n readonly contract: MetadataLoaderContract = {\n name: 'database',\n protocol: 'datasource:',\n capabilities: {\n read: true,\n write: true,\n watch: false,\n list: true,\n },\n };\n\n private driver: IDataDriver;\n private tableName: string;\n private tenantId?: string;\n private schemaReady = false;\n\n constructor(options: DatabaseLoaderOptions) {\n this.driver = options.driver;\n this.tableName = options.tableName ?? 'sys_metadata';\n this.tenantId = options.tenantId;\n }\n\n /**\n * Ensure the metadata table exists.\n * Uses IDataDriver.syncSchema with the SysMetadataObject definition\n * to idempotently create/update the table.\n */\n private async ensureSchema(): Promise<void> {\n if (this.schemaReady) return;\n\n try {\n await this.driver.syncSchema(this.tableName, {\n ...SysMetadataObject,\n name: this.tableName,\n });\n this.schemaReady = true;\n } catch {\n // If syncSchema fails (e.g. table already exists), mark ready and continue\n this.schemaReady = true;\n }\n }\n\n /**\n * Build base filter conditions for queries.\n * Always includes tenantId when configured.\n */\n private baseFilter(type: string, name?: string): Record<string, unknown> {\n const filter: Record<string, unknown> = { type };\n if (name !== undefined) {\n filter.name = name;\n }\n if (this.tenantId) {\n filter.tenant_id = this.tenantId;\n }\n return filter;\n }\n\n /**\n * Convert a database row to a metadata payload.\n * Parses the JSON `metadata` column back into an object.\n */\n private rowToData(row: Record<string, unknown>): Record<string, unknown> | null {\n if (!row || !row.metadata) return null;\n\n const payload = typeof row.metadata === 'string'\n ? JSON.parse(row.metadata as string)\n : row.metadata;\n\n return payload as Record<string, unknown>;\n }\n\n /**\n * Convert a database row to a MetadataRecord-like object.\n */\n private rowToRecord(row: Record<string, unknown>): MetadataRecord {\n return {\n id: row.id as string,\n name: row.name as string,\n type: row.type as string,\n namespace: (row.namespace as string) ?? 'default',\n packageId: row.package_id as string | undefined,\n managedBy: row.managed_by as MetadataRecord['managedBy'],\n scope: (row.scope as MetadataRecord['scope']) ?? 'platform',\n metadata: this.rowToData(row) ?? {},\n extends: row.extends as string | undefined,\n strategy: (row.strategy as MetadataRecord['strategy']) ?? 'merge',\n owner: row.owner as string | undefined,\n state: (row.state as MetadataRecord['state']) ?? 'active',\n tenantId: row.tenant_id as string | undefined,\n version: (row.version as number) ?? 1,\n checksum: row.checksum as string | undefined,\n source: row.source as MetadataRecord['source'],\n tags: row.tags ? (typeof row.tags === 'string' ? JSON.parse(row.tags as string) : row.tags as string[]) : undefined,\n createdBy: row.created_by as string | undefined,\n createdAt: row.created_at as string | undefined,\n updatedBy: row.updated_by as string | undefined,\n updatedAt: row.updated_at as string | undefined,\n };\n }\n\n // ==========================================\n // MetadataLoader Interface Implementation\n // ==========================================\n\n async load(\n type: string,\n name: string,\n _options?: MetadataLoadOptions\n ): Promise<MetadataLoadResult> {\n const startTime = Date.now();\n\n await this.ensureSchema();\n\n try {\n const row = await this.driver.findOne(this.tableName, {\n object: this.tableName,\n where: this.baseFilter(type, name),\n });\n\n if (!row) {\n return {\n data: null,\n loadTime: Date.now() - startTime,\n };\n }\n\n const data = this.rowToData(row);\n const record = this.rowToRecord(row);\n\n return {\n data,\n source: 'database',\n format: 'json',\n etag: record.checksum,\n loadTime: Date.now() - startTime,\n };\n } catch {\n return {\n data: null,\n loadTime: Date.now() - startTime,\n };\n }\n }\n\n async loadMany<T = any>(\n type: string,\n _options?: MetadataLoadOptions\n ): Promise<T[]> {\n await this.ensureSchema();\n\n try {\n const rows = await this.driver.find(this.tableName, {\n object: this.tableName,\n where: this.baseFilter(type),\n });\n\n return rows\n .map(row => this.rowToData(row))\n .filter((data): data is Record<string, unknown> => data !== null) as T[];\n } catch {\n return [];\n }\n }\n\n async exists(type: string, name: string): Promise<boolean> {\n await this.ensureSchema();\n\n try {\n const count = await this.driver.count(this.tableName, {\n object: this.tableName,\n where: this.baseFilter(type, name),\n });\n\n return count > 0;\n } catch {\n return false;\n }\n }\n\n async stat(type: string, name: string): Promise<MetadataStats | null> {\n await this.ensureSchema();\n\n try {\n const row = await this.driver.findOne(this.tableName, {\n object: this.tableName,\n where: this.baseFilter(type, name),\n });\n\n if (!row) return null;\n\n const record = this.rowToRecord(row);\n const metadataStr = typeof row.metadata === 'string'\n ? row.metadata as string\n : JSON.stringify(row.metadata);\n\n return {\n size: metadataStr.length,\n mtime: record.updatedAt ?? record.createdAt ?? new Date().toISOString(),\n format: 'json',\n etag: record.checksum,\n };\n } catch {\n return null;\n }\n }\n\n async list(type: string): Promise<string[]> {\n await this.ensureSchema();\n\n try {\n const rows = await this.driver.find(this.tableName, {\n object: this.tableName,\n where: this.baseFilter(type),\n fields: ['name'],\n });\n\n return rows\n .map(row => row.name as string)\n .filter(name => typeof name === 'string');\n } catch {\n return [];\n }\n }\n\n async save(\n type: string,\n name: string,\n data: any,\n _options?: MetadataSaveOptions\n ): Promise<MetadataSaveResult> {\n const startTime = Date.now();\n\n await this.ensureSchema();\n\n const now = new Date().toISOString();\n const metadataJson = JSON.stringify(data);\n\n try {\n const existing = await this.driver.findOne(this.tableName, {\n object: this.tableName,\n where: this.baseFilter(type, name),\n });\n\n if (existing) {\n // Update existing record\n const version = ((existing.version as number) ?? 0) + 1;\n await this.driver.update(this.tableName, existing.id as string, {\n metadata: metadataJson,\n version,\n updated_at: now,\n state: 'active',\n });\n\n return {\n success: true,\n path: `datasource://${this.tableName}/${type}/${name}`,\n size: metadataJson.length,\n saveTime: Date.now() - startTime,\n };\n } else {\n // Create new record\n const id = generateId();\n await this.driver.create(this.tableName, {\n id,\n name,\n type,\n namespace: 'default',\n scope: (data as any)?.scope ?? 'platform',\n metadata: metadataJson,\n strategy: 'merge',\n state: 'active',\n version: 1,\n source: 'database',\n ...(this.tenantId ? { tenant_id: this.tenantId } : {}),\n created_at: now,\n updated_at: now,\n });\n\n return {\n success: true,\n path: `datasource://${this.tableName}/${type}/${name}`,\n size: metadataJson.length,\n saveTime: Date.now() - startTime,\n };\n }\n } catch (error) {\n throw new Error(\n `DatabaseLoader save failed for ${type}/${name}: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n }\n}\n\n/**\n * Generate a simple unique ID for metadata records.\n * Uses crypto.randomUUID when available, falls back to timestamp-based ID.\n */\nfunction generateId(): string {\n if (typeof globalThis.crypto !== 'undefined' && typeof globalThis.crypto.randomUUID === 'function') {\n return globalThis.crypto.randomUUID();\n }\n // Fallback for environments without crypto.randomUUID\n return `meta_${Date.now()}_${Math.random().toString(36).substring(2, 10)}`;\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Node Metadata Manager\n * \n * Extends MetadataManager with Filesystem capabilities (Watching, default loader)\n */\n\nimport * as path from 'node:path';\nimport { watch as chokidarWatch, type FSWatcher } from 'chokidar';\nimport type {\n MetadataWatchEvent,\n} from '@objectstack/spec/system';\nimport { FilesystemLoader } from './loaders/filesystem-loader.js';\nimport { MetadataManager, type MetadataManagerOptions } from './metadata-manager.js';\n\n/**\n * Node metadata manager class\n */\nexport class NodeMetadataManager extends MetadataManager {\n private watcher?: FSWatcher;\n\n constructor(config: MetadataManagerOptions) {\n super(config);\n\n // Initialize Default Filesystem Loader if no loaders provided\n // This logic replaces the removed logic from base class\n if (!config.loaders || config.loaders.length === 0) {\n const rootDir = config.rootDir || process.cwd();\n this.registerLoader(new FilesystemLoader(rootDir, this.serializers, this.logger));\n }\n\n // Start watching if enabled\n if (config.watch) {\n this.startWatching();\n }\n }\n\n /**\n * Stop all watching\n */\n async stopWatching(): Promise<void> {\n if (this.watcher) {\n await this.watcher.close();\n this.watcher = undefined;\n }\n // Call base cleanup if any\n }\n\n /**\n * Start watching for file changes\n */\n private startWatching(): void {\n const rootDir = this.config.rootDir || process.cwd();\n const { ignored = ['**/node_modules/**', '**/*.test.*'], persistent = true } =\n this.config.watchOptions || {};\n\n this.watcher = chokidarWatch(rootDir, {\n ignored,\n persistent,\n ignoreInitial: true,\n });\n\n this.watcher.on('add', async (filePath) => {\n await this.handleFileEvent('added', filePath);\n });\n\n this.watcher.on('change', async (filePath) => {\n await this.handleFileEvent('changed', filePath);\n });\n\n this.watcher.on('unlink', async (filePath) => {\n await this.handleFileEvent('deleted', filePath);\n });\n\n this.logger.info('File watcher started', { rootDir });\n }\n\n /**\n * Handle file change events\n */\n private async handleFileEvent(\n eventType: 'added' | 'changed' | 'deleted',\n filePath: string\n ): Promise<void> {\n const rootDir = this.config.rootDir || process.cwd();\n const relativePath = path.relative(rootDir, filePath);\n const parts = relativePath.split(path.sep);\n\n if (parts.length < 2) {\n return; // Not a metadata file\n }\n\n const type = parts[0];\n const fileName = parts[parts.length - 1];\n const name = path.basename(fileName, path.extname(fileName));\n\n // We can't access private watchCallbacks from parent.\n // We need a protected method to trigger watch event or access it.\n // OPTION: Add a method `triggerWatchEvent` to MetadataManager\n \n let data: any = undefined;\n if (eventType !== 'deleted') {\n try {\n data = await this.load(type, name, { useCache: false });\n } catch (error) {\n this.logger.error('Failed to load changed file', undefined, {\n filePath,\n error: error instanceof Error ? error.message : String(error),\n });\n return;\n }\n }\n\n const event: MetadataWatchEvent = {\n type: eventType,\n metadataType: type,\n name,\n path: filePath,\n data,\n timestamp: new Date().toISOString(),\n };\n\n this.notifyWatchers(type, event);\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Filesystem Metadata Loader\n * \n * Loads metadata from the filesystem using glob patterns\n */\n\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { glob } from 'glob';\nimport { createHash } from 'node:crypto';\nimport type {\n MetadataLoadOptions,\n MetadataLoadResult,\n MetadataStats,\n MetadataLoaderContract,\n MetadataFormat,\n MetadataSaveOptions,\n MetadataSaveResult,\n} from '@objectstack/spec/system';\nimport type { Logger } from '@objectstack/core';\nimport type { MetadataLoader } from './loader-interface.js';\nimport type { MetadataSerializer } from '../serializers/serializer-interface.js';\n\nexport class FilesystemLoader implements MetadataLoader {\n readonly contract: MetadataLoaderContract = {\n name: 'filesystem',\n protocol: 'file:',\n capabilities: {\n read: true,\n write: true,\n watch: true,\n list: true,\n },\n supportedFormats: ['json', 'yaml', 'typescript', 'javascript'],\n supportsWatch: true,\n supportsWrite: true,\n supportsCache: true,\n };\n\n private cache = new Map<string, { data: any; etag: string; timestamp: number }>();\n\n constructor(\n private rootDir: string,\n private serializers: Map<MetadataFormat, MetadataSerializer>,\n private logger?: Logger\n ) {}\n\n async load(\n type: string,\n name: string,\n options?: MetadataLoadOptions\n ): Promise<MetadataLoadResult> {\n const startTime = Date.now();\n const { validate: _validate = true, useCache = true, ifNoneMatch } = options || {};\n\n try {\n // Find the file\n const filePath = await this.findFile(type, name);\n\n if (!filePath) {\n return {\n data: null,\n fromCache: false,\n notModified: false,\n loadTime: Date.now() - startTime,\n };\n }\n\n // Get stats\n const stats = await this.stat(type, name);\n\n if (!stats) {\n return {\n data: null,\n fromCache: false,\n notModified: false,\n loadTime: Date.now() - startTime,\n };\n }\n\n // Check cache\n if (useCache && ifNoneMatch && stats.etag === ifNoneMatch) {\n return {\n data: null,\n fromCache: true,\n notModified: true,\n etag: stats.etag,\n stats,\n loadTime: Date.now() - startTime,\n };\n }\n\n // Check memory cache\n const cacheKey = `${type}:${name}`;\n if (useCache && this.cache.has(cacheKey)) {\n const cached = this.cache.get(cacheKey)!;\n if (cached.etag === stats.etag) {\n return {\n data: cached.data,\n fromCache: true,\n notModified: false,\n etag: stats.etag,\n stats,\n loadTime: Date.now() - startTime,\n };\n }\n }\n\n // Load and deserialize\n const content = await fs.readFile(filePath, 'utf-8');\n const serializer = this.getSerializer(stats.format!);\n\n if (!serializer) {\n throw new Error(`No serializer found for format: ${stats.format}`);\n }\n\n const data = serializer.deserialize(content);\n\n // Update cache\n if (useCache) {\n this.cache.set(cacheKey, {\n data,\n etag: stats.etag || '',\n timestamp: Date.now(),\n });\n }\n\n return {\n data,\n fromCache: false,\n notModified: false,\n etag: stats.etag,\n stats,\n loadTime: Date.now() - startTime,\n };\n } catch (error) {\n this.logger?.error('Failed to load metadata', undefined, {\n type,\n name,\n error: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n }\n\n async loadMany<T = any>(\n type: string,\n options?: MetadataLoadOptions\n ): Promise<T[]> {\n const { patterns = ['**/*'], recursive: _recursive = true, limit } = options || {};\n\n const typeDir = path.join(this.rootDir, type);\n const items: T[] = [];\n\n try {\n // Build glob patterns\n const globPatterns = patterns.map(pattern =>\n path.join(typeDir, pattern)\n );\n\n for (const pattern of globPatterns) {\n const files = await glob(pattern, {\n ignore: ['**/node_modules/**', '**/*.test.*', '**/*.spec.*'],\n nodir: true,\n });\n\n for (const file of files) {\n if (limit && items.length >= limit) {\n break;\n }\n\n try {\n const content = await fs.readFile(file, 'utf-8');\n const format = this.detectFormat(file);\n const serializer = this.getSerializer(format);\n\n if (serializer) {\n const data = serializer.deserialize<T>(content);\n items.push(data);\n }\n } catch (error) {\n this.logger?.warn('Failed to load file', {\n file,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n if (limit && items.length >= limit) {\n break;\n }\n }\n\n return items;\n } catch (error) {\n this.logger?.error('Failed to load many', undefined, {\n type,\n patterns,\n error: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n }\n\n async exists(type: string, name: string): Promise<boolean> {\n const filePath = await this.findFile(type, name);\n return filePath !== null;\n }\n\n async stat(type: string, name: string): Promise<MetadataStats | null> {\n const filePath = await this.findFile(type, name);\n\n if (!filePath) {\n return null;\n }\n\n try {\n const stats = await fs.stat(filePath);\n const content = await fs.readFile(filePath, 'utf-8');\n const etag = this.generateETag(content);\n const format = this.detectFormat(filePath);\n\n return {\n size: stats.size,\n modifiedAt: stats.mtime.toISOString(),\n etag,\n format,\n path: filePath,\n };\n } catch (error) {\n this.logger?.error('Failed to stat file', undefined, {\n type,\n name,\n filePath,\n error: error instanceof Error ? error.message : String(error),\n });\n return null;\n }\n }\n\n async list(type: string): Promise<string[]> {\n const typeDir = path.join(this.rootDir, type);\n\n try {\n const files = await glob('**/*', {\n cwd: typeDir,\n ignore: ['**/node_modules/**', '**/*.test.*', '**/*.spec.*'],\n nodir: true,\n });\n\n return files.map(file => {\n const ext = path.extname(file);\n const basename = path.basename(file, ext);\n return basename;\n });\n } catch (error) {\n this.logger?.error('Failed to list', undefined, {\n type,\n error: error instanceof Error ? error.message : String(error),\n });\n return [];\n }\n }\n\n async save(\n type: string,\n name: string,\n data: any,\n options?: MetadataSaveOptions\n ): Promise<MetadataSaveResult> {\n const startTime = Date.now();\n const {\n format = 'typescript',\n prettify = true,\n indent = 2,\n sortKeys = false,\n backup = false,\n overwrite = true,\n atomic = true,\n path: customPath,\n } = options || {};\n\n try {\n // Get serializer\n const serializer = this.getSerializer(format);\n if (!serializer) {\n throw new Error(`No serializer found for format: ${format}`);\n }\n\n // Determine file path\n const typeDir = path.join(this.rootDir, type);\n const fileName = `${name}${serializer.getExtension()}`;\n const filePath = customPath || path.join(typeDir, fileName);\n\n // Check if file exists\n if (!overwrite) {\n try {\n await fs.access(filePath);\n throw new Error(`File already exists: ${filePath}`);\n } catch (error) {\n // File doesn't exist, continue\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n throw error;\n }\n }\n }\n\n // Create directory if it doesn't exist\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n\n // Create backup if requested\n let backupPath: string | undefined;\n if (backup) {\n try {\n await fs.access(filePath);\n backupPath = `${filePath}.bak`;\n await fs.copyFile(filePath, backupPath);\n } catch {\n // File doesn't exist, no backup needed\n }\n }\n\n // Serialize data\n const content = serializer.serialize(data, {\n prettify,\n indent,\n sortKeys,\n });\n\n // Write to disk (atomic or direct)\n if (atomic) {\n const tempPath = `${filePath}.tmp`;\n await fs.writeFile(tempPath, content, 'utf-8');\n await fs.rename(tempPath, filePath);\n } else {\n await fs.writeFile(filePath, content, 'utf-8');\n }\n\n // Update cache logic if needed (e.g., invalidate or update)\n // For now, we rely on the watcher to pick up changes\n\n return {\n success: true,\n path: filePath,\n // format, // Not in schema\n size: Buffer.byteLength(content, 'utf-8'),\n backupPath,\n saveTime: Date.now() - startTime,\n };\n } catch (error) {\n this.logger?.error('Failed to save metadata', undefined, {\n type,\n name,\n error: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n }\n\n /**\n * Find file for a given type and name\n */\n private async findFile(type: string, name: string): Promise<string | null> {\n const typeDir = path.join(this.rootDir, type);\n const extensions = ['.json', '.yaml', '.yml', '.ts', '.js'];\n\n for (const ext of extensions) {\n const filePath = path.join(typeDir, `${name}${ext}`);\n\n try {\n await fs.access(filePath);\n return filePath;\n } catch {\n // File doesn't exist, try next extension\n }\n }\n\n return null;\n }\n\n /**\n * Detect format from file extension\n */\n private detectFormat(filePath: string): MetadataFormat {\n const ext = path.extname(filePath).toLowerCase();\n\n switch (ext) {\n case '.json':\n return 'json';\n case '.yaml':\n case '.yml':\n return 'yaml';\n case '.ts':\n return 'typescript';\n case '.js':\n return 'javascript';\n default:\n return 'json'; // Default to JSON\n }\n }\n\n /**\n * Get serializer for format\n */\n private getSerializer(format: MetadataFormat): MetadataSerializer | undefined {\n return this.serializers.get(format);\n }\n\n /**\n * Generate ETag for content\n * Uses SHA-256 hash truncated to 32 characters for reasonable collision resistance\n * while keeping ETag headers compact (full 64-char hash is overkill for this use case)\n */\n private generateETag(content: string): string {\n const hash = createHash('sha256').update(content).digest('hex').substring(0, 32);\n return `\"${hash}\"`;\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { Plugin, PluginContext } from '@objectstack/core';\nimport { NodeMetadataManager } from './node-metadata-manager.js';\nimport { DEFAULT_METADATA_TYPE_REGISTRY } from '@objectstack/spec/kernel';\nimport type { MetadataPluginConfig } from '@objectstack/spec/kernel';\nimport { SysMetadataObject } from './objects/sys-metadata.object.js';\n\nexport interface MetadataPluginOptions {\n rootDir?: string;\n watch?: boolean;\n config?: Partial<MetadataPluginConfig>;\n}\n\nexport class MetadataPlugin implements Plugin {\n name = 'com.objectstack.metadata';\n type = 'standard';\n version = '1.0.0';\n \n private manager: NodeMetadataManager;\n private options: MetadataPluginOptions;\n\n constructor(options: MetadataPluginOptions = {}) {\n this.options = {\n watch: true,\n ...options\n };\n\n const rootDir = this.options.rootDir || process.cwd();\n\n this.manager = new NodeMetadataManager({ \n rootDir,\n watch: this.options.watch ?? true,\n formats: ['yaml', 'json', 'typescript', 'javascript'] \n });\n\n // Initialize with default type registry\n this.manager.setTypeRegistry(DEFAULT_METADATA_TYPE_REGISTRY);\n }\n\n init = async (ctx: PluginContext) => {\n ctx.logger.info('Initializing Metadata Manager', {\n root: this.options.rootDir || process.cwd(),\n watch: this.options.watch\n });\n\n // Register Metadata Manager as primary metadata service provider\n // This takes precedence over ObjectQL's fallback metadata service\n ctx.registerService('metadata', this.manager);\n\n // Register metadata system objects so ObjectQLPlugin auto-discovers them\n ctx.registerService('app.com.objectstack.metadata', {\n id: 'com.objectstack.metadata',\n name: 'Metadata',\n version: '1.0.0',\n type: 'plugin',\n namespace: 'sys',\n objects: [SysMetadataObject],\n });\n\n ctx.logger.info('MetadataPlugin providing metadata service (primary mode)', {\n mode: 'file-system',\n features: ['watch', 'persistence', 'multi-format', 'query', 'overlay', 'type-registry']\n });\n }\n\n start = async (ctx: PluginContext) => {\n ctx.logger.info('Loading metadata from file system...');\n \n // Use the type registry to discover metadata types (sorted by loadOrder)\n const sortedTypes = [...DEFAULT_METADATA_TYPE_REGISTRY]\n .sort((a, b) => a.loadOrder - b.loadOrder);\n\n let totalLoaded = 0;\n for (const entry of sortedTypes) {\n try {\n const items = await this.manager.loadMany(entry.type, {\n recursive: true\n });\n\n if (items.length > 0) {\n // Register loaded items in the in-memory registry\n for (const item of items) {\n const meta = item as any;\n if (meta?.name) {\n await this.manager.register(entry.type, meta.name, item);\n }\n }\n ctx.logger.info(`Loaded ${items.length} ${entry.type} from file system`);\n totalLoaded += items.length;\n }\n } catch (e: any) {\n ctx.logger.debug(`No ${entry.type} metadata found`, { error: e.message });\n }\n }\n \n ctx.logger.info('Metadata loading complete', { \n totalItems: totalLoaded,\n registeredTypes: sortedTypes.length,\n });\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Memory Metadata Loader\n * \n * Stores metadata in memory only. Changes are lost when process restarts.\n * Useful for testing, temporary overrides, or \"dirty\" edits.\n */\n\nimport type {\n MetadataLoadOptions,\n MetadataLoadResult,\n MetadataStats,\n MetadataLoaderContract,\n MetadataSaveOptions,\n MetadataSaveResult,\n} from '@objectstack/spec/system';\nimport type { MetadataLoader } from './loader-interface.js';\n\nexport class MemoryLoader implements MetadataLoader {\n readonly contract: MetadataLoaderContract = {\n name: 'memory',\n protocol: 'memory:',\n capabilities: {\n read: true,\n write: true,\n watch: false,\n list: true,\n },\n };\n\n // Storage: Type -> Name -> Data\n private storage = new Map<string, Map<string, any>>();\n\n async load(\n type: string,\n name: string,\n _options?: MetadataLoadOptions\n ): Promise<MetadataLoadResult> {\n const typeStore = this.storage.get(type);\n const data = typeStore?.get(name);\n\n if (data) {\n return {\n data,\n source: 'memory',\n format: 'json',\n loadTime: 0,\n };\n }\n\n return { data: null };\n }\n\n async loadMany<T = any>(\n type: string,\n _options?: MetadataLoadOptions\n ): Promise<T[]> {\n const typeStore = this.storage.get(type);\n if (!typeStore) return [];\n return Array.from(typeStore.values()) as T[];\n }\n\n async exists(type: string, name: string): Promise<boolean> {\n return this.storage.get(type)?.has(name) ?? false;\n }\n\n async stat(type: string, name: string): Promise<MetadataStats | null> {\n if (await this.exists(type, name)) {\n return {\n size: 0, // In-memory\n mtime: new Date().toISOString(),\n format: 'json',\n };\n }\n return null;\n }\n\n async list(type: string): Promise<string[]> {\n const typeStore = this.storage.get(type);\n if (!typeStore) return [];\n return Array.from(typeStore.keys());\n }\n\n async save(\n type: string,\n name: string,\n data: any,\n _options?: MetadataSaveOptions\n ): Promise<MetadataSaveResult> {\n if (!this.storage.has(type)) {\n this.storage.set(type, new Map());\n }\n \n this.storage.get(type)!.set(name, data);\n\n return {\n success: true,\n path: `memory://${type}/${name}`,\n saveTime: 0,\n };\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Remote Metadata Loader\n * \n * Loads metadata from an HTTP API.\n * This loader is stateless and delegates storage to the remote server.\n */\n\nimport type {\n MetadataLoadOptions,\n MetadataLoadResult,\n MetadataStats,\n MetadataLoaderContract,\n MetadataSaveOptions,\n MetadataSaveResult,\n} from '@objectstack/spec/system';\nimport type { MetadataLoader } from './loader-interface.js';\n\nexport class RemoteLoader implements MetadataLoader {\n readonly contract: MetadataLoaderContract = {\n name: 'remote',\n protocol: 'http:',\n capabilities: {\n read: true,\n write: true,\n watch: false, // Could implement SSE/WebSocket in future\n list: true,\n },\n };\n\n constructor(private baseUrl: string, private authToken?: string) {}\n\n private get headers() {\n return {\n 'Content-Type': 'application/json',\n ...(this.authToken ? { Authorization: `Bearer ${this.authToken}` } : {}),\n };\n }\n\n async load(\n type: string,\n name: string,\n _options?: MetadataLoadOptions\n ): Promise<MetadataLoadResult> {\n try {\n const response = await fetch(`${this.baseUrl}/${type}/${name}`, {\n method: 'GET',\n headers: this.headers,\n });\n\n if (response.status === 404) {\n return { data: null };\n }\n\n if (!response.ok) {\n throw new Error(`Remote load failed: ${response.statusText}`);\n }\n\n const data = await response.json();\n return {\n data,\n source: this.baseUrl,\n format: 'json',\n loadTime: 0, \n };\n } catch (error) {\n console.error(`RemoteLoader error loading ${type}/${name}`, error);\n throw error;\n }\n }\n\n async loadMany<T = any>(\n type: string,\n _options?: MetadataLoadOptions\n ): Promise<T[]> {\n const response = await fetch(`${this.baseUrl}/${type}`, {\n method: 'GET',\n headers: this.headers,\n });\n\n if (!response.ok) {\n return [];\n }\n\n return (await response.json()) as T[];\n }\n\n async exists(type: string, name: string): Promise<boolean> {\n const response = await fetch(`${this.baseUrl}/${type}/${name}`, {\n method: 'HEAD',\n headers: this.headers,\n });\n return response.ok;\n }\n\n async stat(type: string, name: string): Promise<MetadataStats | null> {\n // Basic implementation using HEAD\n const response = await fetch(`${this.baseUrl}/${type}/${name}`, {\n method: 'HEAD',\n headers: this.headers,\n });\n \n if (!response.ok) return null;\n\n return {\n size: Number(response.headers.get('content-length') || 0),\n mtime: new Date(response.headers.get('last-modified') || Date.now()).toISOString(),\n format: 'json',\n };\n }\n\n async list(type: string): Promise<string[]> {\n const items = await this.loadMany<{ name: string }>(type);\n return items.map(i => i.name);\n }\n\n async save(\n type: string,\n name: string,\n data: any,\n _options?: MetadataSaveOptions\n ): Promise<MetadataSaveResult> {\n const response = await fetch(`${this.baseUrl}/${type}/${name}`, {\n method: 'PUT',\n headers: this.headers,\n body: JSON.stringify(data),\n });\n\n if (!response.ok) {\n throw new Error(`Remote save failed: ${response.statusText}`);\n }\n\n return {\n success: true,\n path: `${this.baseUrl}/${type}/${name}`,\n saveTime: 0,\n };\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nexport * from './executor.js';\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { System } from '@objectstack/spec';\nimport { ISchemaDriver } from '@objectstack/spec/contracts';\n\nexport class MigrationExecutor {\n constructor(private driver: ISchemaDriver) {}\n\n async executeChangeSet(changeSet: System.ChangeSet): Promise<void> {\n console.log(`Executing ChangeSet: ${changeSet.name} (${changeSet.id})`);\n \n for (const op of changeSet.operations) {\n try {\n await this.executeOperation(op);\n } catch (e) {\n console.error(`Failed to execute operation ${op.type}:`, e);\n throw e;\n }\n }\n }\n\n private async executeOperation(op: System.MigrationOperation): Promise<void> {\n switch (op.type) {\n case 'create_object':\n console.log(` > Create Object: ${op.object.name}`);\n await this.driver.createCollection(op.object.name, op.object);\n break;\n case 'add_field':\n console.log(` > Add Field: ${op.objectName}.${op.fieldName}`);\n await this.driver.addColumn(op.objectName, op.fieldName, op.field);\n break;\n case 'remove_field':\n console.log(` > Remove Field: ${op.objectName}.${op.fieldName}`);\n await this.driver.dropColumn(op.objectName, op.fieldName);\n break;\n case 'delete_object':\n console.log(` > Delete Object: ${op.objectName}`);\n await this.driver.dropCollection(op.objectName);\n break;\n case 'execute_sql':\n console.log(` > Execute SQL`);\n await this.driver.executeRaw(op.sql);\n break;\n case 'modify_field':\n console.warn(` ! Modify Field: ${op.objectName}.${op.fieldName} (Not fully implemented)`);\n break;\n case 'rename_object':\n console.warn(` ! Rename Object: ${op.oldName} -> ${op.newName} (Not fully implemented)`);\n break;\n default:\n throw new Error(`Unknown operation type`);\n }\n }\n}\n"],"mappings":"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","names":["path","basename","chokidarWatch"]}
|
package/dist/node.d.cts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { MetadataManager, MetadataManagerOptions, MetadataLoader, MetadataSerializer } from './index.cjs';
|
|
2
|
+
export { DatabaseLoader, DatabaseLoaderOptions, JSONSerializer, MemoryLoader, MetadataPlugin, Migration, RemoteLoader, SerializeOptions, SysMetadataObject, TypeScriptSerializer, WatchCallback, YAMLSerializer } from './index.cjs';
|
|
3
|
+
import { MetadataLoaderContract, MetadataFormat, MetadataLoadOptions, MetadataLoadResult, MetadataStats, MetadataSaveOptions, MetadataSaveResult } from '@objectstack/spec/system';
|
|
4
|
+
export { MetadataCollectionInfo, MetadataExportOptions, MetadataFormat, MetadataImportOptions, MetadataLoadOptions, MetadataLoadResult, MetadataLoaderContract, MetadataManagerConfig, MetadataSaveOptions, MetadataSaveResult, MetadataStats, MetadataWatchEvent } from '@objectstack/spec/system';
|
|
5
|
+
export { IMetadataService, MetadataImportResult, MetadataTypeInfo, MetadataWatchCallback, MetadataWatchHandle } from '@objectstack/spec/contracts';
|
|
6
|
+
export { MetadataBulkResult, MetadataDependency, MetadataPluginConfig, MetadataPluginManifest, MetadataQuery, MetadataQueryResult, MetadataType, MetadataTypeRegistryEntry, MetadataValidationResult } from '@objectstack/spec/kernel';
|
|
7
|
+
import { Logger } from '@objectstack/core';
|
|
8
|
+
import 'zod';
|
|
9
|
+
import '@objectstack/spec/data';
|
|
10
|
+
import '@objectstack/spec';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Node metadata manager class
|
|
14
|
+
*/
|
|
15
|
+
declare class NodeMetadataManager extends MetadataManager {
|
|
16
|
+
private watcher?;
|
|
17
|
+
constructor(config: MetadataManagerOptions);
|
|
18
|
+
/**
|
|
19
|
+
* Stop all watching
|
|
20
|
+
*/
|
|
21
|
+
stopWatching(): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Start watching for file changes
|
|
24
|
+
*/
|
|
25
|
+
private startWatching;
|
|
26
|
+
/**
|
|
27
|
+
* Handle file change events
|
|
28
|
+
*/
|
|
29
|
+
private handleFileEvent;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
declare class FilesystemLoader implements MetadataLoader {
|
|
33
|
+
private rootDir;
|
|
34
|
+
private serializers;
|
|
35
|
+
private logger?;
|
|
36
|
+
readonly contract: MetadataLoaderContract;
|
|
37
|
+
private cache;
|
|
38
|
+
constructor(rootDir: string, serializers: Map<MetadataFormat, MetadataSerializer>, logger?: Logger | undefined);
|
|
39
|
+
load(type: string, name: string, options?: MetadataLoadOptions): Promise<MetadataLoadResult>;
|
|
40
|
+
loadMany<T = any>(type: string, options?: MetadataLoadOptions): Promise<T[]>;
|
|
41
|
+
exists(type: string, name: string): Promise<boolean>;
|
|
42
|
+
stat(type: string, name: string): Promise<MetadataStats | null>;
|
|
43
|
+
list(type: string): Promise<string[]>;
|
|
44
|
+
save(type: string, name: string, data: any, options?: MetadataSaveOptions): Promise<MetadataSaveResult>;
|
|
45
|
+
/**
|
|
46
|
+
* Find file for a given type and name
|
|
47
|
+
*/
|
|
48
|
+
private findFile;
|
|
49
|
+
/**
|
|
50
|
+
* Detect format from file extension
|
|
51
|
+
*/
|
|
52
|
+
private detectFormat;
|
|
53
|
+
/**
|
|
54
|
+
* Get serializer for format
|
|
55
|
+
*/
|
|
56
|
+
private getSerializer;
|
|
57
|
+
/**
|
|
58
|
+
* Generate ETag for content
|
|
59
|
+
* Uses SHA-256 hash truncated to 32 characters for reasonable collision resistance
|
|
60
|
+
* while keeping ETag headers compact (full 64-char hash is overkill for this use case)
|
|
61
|
+
*/
|
|
62
|
+
private generateETag;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export { FilesystemLoader, MetadataLoader, MetadataManager, MetadataManagerOptions, MetadataSerializer, NodeMetadataManager };
|
package/dist/node.d.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { MetadataManager, MetadataManagerOptions, MetadataLoader, MetadataSerializer } from './index.js';
|
|
2
|
+
export { DatabaseLoader, DatabaseLoaderOptions, JSONSerializer, MemoryLoader, MetadataPlugin, Migration, RemoteLoader, SerializeOptions, SysMetadataObject, TypeScriptSerializer, WatchCallback, YAMLSerializer } from './index.js';
|
|
3
|
+
import { MetadataLoaderContract, MetadataFormat, MetadataLoadOptions, MetadataLoadResult, MetadataStats, MetadataSaveOptions, MetadataSaveResult } from '@objectstack/spec/system';
|
|
4
|
+
export { MetadataCollectionInfo, MetadataExportOptions, MetadataFormat, MetadataImportOptions, MetadataLoadOptions, MetadataLoadResult, MetadataLoaderContract, MetadataManagerConfig, MetadataSaveOptions, MetadataSaveResult, MetadataStats, MetadataWatchEvent } from '@objectstack/spec/system';
|
|
5
|
+
export { IMetadataService, MetadataImportResult, MetadataTypeInfo, MetadataWatchCallback, MetadataWatchHandle } from '@objectstack/spec/contracts';
|
|
6
|
+
export { MetadataBulkResult, MetadataDependency, MetadataPluginConfig, MetadataPluginManifest, MetadataQuery, MetadataQueryResult, MetadataType, MetadataTypeRegistryEntry, MetadataValidationResult } from '@objectstack/spec/kernel';
|
|
7
|
+
import { Logger } from '@objectstack/core';
|
|
8
|
+
import 'zod';
|
|
9
|
+
import '@objectstack/spec/data';
|
|
10
|
+
import '@objectstack/spec';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Node metadata manager class
|
|
14
|
+
*/
|
|
15
|
+
declare class NodeMetadataManager extends MetadataManager {
|
|
16
|
+
private watcher?;
|
|
17
|
+
constructor(config: MetadataManagerOptions);
|
|
18
|
+
/**
|
|
19
|
+
* Stop all watching
|
|
20
|
+
*/
|
|
21
|
+
stopWatching(): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Start watching for file changes
|
|
24
|
+
*/
|
|
25
|
+
private startWatching;
|
|
26
|
+
/**
|
|
27
|
+
* Handle file change events
|
|
28
|
+
*/
|
|
29
|
+
private handleFileEvent;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
declare class FilesystemLoader implements MetadataLoader {
|
|
33
|
+
private rootDir;
|
|
34
|
+
private serializers;
|
|
35
|
+
private logger?;
|
|
36
|
+
readonly contract: MetadataLoaderContract;
|
|
37
|
+
private cache;
|
|
38
|
+
constructor(rootDir: string, serializers: Map<MetadataFormat, MetadataSerializer>, logger?: Logger | undefined);
|
|
39
|
+
load(type: string, name: string, options?: MetadataLoadOptions): Promise<MetadataLoadResult>;
|
|
40
|
+
loadMany<T = any>(type: string, options?: MetadataLoadOptions): Promise<T[]>;
|
|
41
|
+
exists(type: string, name: string): Promise<boolean>;
|
|
42
|
+
stat(type: string, name: string): Promise<MetadataStats | null>;
|
|
43
|
+
list(type: string): Promise<string[]>;
|
|
44
|
+
save(type: string, name: string, data: any, options?: MetadataSaveOptions): Promise<MetadataSaveResult>;
|
|
45
|
+
/**
|
|
46
|
+
* Find file for a given type and name
|
|
47
|
+
*/
|
|
48
|
+
private findFile;
|
|
49
|
+
/**
|
|
50
|
+
* Detect format from file extension
|
|
51
|
+
*/
|
|
52
|
+
private detectFormat;
|
|
53
|
+
/**
|
|
54
|
+
* Get serializer for format
|
|
55
|
+
*/
|
|
56
|
+
private getSerializer;
|
|
57
|
+
/**
|
|
58
|
+
* Generate ETag for content
|
|
59
|
+
* Uses SHA-256 hash truncated to 32 characters for reasonable collision resistance
|
|
60
|
+
* while keeping ETag headers compact (full 64-char hash is overkill for this use case)
|
|
61
|
+
*/
|
|
62
|
+
private generateETag;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export { FilesystemLoader, MetadataLoader, MetadataManager, MetadataManagerOptions, MetadataSerializer, NodeMetadataManager };
|
|
@@ -2144,14 +2144,16 @@ var MigrationExecutor = class {
|
|
|
2144
2144
|
};
|
|
2145
2145
|
export {
|
|
2146
2146
|
DatabaseLoader,
|
|
2147
|
+
FilesystemLoader,
|
|
2147
2148
|
JSONSerializer,
|
|
2148
2149
|
MemoryLoader,
|
|
2149
2150
|
MetadataManager,
|
|
2150
2151
|
MetadataPlugin,
|
|
2151
2152
|
migration_exports as Migration,
|
|
2153
|
+
NodeMetadataManager,
|
|
2152
2154
|
RemoteLoader,
|
|
2153
2155
|
SysMetadataObject,
|
|
2154
2156
|
TypeScriptSerializer,
|
|
2155
2157
|
YAMLSerializer
|
|
2156
2158
|
};
|
|
2157
|
-
//# sourceMappingURL=
|
|
2159
|
+
//# sourceMappingURL=node.js.map
|
package/package.json
CHANGED
|
@@ -1,22 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@objectstack/metadata",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.1",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "Metadata loading, saving, and persistence for ObjectStack",
|
|
6
|
-
"
|
|
7
|
-
"
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
8
9
|
"exports": {
|
|
9
10
|
".": {
|
|
10
|
-
"types": "./
|
|
11
|
-
"import": "./
|
|
12
|
-
"
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
13
14
|
},
|
|
14
15
|
"./node": {
|
|
15
|
-
"types": "./
|
|
16
|
-
"import": "./
|
|
17
|
-
"
|
|
16
|
+
"types": "./dist/node.d.ts",
|
|
17
|
+
"import": "./dist/node.js",
|
|
18
|
+
"require": "./dist/node.cjs"
|
|
18
19
|
}
|
|
19
20
|
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist",
|
|
23
|
+
"README.md"
|
|
24
|
+
],
|
|
20
25
|
"keywords": [
|
|
21
26
|
"objectstack",
|
|
22
27
|
"metadata",
|
|
@@ -29,9 +34,9 @@
|
|
|
29
34
|
"js-yaml": "^4.1.0",
|
|
30
35
|
"chokidar": "^5.0.0",
|
|
31
36
|
"zod": "^4.3.6",
|
|
32
|
-
"@objectstack/core": "3.3.
|
|
33
|
-
"@objectstack/spec": "3.3.
|
|
34
|
-
"@objectstack/types": "3.3.
|
|
37
|
+
"@objectstack/core": "3.3.1",
|
|
38
|
+
"@objectstack/spec": "3.3.1",
|
|
39
|
+
"@objectstack/types": "3.3.1"
|
|
35
40
|
},
|
|
36
41
|
"devDependencies": {
|
|
37
42
|
"@types/js-yaml": "^4.0.9",
|
|
@@ -40,7 +45,7 @@
|
|
|
40
45
|
"vitest": "^4.1.0"
|
|
41
46
|
},
|
|
42
47
|
"scripts": {
|
|
43
|
-
"build": "tsup
|
|
48
|
+
"build": "tsup",
|
|
44
49
|
"dev": "tsc --watch",
|
|
45
50
|
"clean": "rm -rf dist",
|
|
46
51
|
"test": "vitest run",
|
package/.turbo/turbo-build.log
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
> @objectstack/metadata@3.3.0 build /home/runner/work/spec/spec/packages/metadata
|
|
3
|
-
> tsup --config ../../tsup.config.ts
|
|
4
|
-
|
|
5
|
-
[34mCLI[39m Building entry: src/index.ts
|
|
6
|
-
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
7
|
-
[34mCLI[39m tsup v8.5.1
|
|
8
|
-
[34mCLI[39m Using tsup config: /home/runner/work/spec/spec/tsup.config.ts
|
|
9
|
-
[34mCLI[39m Target: es2020
|
|
10
|
-
[34mCLI[39m Cleaning output folder
|
|
11
|
-
[34mESM[39m Build start
|
|
12
|
-
[34mCJS[39m Build start
|
|
13
|
-
[32mESM[39m [1mdist/index.mjs [22m[32m61.75 KB[39m
|
|
14
|
-
[32mESM[39m [1mdist/index.mjs.map [22m[32m124.90 KB[39m
|
|
15
|
-
[32mESM[39m ⚡️ Build success in 142ms
|
|
16
|
-
[32mCJS[39m [1mdist/index.js [22m[32m63.89 KB[39m
|
|
17
|
-
[32mCJS[39m [1mdist/index.js.map [22m[32m127.07 KB[39m
|
|
18
|
-
[32mCJS[39m ⚡️ Build success in 147ms
|
|
19
|
-
[34mDTS[39m Build start
|
|
20
|
-
[32mDTS[39m ⚡️ Build success in 25486ms
|
|
21
|
-
[32mDTS[39m [1mdist/index.d.mts [22m[32m190.71 KB[39m
|
|
22
|
-
[32mDTS[39m [1mdist/index.d.ts [22m[32m190.71 KB[39m
|