@omen.foundation/node-microservice-runtime 0.1.103 → 0.1.105

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@omen.foundation/node-microservice-runtime",
3
- "version": "0.1.103",
3
+ "version": "0.1.105",
4
4
  "description": "Beamable microservice runtime for Node.js/TypeScript services.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -747,19 +747,39 @@ async function fetchCurrentManifest(apiHost, token, cid, pid) {
747
747
  return response.json();
748
748
  }
749
749
 
750
- async function discoverStorageObjects(srcDir) {
750
+ async function discoverStorageObjects(srcDir, cwd = process.cwd()) {
751
751
  const storageObjects = [];
752
752
  try {
753
- const srcPath = path.resolve(srcDir || 'src');
753
+ // Resolve src path relative to current working directory (where publish is run from)
754
+ const srcPath = path.isAbsolute(srcDir) ? srcDir : path.resolve(cwd, srcDir || 'src');
755
+
756
+ console.log(`[beamo-node] Searching for @StorageObject decorators in: ${srcPath}`);
757
+
758
+ // Check if directory exists
759
+ try {
760
+ const stats = await fs.stat(srcPath);
761
+ if (!stats.isDirectory()) {
762
+ console.warn(`[beamo-node] Warning: ${srcPath} is not a directory`);
763
+ return storageObjects;
764
+ }
765
+ } catch (error) {
766
+ console.warn(`[beamo-node] Warning: Directory ${srcPath} does not exist`);
767
+ return storageObjects;
768
+ }
769
+
754
770
  const files = await getAllTypeScriptFiles(srcPath);
755
771
 
756
772
  if (files.length === 0) {
757
773
  console.warn(`[beamo-node] Warning: No TypeScript files found in ${srcPath}`);
774
+ return storageObjects;
758
775
  }
759
776
 
777
+ console.log(`[beamo-node] Scanning ${files.length} TypeScript file(s) for @StorageObject decorators...`);
778
+
760
779
  for (const file of files) {
761
780
  const content = await fs.readFile(file, 'utf-8');
762
- // Match @StorageObject('StorageName') pattern
781
+ // Match @StorageObject('StorageName') pattern - handle both single and double quotes
782
+ // Also match multiline patterns where decorator might be on a different line
763
783
  const storageRegex = /@StorageObject\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
764
784
  let match;
765
785
  while ((match = storageRegex.exec(content)) !== null) {
@@ -771,16 +791,20 @@ async function discoverStorageObjects(srcDir) {
771
791
  checksum: null,
772
792
  archived: false,
773
793
  });
774
- console.log(`[beamo-node] Discovered storage object: ${storageName}`);
794
+ console.log(`[beamo-node] Discovered storage object: ${storageName} (from ${path.relative(cwd, file)})`);
775
795
  }
776
796
  }
777
797
  }
778
798
 
779
799
  if (storageObjects.length === 0) {
780
- console.log(`[beamo-node] No @StorageObject decorators found in ${srcPath}`);
800
+ console.log(`[beamo-node] No @StorageObject decorators found in ${files.length} file(s) in ${srcPath}`);
801
+ console.log(`[beamo-node] Make sure your storage classes are decorated with @StorageObject('StorageName')`);
781
802
  }
782
803
  } catch (error) {
783
804
  console.warn(`[beamo-node] Error discovering storage objects: ${error instanceof Error ? error.message : String(error)}`);
805
+ if (error instanceof Error && error.stack) {
806
+ console.warn(`[beamo-node] Stack: ${error.stack}`);
807
+ }
784
808
  // If we can't discover storage, that's okay - we'll just use existing ones
785
809
  }
786
810
  return storageObjects;
@@ -887,8 +911,10 @@ async function updateManifest({
887
911
  id: reference.id?.Value ?? reference.id,
888
912
  storageType: reference.storageType?.Value ?? reference.storageType ?? 'mongov1',
889
913
  enabled: reference.enabled?.Value ?? reference.enabled ?? true,
890
- checksum: reference.checksum?.Value ?? reference.checksum,
891
- archived: reference.archived?.Value ?? reference.archived ?? false,
914
+ // templateId and archived are optional - only include if present
915
+ ...(reference.templateId ? { templateId: reference.templateId?.Value ?? reference.templateId } : {}),
916
+ ...(reference.archived !== undefined ? { archived: reference.archived?.Value ?? reference.archived ?? false } : {}),
917
+ // Note: checksum is computed by backend, we don't send it
892
918
  }))
893
919
  : [];
894
920
 
@@ -906,20 +932,41 @@ async function updateManifest({
906
932
  });
907
933
  discoveredStorage.forEach(s => {
908
934
  if (!storageMap.has(s.id)) {
909
- storageMap.set(s.id, {
910
- ...s,
935
+ // New storage - create ServiceStorageReference matching backend case class:
936
+ // case class ServiceStorageReference(id: String, storageType: String, enabled: Boolean, templateId: Option[String] = None, archived: Option[Boolean] = None)
937
+ const newStorage = {
938
+ id: s.id,
911
939
  storageType: 'mongov1', // All discovered storage uses MongoDB
912
- });
940
+ enabled: true,
941
+ // templateId and archived are optional - only include if explicitly set
942
+ ...(s.templateId ? { templateId: s.templateId } : {}),
943
+ ...(s.archived !== undefined ? { archived: s.archived } : {}),
944
+ };
945
+ storageMap.set(s.id, newStorage);
946
+ console.log(`[beamo-node] Adding new storage to manifest: ${s.id} (type: ${newStorage.storageType}, enabled: ${newStorage.enabled})`);
913
947
  } else {
914
- // Update existing storage to ensure storageType is 'mongov1'
948
+ // Update existing storage to ensure storageType is 'mongov1' and format is correct
915
949
  const existing = storageMap.get(s.id);
916
- storageMap.set(s.id, {
917
- ...existing,
950
+ const updatedStorage = {
951
+ id: existing.id,
918
952
  storageType: 'mongov1',
919
- });
953
+ enabled: existing.enabled !== false, // Ensure enabled is true unless explicitly false
954
+ // Only include optional fields if they have values
955
+ ...(existing.templateId ? { templateId: existing.templateId } : {}),
956
+ ...(existing.archived !== undefined ? { archived: existing.archived } : {}),
957
+ };
958
+ storageMap.set(s.id, updatedStorage);
959
+ console.log(`[beamo-node] Updating existing storage in manifest: ${s.id} (type: mongov1, enabled: ${updatedStorage.enabled})`);
920
960
  }
921
961
  });
922
- const storageReferences = Array.from(storageMap.values());
962
+ // Convert to array and remove any extra fields (like checksum) that backend doesn't expect
963
+ const storageReferences = Array.from(storageMap.values()).map(s => ({
964
+ id: s.id,
965
+ storageType: s.storageType,
966
+ enabled: s.enabled,
967
+ ...(s.templateId ? { templateId: s.templateId } : {}),
968
+ ...(s.archived !== undefined ? { archived: s.archived } : {}),
969
+ }));
923
970
 
924
971
  // Extract existing components and dependencies for the service
925
972
  const existingServiceRef = serviceReferences.find(
@@ -1027,10 +1074,19 @@ async function updateManifest({
1027
1074
  if (storageReferences.length > 0) {
1028
1075
  console.log(`[beamo-node] Publishing ${storageReferences.length} storage reference(s) in manifest:`);
1029
1076
  storageReferences.forEach(s => {
1030
- console.log(`[beamo-node] - ${s.id} (type: ${s.storageType || 'mongov1'}, enabled: ${s.enabled !== false})`);
1077
+ const details = [
1078
+ `id: ${s.id}`,
1079
+ `storageType: ${s.storageType || 'mongov1'}`,
1080
+ `enabled: ${s.enabled !== false}`,
1081
+ ...(s.templateId ? [`templateId: ${s.templateId}`] : []),
1082
+ ...(s.archived !== undefined ? [`archived: ${s.archived}`] : []),
1083
+ ].join(', ');
1084
+ console.log(`[beamo-node] - ${details}`);
1031
1085
  });
1086
+ console.log(`[beamo-node] Storage references JSON: ${JSON.stringify(storageReferences, null, 2)}`);
1032
1087
  } else {
1033
- console.warn(`[beamo-node] Warning: No storage references in manifest. Database will not be created automatically.`);
1088
+ console.warn(`[beamo-node] ⚠️ WARNING: No storage references in manifest. Database will NOT be created automatically.`);
1089
+ console.warn(`[beamo-node] Make sure you have @StorageObject('StorageName') decorators in your code.`);
1034
1090
  }
1035
1091
 
1036
1092
  const publishUrl = new URL('/basic/beamo/manifest', apiHost);
@@ -1458,7 +1514,7 @@ async function main() {
1458
1514
  progress.start('Discovering storage objects and components');
1459
1515
  // shortImageId already defined above from verification step
1460
1516
  const existingManifest = await fetchCurrentManifest(apiHost, token, cid, pid);
1461
- const discoveredStorage = await discoverStorageObjects('src');
1517
+ const discoveredStorage = await discoverStorageObjects('src', process.cwd());
1462
1518
  const discoveredComponents = await discoverFederationComponents('src');
1463
1519
  // Dependencies are ServiceDependencyReference objects with id and storageType
1464
1520
  // storageType should be "mongov1" for MongoDB storage objects (matching C# microservices)