lua-cli 3.23.2 → 3.25.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/api-exports.d.ts +173 -11
- package/dist/api-exports.js +158 -13
- package/dist/api-exports.js.map +1 -1
- package/dist/index.js +176 -15
- package/dist/index.js.map +1 -1
- package/docs/README.md +2 -2
- package/package.json +1 -1
- package/template/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1146,6 +1146,9 @@ function isDesktopFileCommandName(value) {
|
|
|
1146
1146
|
function isDesktopFileSessionId(value) {
|
|
1147
1147
|
return typeof value === "string" && /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);
|
|
1148
1148
|
}
|
|
1149
|
+
function isImplicitModelSelectionSource(source) {
|
|
1150
|
+
return source !== void 0 && IMPLICIT_MODEL_SELECTION_SOURCES.includes(source);
|
|
1151
|
+
}
|
|
1149
1152
|
function resolveRequireToolApproval(rules) {
|
|
1150
1153
|
const raw = rules?.requireToolApproval ?? rules?.requireApproval;
|
|
1151
1154
|
if (raw === void 0 || raw === null) return void 0;
|
|
@@ -1173,7 +1176,7 @@ function normalizeLuaJobExecutionTimeoutSeconds(timeout) {
|
|
|
1173
1176
|
}
|
|
1174
1177
|
return Math.min(Math.max(timeout, LUA_JOB_MIN_TIMEOUT_SECONDS), LUA_JOB_MAX_TIMEOUT_SECONDS);
|
|
1175
1178
|
}
|
|
1176
|
-
var __defProp2, __name2, REVIEWABLE_ACTION_EXECUTE_TOOL_ALLOWLIST, REVIEWABLE_MCP_SEND_TOOL_SUFFIX, MCP_TOOL_READ_VERB_RE, MCP_DRAFT_CREATE_VERBS, NON_INTERACTIVE_CHANNELS, RICH_PARTS_MESSAGE_ID_PREFIX, SCREENSHOT_MESSAGE_ID_PREFIX, BROWSER_COMMANDS, BROWSER_COMMAND_NAMES, DESKTOP_FILE_COMMANDS, DESKTOP_FILE_COMMAND_SET, REASONING_EFFORT_VALUES, AGENT_NAME_TOKEN, DEFAULT_PERSONA_GUIDE, AGENT_LOG_SOURCES, VoiceNameSchema, PluginProviderSchema, RealtimeProviderSchema, PluginClassSchema, ModelDescriptorSchema, InferenceModelSchema, PluginModelSchema, RealtimeModelSchema, LuaVoiceModelSchema, TurnDetectionSchema, InterruptionSchema, BuiltinAudioClipSchema, AudioConfigSchema, BackgroundAudioEntrySchema, BackgroundAudioSchema, LuaVoiceConfigInnerSchema, LuaVoiceConfigSchema, LuaVoiceRefSchema, LUA_JOB_DEFAULT_TIMEOUT_SECONDS, LUA_JOB_MIN_TIMEOUT_SECONDS, LUA_JOB_MAX_TIMEOUT_SECONDS;
|
|
1179
|
+
var __defProp2, __name2, REVIEWABLE_ACTION_EXECUTE_TOOL_ALLOWLIST, REVIEWABLE_MCP_SEND_TOOL_SUFFIX, MCP_TOOL_READ_VERB_RE, MCP_DRAFT_CREATE_VERBS, NON_INTERACTIVE_CHANNELS, RICH_PARTS_MESSAGE_ID_PREFIX, SCREENSHOT_MESSAGE_ID_PREFIX, BROWSER_COMMANDS, BROWSER_COMMAND_NAMES, DESKTOP_FILE_COMMANDS, DESKTOP_FILE_COMMAND_SET, REASONING_EFFORT_VALUES, IMPLICIT_MODEL_SELECTION_SOURCES, AGENT_NAME_TOKEN, DEFAULT_PERSONA_GUIDE, AGENT_LOG_SOURCES, VoiceNameSchema, PluginProviderSchema, RealtimeProviderSchema, PluginClassSchema, ModelDescriptorSchema, InferenceModelSchema, PluginModelSchema, RealtimeModelSchema, LuaVoiceModelSchema, TurnDetectionSchema, InterruptionSchema, BuiltinAudioClipSchema, AudioConfigSchema, BackgroundAudioEntrySchema, BackgroundAudioSchema, LuaVoiceConfigInnerSchema, LuaVoiceConfigSchema, LuaVoiceRefSchema, LUA_JOB_DEFAULT_TIMEOUT_SECONDS, LUA_JOB_MIN_TIMEOUT_SECONDS, LUA_JOB_MAX_TIMEOUT_SECONDS;
|
|
1177
1180
|
var init_dist = __esm({
|
|
1178
1181
|
"../shared-types/dist/index.mjs"() {
|
|
1179
1182
|
"use strict";
|
|
@@ -1487,6 +1490,12 @@ var init_dist = __esm({
|
|
|
1487
1490
|
"high",
|
|
1488
1491
|
"max"
|
|
1489
1492
|
];
|
|
1493
|
+
IMPLICIT_MODEL_SELECTION_SOURCES = [
|
|
1494
|
+
"workspace-default",
|
|
1495
|
+
"platform-default"
|
|
1496
|
+
];
|
|
1497
|
+
__name(isImplicitModelSelectionSource, "isImplicitModelSelectionSource");
|
|
1498
|
+
__name2(isImplicitModelSelectionSource, "isImplicitModelSelectionSource");
|
|
1490
1499
|
__name(resolveRequireToolApproval, "resolveRequireToolApproval");
|
|
1491
1500
|
__name2(resolveRequireToolApproval, "resolveRequireToolApproval");
|
|
1492
1501
|
AGENT_NAME_TOKEN = "[Your Agent Name]";
|
|
@@ -7588,7 +7597,8 @@ var init_agent_plugin = __esm({
|
|
|
7588
7597
|
const isDefaultExport = classDecl.isDefaultExport();
|
|
7589
7598
|
const exportName = isDefaultExport ? "default" : className;
|
|
7590
7599
|
const name = readStringMember(classDecl, "name") ?? deriveNameFromClassName(className);
|
|
7591
|
-
const
|
|
7600
|
+
const routingDescription = readStringMember(classDecl, "description");
|
|
7601
|
+
const baseDescription = routingDescription ?? "";
|
|
7592
7602
|
const personaHit = findClassMember(classDecl, "persona", "property");
|
|
7593
7603
|
let persona = "";
|
|
7594
7604
|
if (personaHit && Node13.isPropertyDeclaration(personaHit.node)) {
|
|
@@ -7639,6 +7649,7 @@ var init_agent_plugin = __esm({
|
|
|
7639
7649
|
metadata: {
|
|
7640
7650
|
pattern: "class-definition",
|
|
7641
7651
|
persona,
|
|
7652
|
+
routingDescription,
|
|
7642
7653
|
model,
|
|
7643
7654
|
hasModelResolver,
|
|
7644
7655
|
modelSettings,
|
|
@@ -7671,6 +7682,7 @@ var init_agent_plugin = __esm({
|
|
|
7671
7682
|
"voice",
|
|
7672
7683
|
"text"
|
|
7673
7684
|
]) ?? "";
|
|
7685
|
+
const routingDescription = extractStringProperty(config, "description");
|
|
7674
7686
|
const { model, hasModelResolver } = this.extractModelInfo(config);
|
|
7675
7687
|
const modelSettings = this.extractModelSettings(config);
|
|
7676
7688
|
const batching = this.extractBatchingInfo(config);
|
|
@@ -7688,6 +7700,7 @@ var init_agent_plugin = __esm({
|
|
|
7688
7700
|
metadata: {
|
|
7689
7701
|
pattern,
|
|
7690
7702
|
persona,
|
|
7703
|
+
routingDescription,
|
|
7691
7704
|
model,
|
|
7692
7705
|
hasModelResolver,
|
|
7693
7706
|
modelSettings,
|
|
@@ -7873,6 +7886,7 @@ var init_agent_plugin = __esm({
|
|
|
7873
7886
|
return {
|
|
7874
7887
|
...this.baseManifestFields(compiled),
|
|
7875
7888
|
persona: agentMeta.persona,
|
|
7889
|
+
routingDescription: agentMeta.routingDescription,
|
|
7876
7890
|
model: agentMeta.model,
|
|
7877
7891
|
hasModelResolver: agentMeta.hasModelResolver || void 0,
|
|
7878
7892
|
modelSettings: agentMeta.modelSettings,
|
|
@@ -12890,17 +12904,42 @@ var init_custom_data_api_service = __esm({
|
|
|
12890
12904
|
this.agentId = agentId;
|
|
12891
12905
|
}
|
|
12892
12906
|
/**
|
|
12907
|
+
* Lists the agent's data collections with entry counts, timestamps, and —
|
|
12908
|
+
* when declared — managed index status (fields, pending/building/ready/
|
|
12909
|
+
* failed/rejected, error reason). The place to diagnose index declarations.
|
|
12910
|
+
* @returns Promise resolving to the collections listing
|
|
12911
|
+
*/
|
|
12912
|
+
async collections() {
|
|
12913
|
+
const response = await this.httpGet(`/developer/agents/${this.agentId}/custom-data`, {
|
|
12914
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
12915
|
+
});
|
|
12916
|
+
if (response.success && response.data) {
|
|
12917
|
+
return response.data;
|
|
12918
|
+
}
|
|
12919
|
+
throw new Error(response.error?.message || "Failed to list custom data collections");
|
|
12920
|
+
}
|
|
12921
|
+
/**
|
|
12893
12922
|
* Creates a new custom data entry in a specified collection
|
|
12894
12923
|
* @param collectionName - The name of the collection to create the entry in
|
|
12895
12924
|
* @param data - The data object to store in the entry
|
|
12896
|
-
* @param
|
|
12925
|
+
* @param optionsOrSearchText - Either a searchText string (legacy form) or an
|
|
12926
|
+
* options object: `searchText` for semantic search indexing, and `index` to
|
|
12927
|
+
* declare data fields this agent filters on (e.g. `['business_id']` or
|
|
12928
|
+
* compounds like `[['country', 'business_id']]`). Declared fields get
|
|
12929
|
+
* agent-scoped database indexes maintained by the platform: created when
|
|
12930
|
+
* first declared, removed automatically ~14 days after the code stops
|
|
12931
|
+
* declaring them. Declaring on every write is the intended, idempotent use.
|
|
12897
12932
|
* @returns Promise resolving to a DataEntryInstance representing the created entry
|
|
12898
12933
|
* @throws Error if the entry creation fails or the API request is unsuccessful
|
|
12899
12934
|
*/
|
|
12900
|
-
async create(collectionName, data,
|
|
12935
|
+
async create(collectionName, data, optionsOrSearchText) {
|
|
12936
|
+
const options = typeof optionsOrSearchText === "string" ? {
|
|
12937
|
+
searchText: optionsOrSearchText
|
|
12938
|
+
} : optionsOrSearchText ?? {};
|
|
12901
12939
|
const response = await this.httpPost(`/developer/agents/${this.agentId}/custom-data/${collectionName}`, {
|
|
12902
12940
|
data,
|
|
12903
|
-
searchText
|
|
12941
|
+
searchText: options.searchText,
|
|
12942
|
+
index: options.index
|
|
12904
12943
|
}, {
|
|
12905
12944
|
Authorization: `Bearer ${this.apiKey}`
|
|
12906
12945
|
});
|
|
@@ -12953,14 +12992,19 @@ var init_custom_data_api_service = __esm({
|
|
|
12953
12992
|
* @param collectionName - The name of the collection containing the entry
|
|
12954
12993
|
* @param entryId - The unique identifier of the entry to update
|
|
12955
12994
|
* @param data - The data object to update
|
|
12956
|
-
* @param
|
|
12995
|
+
* @param optionsOrSearchText - searchText string (legacy) or { searchText?, index? };
|
|
12996
|
+
* `index` refreshes this agent's index declarations (same semantics as create)
|
|
12957
12997
|
* @returns Promise resolving to an UpdateCustomDataResponse with the updated entry details
|
|
12958
12998
|
* @throws Error if the entry is not found or the update fails
|
|
12959
12999
|
*/
|
|
12960
|
-
async update(collectionName, entryId, data,
|
|
13000
|
+
async update(collectionName, entryId, data, optionsOrSearchText) {
|
|
13001
|
+
const options = typeof optionsOrSearchText === "string" ? {
|
|
13002
|
+
searchText: optionsOrSearchText
|
|
13003
|
+
} : optionsOrSearchText ?? {};
|
|
12961
13004
|
const response = await this.httpPut(`/developer/agents/${this.agentId}/custom-data/${collectionName}/${entryId}`, {
|
|
12962
13005
|
data,
|
|
12963
|
-
searchText
|
|
13006
|
+
searchText: options.searchText,
|
|
13007
|
+
index: options.index
|
|
12964
13008
|
}, {
|
|
12965
13009
|
Authorization: `Bearer ${this.apiKey}`
|
|
12966
13010
|
});
|
|
@@ -13648,6 +13692,31 @@ var init_channels_send_api_service = __esm({
|
|
|
13648
13692
|
}
|
|
13649
13693
|
});
|
|
13650
13694
|
|
|
13695
|
+
// src/api/inbox-push.api.service.ts
|
|
13696
|
+
var InboxPushApiService;
|
|
13697
|
+
var init_inbox_push_api_service = __esm({
|
|
13698
|
+
"src/api/inbox-push.api.service.ts"() {
|
|
13699
|
+
"use strict";
|
|
13700
|
+
init_http_client();
|
|
13701
|
+
InboxPushApiService = class extends HttpClient {
|
|
13702
|
+
static {
|
|
13703
|
+
__name(this, "InboxPushApiService");
|
|
13704
|
+
}
|
|
13705
|
+
apiKey;
|
|
13706
|
+
agentId;
|
|
13707
|
+
constructor(baseUrl, apiKey, agentId) {
|
|
13708
|
+
super(baseUrl), this.apiKey = apiKey, this.agentId = agentId;
|
|
13709
|
+
}
|
|
13710
|
+
/** POST /developer/agents/:agentId/inbox/push */
|
|
13711
|
+
async push(input) {
|
|
13712
|
+
return this.httpPost(`/developer/agents/${this.agentId}/inbox/push`, input, {
|
|
13713
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
13714
|
+
});
|
|
13715
|
+
}
|
|
13716
|
+
};
|
|
13717
|
+
}
|
|
13718
|
+
});
|
|
13719
|
+
|
|
13651
13720
|
// src/api/directory.api.service.ts
|
|
13652
13721
|
var DirectoryApiService;
|
|
13653
13722
|
var init_directory_api_service = __esm({
|
|
@@ -13783,6 +13852,7 @@ __export(lazy_instances_exports, {
|
|
|
13783
13852
|
getDeveloperInstance: () => getDeveloperInstance,
|
|
13784
13853
|
getDeviceInstance: () => getDeviceInstance,
|
|
13785
13854
|
getDirectoryInstance: () => getDirectoryInstance,
|
|
13855
|
+
getInboxPushInstance: () => getInboxPushInstance,
|
|
13786
13856
|
getJobInstance: () => getJobInstance,
|
|
13787
13857
|
getOrderInstance: () => getOrderInstance,
|
|
13788
13858
|
getProductsInstance: () => getProductsInstance,
|
|
@@ -13890,6 +13960,13 @@ async function getVoiceInstance() {
|
|
|
13890
13960
|
}
|
|
13891
13961
|
return _voiceInstance;
|
|
13892
13962
|
}
|
|
13963
|
+
async function getInboxPushInstance() {
|
|
13964
|
+
if (!_inboxPushInstance) {
|
|
13965
|
+
const creds = await getCredentials();
|
|
13966
|
+
_inboxPushInstance = new InboxPushApiService(BASE_URLS.API, creds.apiKey, creds.agentId);
|
|
13967
|
+
}
|
|
13968
|
+
return _inboxPushInstance;
|
|
13969
|
+
}
|
|
13893
13970
|
async function getChannelsSendInstance() {
|
|
13894
13971
|
if (!_channelsSendInstance) {
|
|
13895
13972
|
const creds = await getCredentials();
|
|
@@ -13921,7 +13998,7 @@ function clearAllInstances() {
|
|
|
13921
13998
|
_channelsSendInstance = null;
|
|
13922
13999
|
_directoryInstance = null;
|
|
13923
14000
|
}
|
|
13924
|
-
var _userInstance, _dataInstance, _productsInstance, _basketsInstance, _orderInstance, _webhookInstance, _jobInstance, _aiInstance, _agentsInstance, _whatsAppTemplatesInstance, _cdnInstance, _developerInstance, _voiceInstance, _channelsSendInstance, _directoryInstance, _deviceInstance;
|
|
14001
|
+
var _userInstance, _dataInstance, _productsInstance, _basketsInstance, _orderInstance, _webhookInstance, _jobInstance, _aiInstance, _agentsInstance, _whatsAppTemplatesInstance, _cdnInstance, _developerInstance, _voiceInstance, _channelsSendInstance, _directoryInstance, _deviceInstance, _inboxPushInstance;
|
|
13925
14002
|
var init_lazy_instances = __esm({
|
|
13926
14003
|
"src/api/lazy-instances.ts"() {
|
|
13927
14004
|
"use strict";
|
|
@@ -13941,6 +14018,7 @@ var init_lazy_instances = __esm({
|
|
|
13941
14018
|
init_developer_api_service();
|
|
13942
14019
|
init_voice_api_service();
|
|
13943
14020
|
init_channels_send_api_service();
|
|
14021
|
+
init_inbox_push_api_service();
|
|
13944
14022
|
init_directory_api_service();
|
|
13945
14023
|
_userInstance = null;
|
|
13946
14024
|
_dataInstance = null;
|
|
@@ -13972,6 +14050,8 @@ var init_lazy_instances = __esm({
|
|
|
13972
14050
|
__name(getDeviceInstance, "getDeviceInstance");
|
|
13973
14051
|
__name(getDeveloperInstance, "getDeveloperInstance");
|
|
13974
14052
|
__name(getVoiceInstance, "getVoiceInstance");
|
|
14053
|
+
_inboxPushInstance = null;
|
|
14054
|
+
__name(getInboxPushInstance, "getInboxPushInstance");
|
|
13975
14055
|
__name(getChannelsSendInstance, "getChannelsSendInstance");
|
|
13976
14056
|
__name(getDirectoryInstance, "getDirectoryInstance");
|
|
13977
14057
|
__name(clearAllInstances, "clearAllInstances");
|
|
@@ -16939,6 +17019,29 @@ var AgentHandler = class {
|
|
|
16939
17019
|
async pushAgentConfig(apiKey, agentId, manifest) {
|
|
16940
17020
|
const result = {};
|
|
16941
17021
|
const agent = getPrimitivesByKind(manifest, PrimitiveKind.AGENT)[0];
|
|
17022
|
+
if (agent?.routingDescription !== void 0) {
|
|
17023
|
+
writeProgress("\n\u{1F9ED} Pushing routing description...");
|
|
17024
|
+
try {
|
|
17025
|
+
const success2 = await this.pushDescription({
|
|
17026
|
+
apiKey,
|
|
17027
|
+
agentId
|
|
17028
|
+
}, agent.routingDescription);
|
|
17029
|
+
result.description = {
|
|
17030
|
+
success: success2
|
|
17031
|
+
};
|
|
17032
|
+
if (success2) {
|
|
17033
|
+
writeSuccess(agent.routingDescription ? " \u2705 Routing description pushed" : " \u2705 Routing description cleared");
|
|
17034
|
+
} else {
|
|
17035
|
+
console.error(" \u274C Failed to push routing description");
|
|
17036
|
+
}
|
|
17037
|
+
} catch (error) {
|
|
17038
|
+
if (AuthenticationError.isAuthenticationError(error)) throw error;
|
|
17039
|
+
console.error(` \u274C Failed to push routing description: ${error.message}`);
|
|
17040
|
+
result.description = {
|
|
17041
|
+
success: false
|
|
17042
|
+
};
|
|
17043
|
+
}
|
|
17044
|
+
}
|
|
16942
17045
|
const persona = agent?.persona;
|
|
16943
17046
|
if (hasPersonaTextContent(persona)) {
|
|
16944
17047
|
writeProgress("\n\u{1F319} Pushing persona...");
|
|
@@ -17163,6 +17266,13 @@ var AgentHandler = class {
|
|
|
17163
17266
|
});
|
|
17164
17267
|
return result.success;
|
|
17165
17268
|
}
|
|
17269
|
+
async pushDescription(ctx, description) {
|
|
17270
|
+
const agentApi = new AgentApi(BASE_URLS.API, ctx.apiKey);
|
|
17271
|
+
const result = await agentApi.updateAgent(ctx.agentId, {
|
|
17272
|
+
description
|
|
17273
|
+
});
|
|
17274
|
+
return result.success;
|
|
17275
|
+
}
|
|
17166
17276
|
async pushPersona(ctx, persona) {
|
|
17167
17277
|
const personaApi = new PersonaApi(BASE_URLS.API, ctx.apiKey, ctx.agentId);
|
|
17168
17278
|
const result = await personaApi.createVersion(persona);
|
|
@@ -20723,6 +20833,14 @@ var DEFAULT_BLOCK_CIDRS = [
|
|
|
20723
20833
|
"fe80::/10",
|
|
20724
20834
|
"fc00::/7"
|
|
20725
20835
|
];
|
|
20836
|
+
var HOSTNAME_NON_OVERRIDABLE_CIDRS = [
|
|
20837
|
+
"127.0.0.0/8",
|
|
20838
|
+
"169.254.0.0/16",
|
|
20839
|
+
"0.0.0.0/8",
|
|
20840
|
+
"::1/128",
|
|
20841
|
+
"fe80::/10",
|
|
20842
|
+
"fd00:ec2::254/128"
|
|
20843
|
+
];
|
|
20726
20844
|
function ipv4ToInt(ip) {
|
|
20727
20845
|
const parts = ip.split(".").map(Number);
|
|
20728
20846
|
if (parts.length !== 4 || parts.some((n) => Number.isNaN(n) || n < 0 || n > 255)) {
|
|
@@ -20824,24 +20942,50 @@ function ipInCidr(ip, cidrs) {
|
|
|
20824
20942
|
}
|
|
20825
20943
|
__name(ipInCidr, "ipInCidr");
|
|
20826
20944
|
__name4(ipInCidr, "ipInCidr");
|
|
20945
|
+
function normalizeHostname(hostname) {
|
|
20946
|
+
return stripBrackets(hostname.trim()).toLowerCase().replace(/\.$/, "");
|
|
20947
|
+
}
|
|
20948
|
+
__name(normalizeHostname, "normalizeHostname");
|
|
20949
|
+
__name4(normalizeHostname, "normalizeHostname");
|
|
20950
|
+
function parseAllowedHostname(value) {
|
|
20951
|
+
const hostname = normalizeHostname(value);
|
|
20952
|
+
if (!hostname || net.isIP(hostname) || /[\s*/:\\?#]/.test(hostname)) {
|
|
20953
|
+
throw new Error(`Invalid sandbox egress hostname allowlist entry: ${JSON.stringify(value)}. Use an exact hostname without a wildcard, URL, port, or IP literal.`);
|
|
20954
|
+
}
|
|
20955
|
+
return hostname;
|
|
20956
|
+
}
|
|
20957
|
+
__name(parseAllowedHostname, "parseAllowedHostname");
|
|
20958
|
+
__name4(parseAllowedHostname, "parseAllowedHostname");
|
|
20827
20959
|
function compile2(opts) {
|
|
20828
20960
|
return {
|
|
20829
20961
|
blockCidrs: DEFAULT_BLOCK_CIDRS.map(parseCidr),
|
|
20830
20962
|
allowCidrs: (opts.extraAllowedCidrs ?? []).map(parseCidr),
|
|
20963
|
+
allowHostnames: new Set((opts.extraAllowedHostnames ?? []).map(parseAllowedHostname)),
|
|
20964
|
+
hostnameNonOverridableCidrs: HOSTNAME_NON_OVERRIDABLE_CIDRS.map(parseCidr),
|
|
20831
20965
|
mode: opts.mode,
|
|
20832
20966
|
onEvent: opts.onSecurityEvent
|
|
20833
20967
|
};
|
|
20834
20968
|
}
|
|
20835
20969
|
__name(compile2, "compile");
|
|
20836
20970
|
__name4(compile2, "compile");
|
|
20837
|
-
function
|
|
20838
|
-
|
|
20971
|
+
function isAllowedHostname(hostname, guard) {
|
|
20972
|
+
return !net.isIP(hostname) && guard.allowHostnames.has(normalizeHostname(hostname));
|
|
20973
|
+
}
|
|
20974
|
+
__name(isAllowedHostname, "isAllowedHostname");
|
|
20975
|
+
__name4(isAllowedHostname, "isAllowedHostname");
|
|
20976
|
+
function checkAddress(address, guard, allowedByHostname = false) {
|
|
20977
|
+
const v4 = ipv4MappedFromIpv6(address);
|
|
20978
|
+
if (ipInCidr(address, guard.allowCidrs) || v4 !== null && ipInCidr(v4, guard.allowCidrs)) return null;
|
|
20979
|
+
if (allowedByHostname) {
|
|
20980
|
+
if (ipInCidr(address, guard.hostnameNonOverridableCidrs) || v4 !== null && ipInCidr(v4, guard.hostnameNonOverridableCidrs)) {
|
|
20981
|
+
return `address ${address} is protected from sandbox hostname allowances`;
|
|
20982
|
+
}
|
|
20983
|
+
return null;
|
|
20984
|
+
}
|
|
20839
20985
|
if (ipInCidr(address, guard.blockCidrs)) {
|
|
20840
20986
|
return `address ${address} is in the sandbox egress block list`;
|
|
20841
20987
|
}
|
|
20842
|
-
const v4 = ipv4MappedFromIpv6(address);
|
|
20843
20988
|
if (v4) {
|
|
20844
|
-
if (ipInCidr(v4, guard.allowCidrs)) return null;
|
|
20845
20989
|
if (ipInCidr(v4, guard.blockCidrs)) {
|
|
20846
20990
|
return `address ${address} (IPv4-mapped: ${v4}) is in the sandbox egress block list`;
|
|
20847
20991
|
}
|
|
@@ -20866,8 +21010,9 @@ async function resolveAndCheck(hostname, guard) {
|
|
|
20866
21010
|
} catch {
|
|
20867
21011
|
return null;
|
|
20868
21012
|
}
|
|
21013
|
+
const allowedByHostname = isAllowedHostname(hostname, guard);
|
|
20869
21014
|
for (const { address } of addresses) {
|
|
20870
|
-
const reason = checkAddress(address, guard);
|
|
21015
|
+
const reason = checkAddress(address, guard, allowedByHostname);
|
|
20871
21016
|
if (reason) return {
|
|
20872
21017
|
reason,
|
|
20873
21018
|
address
|
|
@@ -20978,8 +21123,9 @@ function buildBlockingLookup(guard, target) {
|
|
|
20978
21123
|
}, (err, addresses) => {
|
|
20979
21124
|
if (err) return cb(err);
|
|
20980
21125
|
const list = addresses;
|
|
21126
|
+
const allowedByHostname = isAllowedHostname(hostname, guard);
|
|
20981
21127
|
for (const { address } of list) {
|
|
20982
|
-
const reason = checkAddress(address, guard);
|
|
21128
|
+
const reason = checkAddress(address, guard, allowedByHostname);
|
|
20983
21129
|
if (reason) {
|
|
20984
21130
|
emit(guard, target, reason, address);
|
|
20985
21131
|
if (guard.mode === "enforce") {
|
|
@@ -21275,6 +21421,7 @@ function createBaseSandboxContext(opts) {
|
|
|
21275
21421
|
const egressOpts = {
|
|
21276
21422
|
mode: egressMode,
|
|
21277
21423
|
extraAllowedCidrs: opts.egressExtraAllowedCidrs,
|
|
21424
|
+
extraAllowedHostnames: opts.egressExtraAllowedHostnames,
|
|
21278
21425
|
onSecurityEvent: onSecurityEvent ? (evt) => onSecurityEvent(evt) : void 0
|
|
21279
21426
|
};
|
|
21280
21427
|
const wrappedModuleCache = /* @__PURE__ */ new Map();
|
|
@@ -21338,6 +21485,13 @@ function resolveExtraAllowedCidrs() {
|
|
|
21338
21485
|
}
|
|
21339
21486
|
__name(resolveExtraAllowedCidrs, "resolveExtraAllowedCidrs");
|
|
21340
21487
|
__name4(resolveExtraAllowedCidrs, "resolveExtraAllowedCidrs");
|
|
21488
|
+
function resolveExtraAllowedHostnames() {
|
|
21489
|
+
const csv = process.env.LUA_ALLOWED_EGRESS_HOSTNAMES;
|
|
21490
|
+
if (!csv) return [];
|
|
21491
|
+
return csv.split(",").map((s) => s.trim()).filter(Boolean);
|
|
21492
|
+
}
|
|
21493
|
+
__name(resolveExtraAllowedHostnames, "resolveExtraAllowedHostnames");
|
|
21494
|
+
__name4(resolveExtraAllowedHostnames, "resolveExtraAllowedHostnames");
|
|
21341
21495
|
function wrapBundleAsCjsModule(source) {
|
|
21342
21496
|
return "(function(module, exports, require) {\n" + source + "\n})(module, module.exports, require);";
|
|
21343
21497
|
}
|
|
@@ -21571,6 +21725,12 @@ function resolveExtraAllowedCidrs2() {
|
|
|
21571
21725
|
return csv.split(",").map((s) => s.trim()).filter(Boolean);
|
|
21572
21726
|
}
|
|
21573
21727
|
__name(resolveExtraAllowedCidrs2, "resolveExtraAllowedCidrs");
|
|
21728
|
+
function resolveExtraAllowedHostnames2() {
|
|
21729
|
+
const csv = process.env.LUA_ALLOWED_EGRESS_HOSTNAMES;
|
|
21730
|
+
if (!csv) return [];
|
|
21731
|
+
return csv.split(",").map((s) => s.trim()).filter(Boolean);
|
|
21732
|
+
}
|
|
21733
|
+
__name(resolveExtraAllowedHostnames2, "resolveExtraAllowedHostnames");
|
|
21574
21734
|
function defaultSecurityEventLogger(evt) {
|
|
21575
21735
|
console.warn("[sandbox]", JSON.stringify(evt));
|
|
21576
21736
|
}
|
|
@@ -21759,6 +21919,7 @@ function createSandbox(options) {
|
|
|
21759
21919
|
requireMode: resolveRequireMode(),
|
|
21760
21920
|
egressMode: resolveEgressMode(),
|
|
21761
21921
|
egressExtraAllowedCidrs: resolveExtraAllowedCidrs2(),
|
|
21922
|
+
egressExtraAllowedHostnames: resolveExtraAllowedHostnames2(),
|
|
21762
21923
|
onSecurityEvent: defaultSecurityEventLogger
|
|
21763
21924
|
});
|
|
21764
21925
|
}
|