serverless-plugin-module-registry 1.0.17 → 1.0.18

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.js CHANGED
@@ -16426,7 +16426,8 @@ var DynamoDBManager = class {
16426
16426
  // Add settings attributes if they exist for this module
16427
16427
  ...settings && {
16428
16428
  settingsSchemaJson: settings.settingsSchemaJson,
16429
- settingsDefault: settings.settingsDefault
16429
+ settingsDefault: settings.settingsDefault,
16430
+ ...settings.uiHints && { uiHints: settings.uiHints }
16430
16431
  }
16431
16432
  };
16432
16433
  if (settings) {
@@ -17525,18 +17526,21 @@ var RegistryProcessor = class {
17525
17526
  this.logger.warning(` \u26A0\uFE0F Could not load settings module for ${moduleName}`);
17526
17527
  return null;
17527
17528
  }
17528
- const { settingsDefault } = settingsModule;
17529
+ const { settingsDefault, uiHints } = settingsModule;
17529
17530
  this.logger.info(` \u{1F50D} settingsModule keys: ${Object.keys(settingsModule).join(", ")}`);
17530
17531
  this.logger.info(` \u{1F50D} settingsDefault value: ${JSON.stringify(settingsDefault)}`);
17531
17532
  if (!settingsDefault) {
17532
17533
  this.logger.warning(` \u26A0\uFE0F No settingsDefault export found in ${moduleName}/registry/settings.ts`);
17533
17534
  return null;
17534
17535
  }
17535
- const settingsSchemaJson = JSON.stringify(this.inferJsonSchema(settingsDefault));
17536
+ const rawSchema = this.inferJsonSchema(settingsDefault);
17537
+ const enrichedSchema = uiHints ? this.enrichSchemaWithHints(rawSchema, uiHints, settingsDefault) : this.addDefaultsToSchema(rawSchema, settingsDefault);
17538
+ const settingsSchemaJson = JSON.stringify(enrichedSchema);
17536
17539
  const settingsEntry = {
17537
17540
  moduleName,
17538
17541
  settingsSchemaJson,
17539
17542
  settingsDefault,
17543
+ uiHints,
17540
17544
  lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
17541
17545
  };
17542
17546
  this.logger.info(` \u2713 Settings loaded for ${moduleName}: ${JSON.stringify(settingsDefault)}`);
@@ -17631,6 +17635,106 @@ var RegistryProcessor = class {
17631
17635
  return {};
17632
17636
  }
17633
17637
  }
17638
+ /**
17639
+ * Enrich an inferred JSON Schema with uiHints metadata and defaults.
17640
+ * Adds title, description, readOnly, enum labels, and default values.
17641
+ */
17642
+ enrichSchemaWithHints(schema, hints, defaults2) {
17643
+ const enriched = { ...schema };
17644
+ if (hints.title) enriched.title = hints.title;
17645
+ if (hints.description) enriched.description = hints.description;
17646
+ if (enriched.properties && typeof enriched.properties === "object") {
17647
+ enriched.properties = this.enrichProperties(
17648
+ enriched.properties,
17649
+ hints,
17650
+ defaults2,
17651
+ ""
17652
+ );
17653
+ }
17654
+ return enriched;
17655
+ }
17656
+ /**
17657
+ * Recursively enrich schema properties with uiHints metadata.
17658
+ */
17659
+ enrichProperties(properties, hints, defaults2, parentPath) {
17660
+ const readOnlyFields = hints.readOnly || [];
17661
+ const enumLabels = hints.enumLabels || {};
17662
+ const sections = hints.sections || [];
17663
+ const propHints = hints.properties || {};
17664
+ const enriched = {};
17665
+ for (const [key, propSchema] of Object.entries(properties)) {
17666
+ const dotPath = parentPath ? `${parentPath}.${key}` : key;
17667
+ const prop = { ...propSchema };
17668
+ prop.title = prop.title || this.camelCaseToTitle(key);
17669
+ if (propHints[key] && propHints[key].description) {
17670
+ prop.description = propHints[key].description;
17671
+ }
17672
+ if (defaults2 && key in defaults2) {
17673
+ prop.default = defaults2[key];
17674
+ }
17675
+ if (readOnlyFields.includes(dotPath)) {
17676
+ prop.readOnly = true;
17677
+ }
17678
+ const section = sections.find((s) => s.key === key);
17679
+ if (section) {
17680
+ prop.title = section.title;
17681
+ if (section.description) prop.description = section.description;
17682
+ }
17683
+ if (enumLabels[dotPath] && prop.type === "array") {
17684
+ const items = prop.items || {};
17685
+ items.type = "string";
17686
+ items.enum = Object.keys(enumLabels[dotPath]);
17687
+ prop.items = items;
17688
+ prop["x-enumLabels"] = enumLabels[dotPath];
17689
+ }
17690
+ if (prop.type === "object" && prop.properties) {
17691
+ const nestedDefaults = defaults2 && typeof defaults2[key] === "object" && defaults2[key] !== null ? defaults2[key] : {};
17692
+ prop.properties = this.enrichProperties(
17693
+ prop.properties,
17694
+ hints,
17695
+ nestedDefaults,
17696
+ dotPath
17697
+ );
17698
+ }
17699
+ enriched[key] = prop;
17700
+ }
17701
+ return enriched;
17702
+ }
17703
+ /**
17704
+ * Add default values to schema properties (without uiHints).
17705
+ * Fallback for modules without uiHints — still adds auto-generated titles and defaults.
17706
+ */
17707
+ addDefaultsToSchema(schema, defaults2) {
17708
+ const enriched = { ...schema };
17709
+ if (enriched.properties && typeof enriched.properties === "object") {
17710
+ const properties = enriched.properties;
17711
+ const enrichedProps = {};
17712
+ for (const [key, propSchema] of Object.entries(properties)) {
17713
+ const prop = { ...propSchema };
17714
+ prop.title = this.camelCaseToTitle(key);
17715
+ if (defaults2 && key in defaults2) {
17716
+ prop.default = defaults2[key];
17717
+ }
17718
+ if (prop.type === "object" && prop.properties && defaults2 && typeof defaults2[key] === "object") {
17719
+ const nested = this.addDefaultsToSchema(
17720
+ prop,
17721
+ defaults2[key]
17722
+ );
17723
+ Object.assign(prop, nested);
17724
+ }
17725
+ enrichedProps[key] = prop;
17726
+ }
17727
+ enriched.properties = enrichedProps;
17728
+ }
17729
+ return enriched;
17730
+ }
17731
+ /**
17732
+ * Convert a camelCase string to Title Case for auto-generated labels.
17733
+ * e.g., 'serproCredentialsConfigured' → 'Serpro Credentials Configured'
17734
+ */
17735
+ camelCaseToTitle(str) {
17736
+ return str.replace(/([A-Z])/g, " $1").replace(/^./, (s) => s.toUpperCase()).trim();
17737
+ }
17634
17738
  /**
17635
17739
  * Fallback: Parse settings file manually to extract settingsDefault
17636
17740
  * Handles both direct object literals and re-exports from imported variables
@@ -17645,6 +17749,7 @@ var RegistryProcessor = class {
17645
17749
  return null;
17646
17750
  }
17647
17751
  const startIndex = exportMatch.index + exportMatch[0].length;
17752
+ let result = null;
17648
17753
  if (content[startIndex] === "{") {
17649
17754
  const objectLiteral = this.extractBalancedBraces(content, startIndex);
17650
17755
  if (!objectLiteral) {
@@ -17652,7 +17757,7 @@ var RegistryProcessor = class {
17652
17757
  return null;
17653
17758
  }
17654
17759
  this.logger.info(` \u{1F4E6} Found direct settingsDefault: ${objectLiteral.substring(0, 100)}${objectLiteral.length > 100 ? "..." : ""}`);
17655
- return this.parseObjectLiteral(objectLiteral);
17760
+ result = this.parseObjectLiteral(objectLiteral);
17656
17761
  } else {
17657
17762
  const varMatch = content.substring(startIndex).match(/^(\w+)/);
17658
17763
  if (!varMatch) {
@@ -17661,13 +17766,44 @@ var RegistryProcessor = class {
17661
17766
  }
17662
17767
  const varName = varMatch[1];
17663
17768
  this.logger.info(` \u{1F517} settingsDefault references variable: ${varName}`);
17664
- return this.resolveImportedSettings(settingsFile, content, varName);
17769
+ result = this.resolveImportedSettings(settingsFile, content, varName);
17665
17770
  }
17771
+ if (result) {
17772
+ const uiHints = this.extractUiHints(content);
17773
+ if (uiHints) {
17774
+ result.uiHints = uiHints;
17775
+ this.logger.info(` \u{1F3A8} Found uiHints: ${JSON.stringify(uiHints).substring(0, 100)}...`);
17776
+ }
17777
+ }
17778
+ return result;
17666
17779
  } catch (readError) {
17667
17780
  this.logger.warning(` \u26A0\uFE0F Could not read settings file ${settingsFile}: ${readError.message}`);
17668
17781
  return null;
17669
17782
  }
17670
17783
  }
17784
+ /**
17785
+ * Extract uiHints export from a settings file
17786
+ */
17787
+ extractUiHints(content) {
17788
+ const hintsMatch = content.match(/export\s+const\s+uiHints(?:\s*:\s*[\w<>,\s]+)?\s*=\s*/);
17789
+ if (!hintsMatch) {
17790
+ return null;
17791
+ }
17792
+ const startIndex = hintsMatch.index + hintsMatch[0].length;
17793
+ if (content[startIndex] !== "{") {
17794
+ return null;
17795
+ }
17796
+ const objectLiteral = this.extractBalancedBraces(content, startIndex);
17797
+ if (!objectLiteral) {
17798
+ return null;
17799
+ }
17800
+ try {
17801
+ return new Function(`return ${objectLiteral}`)();
17802
+ } catch {
17803
+ this.logger.warning(" \u26A0\uFE0F Could not parse uiHints object literal");
17804
+ return null;
17805
+ }
17806
+ }
17671
17807
  /**
17672
17808
  * Parse an object literal string into a JS object
17673
17809
  */