@subconverter/core 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -228,15 +228,22 @@ interface ExtraSettings {
228
228
  nameRemove: string[];
229
229
  addEmoji: boolean;
230
230
  removeEmoji: boolean;
231
- /** Prefix node names with the server's country/region when the name lacks one. */
231
+ /** Prefix node names with the server's ISO country code when the name lacks one. */
232
232
  autoCountry: boolean;
233
- /** Locale used for `Intl.DisplayNames` country names (default `zh-CN`). */
234
- countryLocale: string;
235
233
  /**
236
234
  * Resolve a node's ISO 3166-1 alpha-2 country code. Platform-free: the Node
237
235
  * adapter supplies a GeoIP-backed lookup; browsers may supply their own.
236
+ * Required by `autoCountry` and the country filters below.
238
237
  */
239
238
  countryResolver?: (node: Proxy) => string | undefined;
239
+ /** Keep only nodes whose GeoIP country is in this ISO code list. */
240
+ includeCountries: string[];
241
+ /** Drop nodes whose GeoIP country is in this ISO code list. */
242
+ excludeCountries: string[];
243
+ /** Keep only nodes matching one of these remark rules (empty keeps all). */
244
+ includeRemarks: string[];
245
+ /** Drop nodes matching one of these remark rules. */
246
+ excludeRemarks: string[];
240
247
  appendProxyType: boolean;
241
248
  nodeList: boolean;
242
249
  sortFlag: boolean;
@@ -273,6 +280,10 @@ interface RequestSettings {
273
280
  nameRemove: string[];
274
281
  includeRemarks: string[];
275
282
  excludeRemarks: string[];
283
+ /** Keep only nodes whose GeoIP country is in this ISO code list. */
284
+ includeCountries: string[];
285
+ /** Drop nodes whose GeoIP country is in this ISO code list. */
286
+ excludeCountries: string[];
276
287
  addEmoji: boolean;
277
288
  removeEmoji: boolean;
278
289
  autoCountry: boolean;
@@ -459,6 +470,8 @@ interface ExternalConfig {
459
470
  nameRemove: string[];
460
471
  includeRemarks: string[];
461
472
  excludeRemarks: string[];
473
+ includeCountries: string[];
474
+ excludeCountries: string[];
462
475
  addEmoji: boolean;
463
476
  removeEmoji: boolean;
464
477
  autoCountry: boolean;
@@ -1128,13 +1141,19 @@ declare function nodeNameRemove(node: Proxy, removeList: string[]): void;
1128
1141
  /** Apply rename rules to a node's remark (script rules are ignored). */
1129
1142
  declare function nodeRename(node: Proxy, renameArray: RegexMatchConfig[]): void;
1130
1143
  /**
1131
- * Prefix a node's remark with its server country/region when the remark does
1132
- * not already mention one (e.g. `server1` -> `美国-server1`).
1144
+ * Prefix a node's remark with its ISO server country when the remark does
1145
+ * not already mention one (e.g. `server1` -> `US-server1`).
1133
1146
  *
1134
1147
  * `resolve` returns an ISO 3166-1 alpha-2 code; a missing/unknown code leaves
1135
1148
  * the remark untouched. Mirrors the request `auto_country` switch.
1136
1149
  */
1137
- declare function addCountryPrefix(node: Proxy, resolve: (node: Proxy) => string | undefined, locale?: string): string;
1150
+ declare function addCountryPrefix(node: Proxy, resolve: (node: Proxy) => string | undefined): string;
1151
+ /**
1152
+ * Drop nodes by GeoIP country: keep only `include` codes (unknown countries
1153
+ * never match, so they are dropped), then drop `exclude` codes (unknown
1154
+ * countries are kept). Invalid codes are ignored.
1155
+ */
1156
+ declare function filterNodesByCountry(nodes: Proxy[], resolve: ((node: Proxy) => string | undefined) | undefined, include: string[], exclude: string[]): void;
1138
1157
  interface PreprocessOptions {
1139
1158
  removeEmoji: boolean;
1140
1159
  addEmoji: boolean;
@@ -1146,8 +1165,15 @@ interface PreprocessOptions {
1146
1165
  /** Literal fragments stripped from names before every other naming rule. */
1147
1166
  nameRemove?: string[];
1148
1167
  autoCountry?: boolean;
1149
- countryLocale?: string;
1150
1168
  countryResolver?: (node: Proxy) => string | undefined;
1169
+ /** Keep only nodes whose GeoIP country is in this ISO code list. */
1170
+ includeCountries?: string[];
1171
+ /** Drop nodes whose GeoIP country is in this ISO code list. */
1172
+ excludeCountries?: string[];
1173
+ /** Keep only nodes matching one of these remark rules (empty keeps all). */
1174
+ includeRemarks?: string[];
1175
+ /** Drop nodes matching one of these remark rules. */
1176
+ excludeRemarks?: string[];
1151
1177
  }
1152
1178
  /** Apply name cleanup, emoji removal, renaming, emoji insertion, and optional sorting. */
1153
1179
  declare function preprocessNodes(nodes: Proxy[], options: PreprocessOptions): void;
@@ -1155,16 +1181,18 @@ declare function preprocessNodes(nodes: Proxy[], options: PreprocessOptions): vo
1155
1181
  declare function dedupeNodes(nodes: Proxy[]): number;
1156
1182
 
1157
1183
  /**
1158
- * ISO 3166-1 alpha-2 region helpers used when a proxy name has no country.
1184
+ * ISO 3166-1 alpha-2 region helpers.
1159
1185
  *
1160
- * The display names come from `Intl.DisplayNames` (no bundled database), with
1161
- * small overrides where the CLDR Chinese name is too verbose for a node name
1162
- * (e.g. `中国香港特别行政区` -> `香港`). Flag emoji are derived from the code.
1186
+ * Emitted prefixes are always the uppercase ISO code (`US-server1`) so node
1187
+ * names stay stable across locales. Multilingual names (Chinese/English
1188
+ * spellings, flag emoji) are only recognized by `hasRegionName` so existing
1189
+ * names are never double-prefixed.
1190
+ */
1191
+ /**
1192
+ * Normalize user input to an ISO 3166-1 alpha-2 code (`"us"` -> `"US"`),
1193
+ * or `undefined` when it is not a known region. Used for country filters.
1163
1194
  */
1164
- /** Localized country/region name (e.g. `美国`), falling back to the code. */
1165
- declare function regionDisplayName(code: string, locale?: string): string;
1166
- /** Flag emoji for a region code, or `""` when the code is invalid. */
1167
- declare function regionFlag(code: string): string;
1195
+ declare function normalizeCountryCode(code: string): string | undefined;
1168
1196
  /** `true` when the code is a known ISO 3166-1 alpha-2 region. */
1169
1197
  declare function isRegionCode(code: string): boolean;
1170
1198
  /**
@@ -1174,9 +1202,10 @@ declare function isRegionCode(code: string): boolean;
1174
1202
  */
1175
1203
  declare function hasRegionName(remark: string): boolean;
1176
1204
  /**
1177
- * Prepend `name-` to a node remark (e.g. `server1` -> `美国-server1`).
1178
- * An empty remark becomes just the country name.
1205
+ * Prefix a remark with the ISO country code (e.g. `server1` -> `US-server1`).
1206
+ * An empty remark becomes just the code. Invalid codes leave the remark
1207
+ * unchanged.
1179
1208
  */
1180
- declare function formatCountryRemark(remark: string, code: string, locale?: string): string;
1209
+ declare function formatCountryRemark(remark: string, code: string): string;
1181
1210
 
1182
- export { BalanceStrategy, CLASH_RULE_TYPES, DEFAULT_GROUPS, type ExternalConfig, type ExtraSettings, type GenerateOptions, type IniDocument, type IniSection, type LoonOptions, type MellowOptions, type Proxy, type ProxyGroupConfig, ProxyGroupType, ProxyType, QUANX_RULE_TYPES, type QuanOptions, type QuanxOptions, type RawIniSection, type RegexMatchConfig, type RequestSettings, type RulesetConfig, type RulesetContent, RulesetType, SING_BOX_RULE_TYPES, SSR_CIPHERS, SS_CIPHERS, SURF_RULE_TYPES, SURGE2_RULE_TYPES, SURGE_RULE_TYPES, type SingBoxOptions, type SingBoxRoute, type SurfboardOptions, type SurgeRulesetResult, TargetFormat, type TemplateVars, type TriBool, type UserinfoData, type UserinfoProvider, addCountryPrefix, addEmoji, anyTlsConstruct, applyMatcher, base64Decode, base64Encode, buildClash, checkIgnore, convertRuleset, convertUserinfo, countOccurrences, createExtraSettings, createProxy, createProxyGroupConfig, createRequestSettings, createRulesetConfig, createSelectGroup, dedupeNodes, explode, explodeAnyTls, explodeClash, explodeHttp, explodeHttpSub, explodeHysteria2, explodeKitsunebi, explodeNetch, explodeNetchConf, explodeQuan, explodeShadowrocket, explodeSocks, explodeSs, explodeSsAndroid, explodeSsConf, explodeSsd, explodeSsr, explodeSsrConf, explodeSstap, explodeStdVmess, explodeSub, explodeSurge, explodeTrojan, explodeTuic, explodeVless, explodeVmess, explodeVmessConf, filterNodes, findSection, fnv1a64, fnv1a64Hex, formatCountryRemark, formatSingBoxInterval, formatSubscriptionUserinfo, generate, generatePeer, getAllUrlArgs, getDefaultProxyGroups, getDefaultRulesetConfigs, getDefaultRulesets, getSectionItems, getUrlArg, groupGenerate, hasRegionName, hasTemplatePlaceholders, httpConstruct, hysteria2Construct, hysteriaConstruct, inferUserinfoProviderFromUrl, isBlank, isFlattenableSsr, isIp, isIpv4, isIpv6, isLink, isRegionCode, isSsCipher, matchRange, nextMonthlyResetTimestamp, nodeNameRegex, nodeNameRemove, nodeRename, normalizeQueryKey, normalizeUserinfoProvider, pad2, parseClashText, parseConfContent, parseCustomProxyGroup, parseExternalConfig, parseGroupTimes, parseIni, parseJmsUserinfo, parseLink, parsePeers, parseProxyGroupType, parseRawIni, parseRegexMatch, parseRequestSettings, parseRulesetConfig, parseSubscription, parseSubscriptionUserinfo, parseTriBool, preprocessNodes, processRemark, proxyToSingle, proxyToSsSub, proxyToSsd, proxyTypeName, queryBoolFlag, regMatch, regReplace, regionDisplayName, regionFlag, removeEmoji, renderRawIni, renderTemplate, replaceAllDistinct, resolveNewFieldName, rulesetToClashRules, rulesetToSingBoxRules, rulesetToSurgeRules, runPreprocess, setRawSection, snellConstruct, socksConstruct, split, splitUrl, ssConstruct, ssLinkConstruct, ssrConstruct, ssrLinkConstruct, startsWith, strFind, stringifyClash, stripScheme, templateVariableNames, toBool, toClash, toInt, toLoon, toMellow, toQuan, toQuanX, toSingBox, toSip008, toSurfboard, toSurge, transformRuleToCommon, triBoolOr, trim, trimLowerCase, trojanConstruct, trojanLinkConstruct, tryBase64Decode, tuicConstruct, urlDecode, urlEncode, urlSafeBase64Decode, urlSafeBase64Encode, utf8Decode, utf8Encode, vlessConstruct, vmessConstruct, vmessLinkConstruct, wireGuardConstruct };
1211
+ export { BalanceStrategy, CLASH_RULE_TYPES, DEFAULT_GROUPS, type ExternalConfig, type ExtraSettings, type GenerateOptions, type IniDocument, type IniSection, type LoonOptions, type MellowOptions, type Proxy, type ProxyGroupConfig, ProxyGroupType, ProxyType, QUANX_RULE_TYPES, type QuanOptions, type QuanxOptions, type RawIniSection, type RegexMatchConfig, type RequestSettings, type RulesetConfig, type RulesetContent, RulesetType, SING_BOX_RULE_TYPES, SSR_CIPHERS, SS_CIPHERS, SURF_RULE_TYPES, SURGE2_RULE_TYPES, SURGE_RULE_TYPES, type SingBoxOptions, type SingBoxRoute, type SurfboardOptions, type SurgeRulesetResult, TargetFormat, type TemplateVars, type TriBool, type UserinfoData, type UserinfoProvider, addCountryPrefix, addEmoji, anyTlsConstruct, applyMatcher, base64Decode, base64Encode, buildClash, checkIgnore, convertRuleset, convertUserinfo, countOccurrences, createExtraSettings, createProxy, createProxyGroupConfig, createRequestSettings, createRulesetConfig, createSelectGroup, dedupeNodes, explode, explodeAnyTls, explodeClash, explodeHttp, explodeHttpSub, explodeHysteria2, explodeKitsunebi, explodeNetch, explodeNetchConf, explodeQuan, explodeShadowrocket, explodeSocks, explodeSs, explodeSsAndroid, explodeSsConf, explodeSsd, explodeSsr, explodeSsrConf, explodeSstap, explodeStdVmess, explodeSub, explodeSurge, explodeTrojan, explodeTuic, explodeVless, explodeVmess, explodeVmessConf, filterNodes, filterNodesByCountry, findSection, fnv1a64, fnv1a64Hex, formatCountryRemark, formatSingBoxInterval, formatSubscriptionUserinfo, generate, generatePeer, getAllUrlArgs, getDefaultProxyGroups, getDefaultRulesetConfigs, getDefaultRulesets, getSectionItems, getUrlArg, groupGenerate, hasRegionName, hasTemplatePlaceholders, httpConstruct, hysteria2Construct, hysteriaConstruct, inferUserinfoProviderFromUrl, isBlank, isFlattenableSsr, isIp, isIpv4, isIpv6, isLink, isRegionCode, isSsCipher, matchRange, nextMonthlyResetTimestamp, nodeNameRegex, nodeNameRemove, nodeRename, normalizeCountryCode, normalizeQueryKey, normalizeUserinfoProvider, pad2, parseClashText, parseConfContent, parseCustomProxyGroup, parseExternalConfig, parseGroupTimes, parseIni, parseJmsUserinfo, parseLink, parsePeers, parseProxyGroupType, parseRawIni, parseRegexMatch, parseRequestSettings, parseRulesetConfig, parseSubscription, parseSubscriptionUserinfo, parseTriBool, preprocessNodes, processRemark, proxyToSingle, proxyToSsSub, proxyToSsd, proxyTypeName, queryBoolFlag, regMatch, regReplace, removeEmoji, renderRawIni, renderTemplate, replaceAllDistinct, resolveNewFieldName, rulesetToClashRules, rulesetToSingBoxRules, rulesetToSurgeRules, runPreprocess, setRawSection, snellConstruct, socksConstruct, split, splitUrl, ssConstruct, ssLinkConstruct, ssrConstruct, ssrLinkConstruct, startsWith, strFind, stringifyClash, stripScheme, templateVariableNames, toBool, toClash, toInt, toLoon, toMellow, toQuan, toQuanX, toSingBox, toSip008, toSurfboard, toSurge, transformRuleToCommon, triBoolOr, trim, trimLowerCase, trojanConstruct, trojanLinkConstruct, tryBase64Decode, tuicConstruct, urlDecode, urlEncode, urlSafeBase64Decode, urlSafeBase64Encode, utf8Decode, utf8Encode, vlessConstruct, vmessConstruct, vmessLinkConstruct, wireGuardConstruct };
package/dist/index.d.ts CHANGED
@@ -228,15 +228,22 @@ interface ExtraSettings {
228
228
  nameRemove: string[];
229
229
  addEmoji: boolean;
230
230
  removeEmoji: boolean;
231
- /** Prefix node names with the server's country/region when the name lacks one. */
231
+ /** Prefix node names with the server's ISO country code when the name lacks one. */
232
232
  autoCountry: boolean;
233
- /** Locale used for `Intl.DisplayNames` country names (default `zh-CN`). */
234
- countryLocale: string;
235
233
  /**
236
234
  * Resolve a node's ISO 3166-1 alpha-2 country code. Platform-free: the Node
237
235
  * adapter supplies a GeoIP-backed lookup; browsers may supply their own.
236
+ * Required by `autoCountry` and the country filters below.
238
237
  */
239
238
  countryResolver?: (node: Proxy) => string | undefined;
239
+ /** Keep only nodes whose GeoIP country is in this ISO code list. */
240
+ includeCountries: string[];
241
+ /** Drop nodes whose GeoIP country is in this ISO code list. */
242
+ excludeCountries: string[];
243
+ /** Keep only nodes matching one of these remark rules (empty keeps all). */
244
+ includeRemarks: string[];
245
+ /** Drop nodes matching one of these remark rules. */
246
+ excludeRemarks: string[];
240
247
  appendProxyType: boolean;
241
248
  nodeList: boolean;
242
249
  sortFlag: boolean;
@@ -273,6 +280,10 @@ interface RequestSettings {
273
280
  nameRemove: string[];
274
281
  includeRemarks: string[];
275
282
  excludeRemarks: string[];
283
+ /** Keep only nodes whose GeoIP country is in this ISO code list. */
284
+ includeCountries: string[];
285
+ /** Drop nodes whose GeoIP country is in this ISO code list. */
286
+ excludeCountries: string[];
276
287
  addEmoji: boolean;
277
288
  removeEmoji: boolean;
278
289
  autoCountry: boolean;
@@ -459,6 +470,8 @@ interface ExternalConfig {
459
470
  nameRemove: string[];
460
471
  includeRemarks: string[];
461
472
  excludeRemarks: string[];
473
+ includeCountries: string[];
474
+ excludeCountries: string[];
462
475
  addEmoji: boolean;
463
476
  removeEmoji: boolean;
464
477
  autoCountry: boolean;
@@ -1128,13 +1141,19 @@ declare function nodeNameRemove(node: Proxy, removeList: string[]): void;
1128
1141
  /** Apply rename rules to a node's remark (script rules are ignored). */
1129
1142
  declare function nodeRename(node: Proxy, renameArray: RegexMatchConfig[]): void;
1130
1143
  /**
1131
- * Prefix a node's remark with its server country/region when the remark does
1132
- * not already mention one (e.g. `server1` -> `美国-server1`).
1144
+ * Prefix a node's remark with its ISO server country when the remark does
1145
+ * not already mention one (e.g. `server1` -> `US-server1`).
1133
1146
  *
1134
1147
  * `resolve` returns an ISO 3166-1 alpha-2 code; a missing/unknown code leaves
1135
1148
  * the remark untouched. Mirrors the request `auto_country` switch.
1136
1149
  */
1137
- declare function addCountryPrefix(node: Proxy, resolve: (node: Proxy) => string | undefined, locale?: string): string;
1150
+ declare function addCountryPrefix(node: Proxy, resolve: (node: Proxy) => string | undefined): string;
1151
+ /**
1152
+ * Drop nodes by GeoIP country: keep only `include` codes (unknown countries
1153
+ * never match, so they are dropped), then drop `exclude` codes (unknown
1154
+ * countries are kept). Invalid codes are ignored.
1155
+ */
1156
+ declare function filterNodesByCountry(nodes: Proxy[], resolve: ((node: Proxy) => string | undefined) | undefined, include: string[], exclude: string[]): void;
1138
1157
  interface PreprocessOptions {
1139
1158
  removeEmoji: boolean;
1140
1159
  addEmoji: boolean;
@@ -1146,8 +1165,15 @@ interface PreprocessOptions {
1146
1165
  /** Literal fragments stripped from names before every other naming rule. */
1147
1166
  nameRemove?: string[];
1148
1167
  autoCountry?: boolean;
1149
- countryLocale?: string;
1150
1168
  countryResolver?: (node: Proxy) => string | undefined;
1169
+ /** Keep only nodes whose GeoIP country is in this ISO code list. */
1170
+ includeCountries?: string[];
1171
+ /** Drop nodes whose GeoIP country is in this ISO code list. */
1172
+ excludeCountries?: string[];
1173
+ /** Keep only nodes matching one of these remark rules (empty keeps all). */
1174
+ includeRemarks?: string[];
1175
+ /** Drop nodes matching one of these remark rules. */
1176
+ excludeRemarks?: string[];
1151
1177
  }
1152
1178
  /** Apply name cleanup, emoji removal, renaming, emoji insertion, and optional sorting. */
1153
1179
  declare function preprocessNodes(nodes: Proxy[], options: PreprocessOptions): void;
@@ -1155,16 +1181,18 @@ declare function preprocessNodes(nodes: Proxy[], options: PreprocessOptions): vo
1155
1181
  declare function dedupeNodes(nodes: Proxy[]): number;
1156
1182
 
1157
1183
  /**
1158
- * ISO 3166-1 alpha-2 region helpers used when a proxy name has no country.
1184
+ * ISO 3166-1 alpha-2 region helpers.
1159
1185
  *
1160
- * The display names come from `Intl.DisplayNames` (no bundled database), with
1161
- * small overrides where the CLDR Chinese name is too verbose for a node name
1162
- * (e.g. `中国香港特别行政区` -> `香港`). Flag emoji are derived from the code.
1186
+ * Emitted prefixes are always the uppercase ISO code (`US-server1`) so node
1187
+ * names stay stable across locales. Multilingual names (Chinese/English
1188
+ * spellings, flag emoji) are only recognized by `hasRegionName` so existing
1189
+ * names are never double-prefixed.
1190
+ */
1191
+ /**
1192
+ * Normalize user input to an ISO 3166-1 alpha-2 code (`"us"` -> `"US"`),
1193
+ * or `undefined` when it is not a known region. Used for country filters.
1163
1194
  */
1164
- /** Localized country/region name (e.g. `美国`), falling back to the code. */
1165
- declare function regionDisplayName(code: string, locale?: string): string;
1166
- /** Flag emoji for a region code, or `""` when the code is invalid. */
1167
- declare function regionFlag(code: string): string;
1195
+ declare function normalizeCountryCode(code: string): string | undefined;
1168
1196
  /** `true` when the code is a known ISO 3166-1 alpha-2 region. */
1169
1197
  declare function isRegionCode(code: string): boolean;
1170
1198
  /**
@@ -1174,9 +1202,10 @@ declare function isRegionCode(code: string): boolean;
1174
1202
  */
1175
1203
  declare function hasRegionName(remark: string): boolean;
1176
1204
  /**
1177
- * Prepend `name-` to a node remark (e.g. `server1` -> `美国-server1`).
1178
- * An empty remark becomes just the country name.
1205
+ * Prefix a remark with the ISO country code (e.g. `server1` -> `US-server1`).
1206
+ * An empty remark becomes just the code. Invalid codes leave the remark
1207
+ * unchanged.
1179
1208
  */
1180
- declare function formatCountryRemark(remark: string, code: string, locale?: string): string;
1209
+ declare function formatCountryRemark(remark: string, code: string): string;
1181
1210
 
1182
- export { BalanceStrategy, CLASH_RULE_TYPES, DEFAULT_GROUPS, type ExternalConfig, type ExtraSettings, type GenerateOptions, type IniDocument, type IniSection, type LoonOptions, type MellowOptions, type Proxy, type ProxyGroupConfig, ProxyGroupType, ProxyType, QUANX_RULE_TYPES, type QuanOptions, type QuanxOptions, type RawIniSection, type RegexMatchConfig, type RequestSettings, type RulesetConfig, type RulesetContent, RulesetType, SING_BOX_RULE_TYPES, SSR_CIPHERS, SS_CIPHERS, SURF_RULE_TYPES, SURGE2_RULE_TYPES, SURGE_RULE_TYPES, type SingBoxOptions, type SingBoxRoute, type SurfboardOptions, type SurgeRulesetResult, TargetFormat, type TemplateVars, type TriBool, type UserinfoData, type UserinfoProvider, addCountryPrefix, addEmoji, anyTlsConstruct, applyMatcher, base64Decode, base64Encode, buildClash, checkIgnore, convertRuleset, convertUserinfo, countOccurrences, createExtraSettings, createProxy, createProxyGroupConfig, createRequestSettings, createRulesetConfig, createSelectGroup, dedupeNodes, explode, explodeAnyTls, explodeClash, explodeHttp, explodeHttpSub, explodeHysteria2, explodeKitsunebi, explodeNetch, explodeNetchConf, explodeQuan, explodeShadowrocket, explodeSocks, explodeSs, explodeSsAndroid, explodeSsConf, explodeSsd, explodeSsr, explodeSsrConf, explodeSstap, explodeStdVmess, explodeSub, explodeSurge, explodeTrojan, explodeTuic, explodeVless, explodeVmess, explodeVmessConf, filterNodes, findSection, fnv1a64, fnv1a64Hex, formatCountryRemark, formatSingBoxInterval, formatSubscriptionUserinfo, generate, generatePeer, getAllUrlArgs, getDefaultProxyGroups, getDefaultRulesetConfigs, getDefaultRulesets, getSectionItems, getUrlArg, groupGenerate, hasRegionName, hasTemplatePlaceholders, httpConstruct, hysteria2Construct, hysteriaConstruct, inferUserinfoProviderFromUrl, isBlank, isFlattenableSsr, isIp, isIpv4, isIpv6, isLink, isRegionCode, isSsCipher, matchRange, nextMonthlyResetTimestamp, nodeNameRegex, nodeNameRemove, nodeRename, normalizeQueryKey, normalizeUserinfoProvider, pad2, parseClashText, parseConfContent, parseCustomProxyGroup, parseExternalConfig, parseGroupTimes, parseIni, parseJmsUserinfo, parseLink, parsePeers, parseProxyGroupType, parseRawIni, parseRegexMatch, parseRequestSettings, parseRulesetConfig, parseSubscription, parseSubscriptionUserinfo, parseTriBool, preprocessNodes, processRemark, proxyToSingle, proxyToSsSub, proxyToSsd, proxyTypeName, queryBoolFlag, regMatch, regReplace, regionDisplayName, regionFlag, removeEmoji, renderRawIni, renderTemplate, replaceAllDistinct, resolveNewFieldName, rulesetToClashRules, rulesetToSingBoxRules, rulesetToSurgeRules, runPreprocess, setRawSection, snellConstruct, socksConstruct, split, splitUrl, ssConstruct, ssLinkConstruct, ssrConstruct, ssrLinkConstruct, startsWith, strFind, stringifyClash, stripScheme, templateVariableNames, toBool, toClash, toInt, toLoon, toMellow, toQuan, toQuanX, toSingBox, toSip008, toSurfboard, toSurge, transformRuleToCommon, triBoolOr, trim, trimLowerCase, trojanConstruct, trojanLinkConstruct, tryBase64Decode, tuicConstruct, urlDecode, urlEncode, urlSafeBase64Decode, urlSafeBase64Encode, utf8Decode, utf8Encode, vlessConstruct, vmessConstruct, vmessLinkConstruct, wireGuardConstruct };
1211
+ export { BalanceStrategy, CLASH_RULE_TYPES, DEFAULT_GROUPS, type ExternalConfig, type ExtraSettings, type GenerateOptions, type IniDocument, type IniSection, type LoonOptions, type MellowOptions, type Proxy, type ProxyGroupConfig, ProxyGroupType, ProxyType, QUANX_RULE_TYPES, type QuanOptions, type QuanxOptions, type RawIniSection, type RegexMatchConfig, type RequestSettings, type RulesetConfig, type RulesetContent, RulesetType, SING_BOX_RULE_TYPES, SSR_CIPHERS, SS_CIPHERS, SURF_RULE_TYPES, SURGE2_RULE_TYPES, SURGE_RULE_TYPES, type SingBoxOptions, type SingBoxRoute, type SurfboardOptions, type SurgeRulesetResult, TargetFormat, type TemplateVars, type TriBool, type UserinfoData, type UserinfoProvider, addCountryPrefix, addEmoji, anyTlsConstruct, applyMatcher, base64Decode, base64Encode, buildClash, checkIgnore, convertRuleset, convertUserinfo, countOccurrences, createExtraSettings, createProxy, createProxyGroupConfig, createRequestSettings, createRulesetConfig, createSelectGroup, dedupeNodes, explode, explodeAnyTls, explodeClash, explodeHttp, explodeHttpSub, explodeHysteria2, explodeKitsunebi, explodeNetch, explodeNetchConf, explodeQuan, explodeShadowrocket, explodeSocks, explodeSs, explodeSsAndroid, explodeSsConf, explodeSsd, explodeSsr, explodeSsrConf, explodeSstap, explodeStdVmess, explodeSub, explodeSurge, explodeTrojan, explodeTuic, explodeVless, explodeVmess, explodeVmessConf, filterNodes, filterNodesByCountry, findSection, fnv1a64, fnv1a64Hex, formatCountryRemark, formatSingBoxInterval, formatSubscriptionUserinfo, generate, generatePeer, getAllUrlArgs, getDefaultProxyGroups, getDefaultRulesetConfigs, getDefaultRulesets, getSectionItems, getUrlArg, groupGenerate, hasRegionName, hasTemplatePlaceholders, httpConstruct, hysteria2Construct, hysteriaConstruct, inferUserinfoProviderFromUrl, isBlank, isFlattenableSsr, isIp, isIpv4, isIpv6, isLink, isRegionCode, isSsCipher, matchRange, nextMonthlyResetTimestamp, nodeNameRegex, nodeNameRemove, nodeRename, normalizeCountryCode, normalizeQueryKey, normalizeUserinfoProvider, pad2, parseClashText, parseConfContent, parseCustomProxyGroup, parseExternalConfig, parseGroupTimes, parseIni, parseJmsUserinfo, parseLink, parsePeers, parseProxyGroupType, parseRawIni, parseRegexMatch, parseRequestSettings, parseRulesetConfig, parseSubscription, parseSubscriptionUserinfo, parseTriBool, preprocessNodes, processRemark, proxyToSingle, proxyToSsSub, proxyToSsd, proxyTypeName, queryBoolFlag, regMatch, regReplace, removeEmoji, renderRawIni, renderTemplate, replaceAllDistinct, resolveNewFieldName, rulesetToClashRules, rulesetToSingBoxRules, rulesetToSurgeRules, runPreprocess, setRawSection, snellConstruct, socksConstruct, split, splitUrl, ssConstruct, ssLinkConstruct, ssrConstruct, ssrLinkConstruct, startsWith, strFind, stringifyClash, stripScheme, templateVariableNames, toBool, toClash, toInt, toLoon, toMellow, toQuan, toQuanX, toSingBox, toSip008, toSurfboard, toSurge, transformRuleToCommon, triBoolOr, trim, trimLowerCase, trojanConstruct, trojanLinkConstruct, tryBase64Decode, tuicConstruct, urlDecode, urlEncode, urlSafeBase64Decode, urlSafeBase64Encode, utf8Decode, utf8Encode, vlessConstruct, vmessConstruct, vmessLinkConstruct, wireGuardConstruct };
package/dist/index.js CHANGED
@@ -251,12 +251,15 @@ function createExtraSettings() {
251
251
  clashProxiesStyle: "flow",
252
252
  clashProxyGroupsStyle: "flow",
253
253
  clashScript: false,
254
- countryLocale: "zh-CN",
255
254
  countryResolver: void 0,
256
255
  dedupe: false,
257
256
  emojiArray: [],
258
257
  enableRuleGenerator: true,
258
+ excludeCountries: [],
259
+ excludeRemarks: [],
259
260
  filterDeprecated: false,
261
+ includeCountries: [],
262
+ includeRemarks: [],
260
263
  managedConfigPrefix: "",
261
264
  nameRegexArray: [],
262
265
  nameRemove: [],
@@ -742,8 +745,10 @@ function parseExternalConfig(content) {
742
745
  baseFiles: {},
743
746
  emoji: [],
744
747
  enableRuleGenerator: true,
748
+ excludeCountries: [],
745
749
  excludeRemarks: [],
746
750
  groups: [],
751
+ includeCountries: [],
747
752
  includeRemarks: [],
748
753
  nameRegex: [],
749
754
  nameRemove: [],
@@ -812,6 +817,22 @@ function parseExternalConfig(content) {
812
817
  result.includeRemarks.push(value);
813
818
  }
814
819
  break;
820
+ case "include_country":
821
+ for (const fragment of value.split(",")) {
822
+ const trimmed = fragment.trim().toUpperCase();
823
+ if (trimmed !== "") {
824
+ result.includeCountries.push(trimmed);
825
+ }
826
+ }
827
+ break;
828
+ case "exclude_country":
829
+ for (const fragment of value.split(",")) {
830
+ const trimmed = fragment.trim().toUpperCase();
831
+ if (trimmed !== "") {
832
+ result.excludeCountries.push(trimmed);
833
+ }
834
+ }
835
+ break;
815
836
  case "exclude_remarks":
816
837
  case "exclude":
817
838
  if (value !== "") {
@@ -866,6 +887,9 @@ function listArg(query, key) {
866
887
  const value = getUrlArg(query, key);
867
888
  return value === "" ? [] : value.split(",");
868
889
  }
890
+ function countryListArg(query, key) {
891
+ return getAllUrlArgs(query, key).flatMap((raw) => raw.split(",")).map((raw) => raw.trim().toUpperCase()).filter((raw) => raw !== "");
892
+ }
869
893
  function resolveNewFieldName(query) {
870
894
  if (boolArg(query, "legacy") || boolArg(query, "legacy_field_name") || boolArg(query, "legacy-field-name")) {
871
895
  return false;
@@ -908,9 +932,11 @@ function createRequestSettings() {
908
932
  classicalRuleset: false,
909
933
  dedupe: false,
910
934
  emoji: [],
935
+ excludeCountries: [],
911
936
  excludeRemarks: [],
912
937
  filterDeprecated: false,
913
938
  group: [],
939
+ includeCountries: [],
914
940
  includeRemarks: [],
915
941
  insert: false,
916
942
  interval: 0,
@@ -971,6 +997,8 @@ function parseRequestSettings(query) {
971
997
  settings.proxyGroupsStyle = getUrlArg(query, "proxy_groups_style") || "flow";
972
998
  settings.includeRemarks = listArg(query, "include");
973
999
  settings.excludeRemarks = listArg(query, "exclude");
1000
+ settings.includeCountries = countryListArg(query, "include_country");
1001
+ settings.excludeCountries = countryListArg(query, "exclude_country");
974
1002
  settings.userinfoUrl = firstArg(query, "userinfo_url", "userinfo-url", "userinfo");
975
1003
  settings.userinfoProvider = firstArg(
976
1004
  query,
@@ -4916,7 +4944,11 @@ function normalizeRegionCode(code) {
4916
4944
  const upper = code.trim().toUpperCase();
4917
4945
  return /^[A-Z]{2}$/.test(upper) ? upper : "";
4918
4946
  }
4919
- function regionDisplayName(code, locale = "zh-CN") {
4947
+ function normalizeCountryCode(code) {
4948
+ const upper = normalizeRegionCode(code);
4949
+ return upper !== "" && isRegionCode(upper) ? upper : void 0;
4950
+ }
4951
+ function displayName(code, locale) {
4920
4952
  const upper = normalizeRegionCode(code);
4921
4953
  if (upper === "") {
4922
4954
  return code.trim();
@@ -4959,8 +4991,8 @@ function buildAliasRegex() {
4959
4991
  }
4960
4992
  };
4961
4993
  for (const code of REGION_CODES) {
4962
- add(regionDisplayName(code, "zh-CN"));
4963
- add(regionDisplayName(code, "en"));
4994
+ add(displayName(code, "zh-CN"));
4995
+ add(displayName(code, "en"));
4964
4996
  add(regionFlag(code));
4965
4997
  }
4966
4998
  for (const alias of EXTRA_ALIASES) {
@@ -5000,13 +5032,13 @@ function hasRegionName(remark) {
5000
5032
  }
5001
5033
  return false;
5002
5034
  }
5003
- function formatCountryRemark(remark, code, locale = "zh-CN") {
5004
- const name = regionDisplayName(code, locale);
5035
+ function formatCountryRemark(remark, code) {
5036
+ const normalized = normalizeCountryCode(code);
5005
5037
  const trimmed = remark.trim();
5006
- if (name === "") {
5038
+ if (normalized === void 0) {
5007
5039
  return trimmed;
5008
5040
  }
5009
- return trimmed === "" ? name : `${name}-${trimmed}`;
5041
+ return trimmed === "" ? normalized : `${normalized}-${trimmed}`;
5010
5042
  }
5011
5043
 
5012
5044
  // src/generator/nodes.ts
@@ -5265,7 +5297,7 @@ function nodeRename(node, renameArray) {
5265
5297
  node.remark = original;
5266
5298
  }
5267
5299
  }
5268
- function addCountryPrefix(node, resolve, locale = "zh-CN") {
5300
+ function addCountryPrefix(node, resolve) {
5269
5301
  const remark = node.remark.trim();
5270
5302
  if (hasRegionName(remark)) {
5271
5303
  return node.remark;
@@ -5274,7 +5306,31 @@ function addCountryPrefix(node, resolve, locale = "zh-CN") {
5274
5306
  if (code === void 0 || code === "") {
5275
5307
  return node.remark;
5276
5308
  }
5277
- return formatCountryRemark(remark, code, locale);
5309
+ return formatCountryRemark(remark, code);
5310
+ }
5311
+ function filterNodesByCountry(nodes, resolve, include, exclude) {
5312
+ const includeSet = new Set(
5313
+ include.map((code) => normalizeCountryCode(code)).filter((code) => code !== void 0)
5314
+ );
5315
+ const excludeSet = new Set(
5316
+ exclude.map((code) => normalizeCountryCode(code)).filter((code) => code !== void 0)
5317
+ );
5318
+ if (includeSet.size === 0 && excludeSet.size === 0) {
5319
+ return;
5320
+ }
5321
+ const kept = [];
5322
+ for (const node of nodes) {
5323
+ const code = resolve ? normalizeCountryCode(resolve(node) ?? "") : void 0;
5324
+ if (includeSet.size > 0 && (code === void 0 || !includeSet.has(code))) {
5325
+ continue;
5326
+ }
5327
+ if (code !== void 0 && excludeSet.has(code)) {
5328
+ continue;
5329
+ }
5330
+ kept.push(node);
5331
+ }
5332
+ nodes.length = 0;
5333
+ nodes.push(...kept);
5278
5334
  }
5279
5335
  function preprocessNodes(nodes, options) {
5280
5336
  for (const node of nodes) {
@@ -5292,13 +5348,25 @@ function preprocessNodes(nodes, options) {
5292
5348
  node.remark = addEmoji(node, options.emojiArray);
5293
5349
  }
5294
5350
  if (options.autoCountry && options.countryResolver) {
5295
- node.remark = addCountryPrefix(
5296
- node,
5297
- options.countryResolver,
5298
- options.countryLocale ?? "zh-CN"
5299
- );
5351
+ node.remark = addCountryPrefix(node, options.countryResolver);
5300
5352
  }
5301
5353
  }
5354
+ filterNodesByCountry(
5355
+ nodes,
5356
+ options.countryResolver,
5357
+ options.includeCountries ?? [],
5358
+ options.excludeCountries ?? []
5359
+ );
5360
+ const includeRemarks = options.includeRemarks ?? [];
5361
+ const excludeRemarks = options.excludeRemarks ?? [];
5362
+ if (includeRemarks.length > 0 || excludeRemarks.length > 0) {
5363
+ const kept = nodes.filter((node) => !checkIgnore(node, excludeRemarks, includeRemarks));
5364
+ kept.forEach((node, index) => {
5365
+ node.id = index;
5366
+ });
5367
+ nodes.length = 0;
5368
+ nodes.push(...kept);
5369
+ }
5302
5370
  if (options.sortFlag) {
5303
5371
  nodes.sort((a, b) => a.remark < b.remark ? -1 : a.remark > b.remark ? 1 : 0);
5304
5372
  }
@@ -8184,9 +8252,12 @@ function runPreprocess(nodes, settings) {
8184
8252
  preprocessNodes(nodes, {
8185
8253
  addEmoji: settings.addEmoji,
8186
8254
  autoCountry: settings.autoCountry,
8187
- countryLocale: settings.countryLocale,
8188
8255
  countryResolver: settings.countryResolver,
8189
8256
  emojiArray: settings.emojiArray,
8257
+ excludeCountries: settings.excludeCountries,
8258
+ excludeRemarks: settings.excludeRemarks,
8259
+ includeCountries: settings.includeCountries,
8260
+ includeRemarks: settings.includeRemarks,
8190
8261
  nameRegexArray: settings.nameRegexArray,
8191
8262
  nameRemove: settings.nameRemove,
8192
8263
  removeEmoji: settings.removeEmoji,
@@ -8388,6 +8459,7 @@ export {
8388
8459
  explodeVmess,
8389
8460
  explodeVmessConf,
8390
8461
  filterNodes,
8462
+ filterNodesByCountry,
8391
8463
  findSection,
8392
8464
  fnv1a64,
8393
8465
  fnv1a64Hex,
@@ -8422,6 +8494,7 @@ export {
8422
8494
  nodeNameRegex,
8423
8495
  nodeNameRemove,
8424
8496
  nodeRename,
8497
+ normalizeCountryCode,
8425
8498
  normalizeQueryKey,
8426
8499
  normalizeUserinfoProvider,
8427
8500
  pad2,
@@ -8451,8 +8524,6 @@ export {
8451
8524
  queryBoolFlag,
8452
8525
  regMatch,
8453
8526
  regReplace,
8454
- regionDisplayName,
8455
- regionFlag,
8456
8527
  removeEmoji,
8457
8528
  renderRawIni,
8458
8529
  renderTemplate,