@@ -242,6 +242,64 @@ void EnvironmentOptions::CheckOptions(std::vector<std::string>* errors,
242
242
243
243
namespace options_parser {
244
244
245
+ // Helper function to convert option types to their string representation
246
+ // and add them to a V8 Map
247
+ static bool AddOptionTypeToMap (Isolate* isolate,
248
+ Local<Context> context,
249
+ Local<Map> map,
250
+ const std::string& option_name,
251
+ const OptionType& option_type) {
252
+ std::string type;
253
+ switch (static_cast <int >(option_type)) {
254
+ case 0 : // No-op
255
+ case 1 : // V8 flags
256
+ break ; // V8 and NoOp flags are not supported
257
+
258
+ case 2 :
259
+ type = " boolean" ;
260
+ break ;
261
+ case 3 : // integer
262
+ case 4 : // unsigned integer
263
+ case 6 : // host port
264
+ type = " number" ;
265
+ break ;
266
+ case 5 : // string
267
+ type = " string" ;
268
+ break ;
269
+ case 7 : // string array
270
+ type = " array" ;
271
+ break ;
272
+ default :
273
+ UNREACHABLE ();
274
+ }
275
+
276
+ if (type.empty ()) {
277
+ return true ; // Skip this entry but continue processing
278
+ }
279
+
280
+ Local<String> option_key;
281
+ if (!String::NewFromUtf8 (isolate,
282
+ option_name.data (),
283
+ v8::NewStringType::kNormal ,
284
+ option_name.size ())
285
+ .ToLocal (&option_key)) {
286
+ return true ; // Skip this entry but continue processing
287
+ }
288
+
289
+ Local<String> type_value;
290
+ if (!String::NewFromUtf8 (
291
+ isolate, type.data (), v8::NewStringType::kNormal , type.size ())
292
+ .ToLocal (&type_value)) {
293
+ return true ; // Skip this entry but continue processing
294
+ }
295
+
296
+ if (map->Set (context, option_key, type_value).IsEmpty ()) {
297
+ return false ; // Error occurred, stop processing
298
+ }
299
+
300
+ return true ;
301
+ }
302
+
245
303
class DebugOptionsParser : public OptionsParser <DebugOptions> {
246
304
public:
247
305
DebugOptionsParser ();
@@ -1636,56 +1694,71 @@ void GetEnvOptionsInputType(const FunctionCallbackInfo<Value>& args) {
1636
1694
for (const auto & item : _ppop_instance.options_ ) {
1637
1695
if (!item.first .empty () && !item.first .starts_with (' [' ) &&
1638
1696
item.second .env_setting == kAllowedInEnvvar ) {
1639
- std::string type;
1640
- switch (static_cast <int >(item.second .type )) {
1641
- case 0 : // No-op
1642
- case 1 : // V8 flags
1643
- break ; // V8 and NoOp flags are not supported
1644
-
1645
- case 2 :
1646
- type = " boolean" ;
1647
- break ;
1648
- case 3 : // integer
1649
- case 4 : // unsigned integer
1650
- case 6 : // host port
1651
- type = " number" ;
1652
- break ;
1653
- case 5 : // string
1654
- type = " string" ;
1655
- break ;
1656
- case 7 : // string array
1657
- type = " array" ;
1658
- break ;
1659
- default :
1660
- UNREACHABLE ();
1697
+ if (!AddOptionTypeToMap (
1698
+ isolate, context, flags_map, item.first , item.second .type )) {
1699
+ return ;
1661
1700
}
1701
+ }
1702
+ }
1703
+ args.GetReturnValue ().Set (flags_map);
1704
+ }
1662
1705
1663
- if (type.empty ()) {
1664
- continue ;
1665
- }
1706
+ // This function returns a two-level nested map containing all the available
1707
+ // options grouped by their namespaces along with their input types. This is
1708
+ // used for config file JSON schema generation
1709
+ void GetNamespaceOptionsInputType (const FunctionCallbackInfo<Value>& args) {
1710
+ Isolate* isolate = args.GetIsolate ();
1711
+ Local<Context> context = isolate->GetCurrentContext ();
1712
+ Environment* env = Environment::GetCurrent (context);
1666
1713
1667
- Local<String> value;
1668
- if (!String::NewFromUtf8 (
1669
- isolate, type.data (), v8::NewStringType::kNormal , type.size ())
1670
- .ToLocal (&value)) {
1671
- continue ;
1714
+ if (!env->has_run_bootstrapping_code ()) {
1715
+ // No code because this is an assertion.
1716
+ THROW_ERR_OPTIONS_BEFORE_BOOTSTRAPPING (
1717
+ isolate, " Should not query options before bootstrapping is done" );
1718
+ }
1719
+
1720
+ Mutex::ScopedLock lock (per_process::cli_options_mutex);
1721
+
1722
+ Local<Map> namespaces_map = Map::New (isolate);
1723
+
1724
+ // Get the mapping of namespaces to their options and types
1725
+ auto namespace_options = options_parser::MapNamespaceOptionsAssociations ();
1726
+
1727
+ for (const auto & ns_entry : namespace_options) {
1728
+ const std::string& namespace_name = ns_entry.first ;
1729
+ const auto & options_map = ns_entry.second ;
1730
+
1731
+ Local<Map> options_type_map = Map::New (isolate);
1732
+
1733
+ for (const auto & opt_entry : options_map) {
1734
+ const std::string& option_name = opt_entry.first ;
1735
+ const options_parser::OptionType& option_type = opt_entry.second ;
1736
+
1737
+ if (!AddOptionTypeToMap (
1738
+ isolate, context, options_type_map, option_name, option_type)) {
1739
+ return ;
1672
1740
}
1741
+ }
1673
1742
1674
- Local<String> field;
1743
+ // Only add namespaces that have options
1744
+ if (options_type_map->Size () > 0 ) {
1745
+ Local<String> namespace_key;
1675
1746
if (!String::NewFromUtf8 (isolate,
1676
- item. first .data (),
1747
+ namespace_name .data (),
1677
1748
v8::NewStringType::kNormal ,
1678
- item. first .size ())
1679
- .ToLocal (&field )) {
1749
+ namespace_name .size ())
1750
+ .ToLocal (&namespace_key )) {
1680
1751
continue ;
1681
1752
}
1682
1753
1683
- if (flags_map->Set (context, field, value).IsEmpty ()) {
1754
+ if (namespaces_map->Set (context, namespace_key, options_type_map)
1755
+ .IsEmpty ()) {
1684
1756
return ;
1685
1757
}
1686
1758
}
1687
1759
}
1688
- args.GetReturnValue ().Set (flags_map);
1760
+
1761
+ args.GetReturnValue ().Set (namespaces_map);
1689
1762
}
1690
1763
1691
1764
void Initialize (Local<Object> target,
@@ -1702,6 +1775,10 @@ void Initialize(Local<Object> target,
1702
1775
context, target, " getEmbedderOptions" , GetEmbedderOptions);
1703
1776
SetMethodNoSideEffect (
1704
1777
context, target, " getEnvOptionsInputType" , GetEnvOptionsInputType);
1778
+ SetMethodNoSideEffect (context,
1779
+ target,
1780
+ " getNamespaceOptionsInputType" ,
1781
+ GetNamespaceOptionsInputType);
1705
1782
Local<Object> env_settings = Object::New (isolate);
1706
1783
NODE_DEFINE_CONSTANT (env_settings, kAllowedInEnvvar );
1707
1784
NODE_DEFINE_CONSTANT (env_settings, kDisallowedInEnvvar );
@@ -1728,6 +1805,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
1728
1805
registry->Register (GetCLIOptionsInfo);
1729
1806
registry->Register (GetEmbedderOptions);
1730
1807
registry->Register (GetEnvOptionsInputType);
1808
+ registry->Register (GetNamespaceOptionsInputType);
1731
1809
}
1732
1810
} // namespace options_parser
1733
1811
0 commit comments