modal 0.5.0 → 0.5.2
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/README.md +29 -20
- package/dist/index.cjs +378 -60
- package/dist/index.d.cts +27 -2
- package/dist/index.d.ts +27 -2
- package/dist/index.js +378 -60
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -43635,6 +43635,15 @@ var FunctionService = class {
|
|
|
43635
43635
|
objectTag: name,
|
|
43636
43636
|
environmentName: this.#client.environmentName(params.environment)
|
|
43637
43637
|
});
|
|
43638
|
+
this.#client.logger.debug(
|
|
43639
|
+
"Retrieved Function",
|
|
43640
|
+
"function_id",
|
|
43641
|
+
resp.functionId,
|
|
43642
|
+
"app_name",
|
|
43643
|
+
appName,
|
|
43644
|
+
"function_name",
|
|
43645
|
+
name
|
|
43646
|
+
);
|
|
43638
43647
|
return new Function_(
|
|
43639
43648
|
this.#client,
|
|
43640
43649
|
resp.functionId,
|
|
@@ -43666,16 +43675,42 @@ var Function_ = class {
|
|
|
43666
43675
|
static async lookup(appName, name, params = {}) {
|
|
43667
43676
|
return await getDefaultClient().functions.fromName(appName, name, params);
|
|
43668
43677
|
}
|
|
43678
|
+
#checkNoWebUrl(fnName) {
|
|
43679
|
+
if (this.#handleMetadata?.webUrl) {
|
|
43680
|
+
throw new InvalidError(
|
|
43681
|
+
`A webhook Function cannot be invoked for remote execution with '.${fnName}'. Invoke this Function via its web url '${this.#handleMetadata.webUrl}' instead.`
|
|
43682
|
+
);
|
|
43683
|
+
}
|
|
43684
|
+
}
|
|
43669
43685
|
// Execute a single input into a remote Function.
|
|
43670
43686
|
async remote(args = [], kwargs = {}) {
|
|
43687
|
+
this.#client.logger.debug(
|
|
43688
|
+
"Executing function call",
|
|
43689
|
+
"function_id",
|
|
43690
|
+
this.functionId
|
|
43691
|
+
);
|
|
43692
|
+
this.#checkNoWebUrl("remote");
|
|
43671
43693
|
const input = await this.#createInput(args, kwargs);
|
|
43672
43694
|
const invocation = await this.#createRemoteInvocation(input);
|
|
43673
43695
|
let retryCount = 0;
|
|
43674
43696
|
while (true) {
|
|
43675
43697
|
try {
|
|
43676
|
-
|
|
43698
|
+
const result = await invocation.awaitOutput();
|
|
43699
|
+
this.#client.logger.debug(
|
|
43700
|
+
"Function call completed",
|
|
43701
|
+
"function_id",
|
|
43702
|
+
this.functionId
|
|
43703
|
+
);
|
|
43704
|
+
return result;
|
|
43677
43705
|
} catch (err) {
|
|
43678
43706
|
if (err instanceof InternalFailure && retryCount <= maxSystemRetries) {
|
|
43707
|
+
this.#client.logger.debug(
|
|
43708
|
+
"Retrying function call due to internal failure",
|
|
43709
|
+
"function_id",
|
|
43710
|
+
this.functionId,
|
|
43711
|
+
"retry_count",
|
|
43712
|
+
retryCount
|
|
43713
|
+
);
|
|
43679
43714
|
await invocation.retry(retryCount);
|
|
43680
43715
|
retryCount++;
|
|
43681
43716
|
} else {
|
|
@@ -43702,6 +43737,12 @@ var Function_ = class {
|
|
|
43702
43737
|
}
|
|
43703
43738
|
// Spawn a single input into a remote Function.
|
|
43704
43739
|
async spawn(args = [], kwargs = {}) {
|
|
43740
|
+
this.#client.logger.debug(
|
|
43741
|
+
"Spawning function call",
|
|
43742
|
+
"function_id",
|
|
43743
|
+
this.functionId
|
|
43744
|
+
);
|
|
43745
|
+
this.#checkNoWebUrl("spawn");
|
|
43705
43746
|
const input = await this.#createInput(args, kwargs);
|
|
43706
43747
|
const invocation = await ControlPlaneInvocation.create(
|
|
43707
43748
|
this.#client,
|
|
@@ -43709,6 +43750,13 @@ var Function_ = class {
|
|
|
43709
43750
|
input,
|
|
43710
43751
|
3 /* FUNCTION_CALL_INVOCATION_TYPE_ASYNC */
|
|
43711
43752
|
);
|
|
43753
|
+
this.#client.logger.debug(
|
|
43754
|
+
"Function call spawned",
|
|
43755
|
+
"function_id",
|
|
43756
|
+
this.functionId,
|
|
43757
|
+
"function_call_id",
|
|
43758
|
+
invocation.functionCallId
|
|
43759
|
+
);
|
|
43712
43760
|
return new FunctionCall(this.#client, invocation.functionCallId);
|
|
43713
43761
|
}
|
|
43714
43762
|
// Returns statistics about the Function.
|
|
@@ -43748,7 +43796,7 @@ var Function_ = class {
|
|
|
43748
43796
|
const supported_input_formats = this.#handleMetadata?.supportedInputFormats?.length ? this.#handleMetadata.supportedInputFormats : [1 /* DATA_FORMAT_PICKLE */];
|
|
43749
43797
|
if (!supported_input_formats.includes(4 /* DATA_FORMAT_CBOR */)) {
|
|
43750
43798
|
throw new InvalidError(
|
|
43751
|
-
"
|
|
43799
|
+
"cannot call Modal Function from JS SDK since it was deployed with an incompatible Python SDK version. Redeploy with Modal Python SDK >= 1.2"
|
|
43752
43800
|
);
|
|
43753
43801
|
}
|
|
43754
43802
|
const payload = cborEncode([args, kwargs]);
|
|
@@ -43811,6 +43859,13 @@ var SecretService = class {
|
|
|
43811
43859
|
environmentName: this.#client.environmentName(params?.environment),
|
|
43812
43860
|
requiredKeys: params?.requiredKeys ?? []
|
|
43813
43861
|
});
|
|
43862
|
+
this.#client.logger.debug(
|
|
43863
|
+
"Retrieved Secret",
|
|
43864
|
+
"secret_id",
|
|
43865
|
+
resp.secretId,
|
|
43866
|
+
"secret_name",
|
|
43867
|
+
name
|
|
43868
|
+
);
|
|
43814
43869
|
return new Secret(resp.secretId, name);
|
|
43815
43870
|
} catch (err) {
|
|
43816
43871
|
if (err instanceof ClientError2 && err.code === Status2.NOT_FOUND)
|
|
@@ -43835,6 +43890,11 @@ var SecretService = class {
|
|
|
43835
43890
|
envDict: entries,
|
|
43836
43891
|
environmentName: this.#client.environmentName(params?.environment)
|
|
43837
43892
|
});
|
|
43893
|
+
this.#client.logger.debug(
|
|
43894
|
+
"Created ephemeral Secret",
|
|
43895
|
+
"secret_id",
|
|
43896
|
+
resp.secretId
|
|
43897
|
+
);
|
|
43838
43898
|
return new Secret(resp.secretId);
|
|
43839
43899
|
} catch (err) {
|
|
43840
43900
|
if (err instanceof ClientError2 && (err.code === Status2.INVALID_ARGUMENT || err.code === Status2.FAILED_PRECONDITION))
|
|
@@ -43955,6 +44015,15 @@ var ClsService = class {
|
|
|
43955
44015
|
`Unsupported parameter format: ${parameterInfo?.format}`
|
|
43956
44016
|
);
|
|
43957
44017
|
}
|
|
44018
|
+
this.#client.logger.debug(
|
|
44019
|
+
"Retrieved Cls",
|
|
44020
|
+
"function_id",
|
|
44021
|
+
serviceFunction.functionId,
|
|
44022
|
+
"app_name",
|
|
44023
|
+
appName,
|
|
44024
|
+
"cls_name",
|
|
44025
|
+
name
|
|
44026
|
+
);
|
|
43958
44027
|
return new Cls(
|
|
43959
44028
|
this.#client,
|
|
43960
44029
|
serviceFunction.functionId,
|
|
@@ -44333,8 +44402,15 @@ var ImageService = class {
|
|
|
44333
44402
|
* Delete an {@link Image} by ID. Warning: This removes an *entire Image*, and cannot be undone.
|
|
44334
44403
|
*/
|
|
44335
44404
|
async delete(imageId, _ = {}) {
|
|
44336
|
-
|
|
44337
|
-
|
|
44405
|
+
try {
|
|
44406
|
+
await this.#client.cpClient.imageDelete({ imageId });
|
|
44407
|
+
} catch (err) {
|
|
44408
|
+
if (err instanceof ClientError4 && err.code === Status4.NOT_FOUND)
|
|
44409
|
+
throw new NotFoundError(err.details);
|
|
44410
|
+
if (err instanceof ClientError4 && err.code === Status4.FAILED_PRECONDITION && err.details.includes("Could not find image with ID"))
|
|
44411
|
+
throw new NotFoundError(err.details);
|
|
44412
|
+
throw err;
|
|
44413
|
+
}
|
|
44338
44414
|
}
|
|
44339
44415
|
};
|
|
44340
44416
|
var Image2 = class _Image {
|
|
@@ -44432,6 +44508,7 @@ var Image2 = class _Image {
|
|
|
44432
44508
|
if (this.imageId !== "") {
|
|
44433
44509
|
return this;
|
|
44434
44510
|
}
|
|
44511
|
+
this.#client.logger.debug("Building image", "app_id", app.appId);
|
|
44435
44512
|
let baseImageId;
|
|
44436
44513
|
for (let i = 0; i < this.#layers.length; i++) {
|
|
44437
44514
|
const layer = this.#layers[i];
|
|
@@ -44506,6 +44583,7 @@ ${result.exception}`
|
|
|
44506
44583
|
baseImageId = resp.imageId;
|
|
44507
44584
|
}
|
|
44508
44585
|
this.#imageId = baseImageId;
|
|
44586
|
+
this.#client.logger.debug("Image build completed", "image_id", baseImageId);
|
|
44509
44587
|
return this;
|
|
44510
44588
|
}
|
|
44511
44589
|
/**
|
|
@@ -44969,6 +45047,11 @@ var QueueService = class {
|
|
|
44969
45047
|
objectCreationType: 5 /* OBJECT_CREATION_TYPE_EPHEMERAL */,
|
|
44970
45048
|
environmentName: this.#client.environmentName(params.environment)
|
|
44971
45049
|
});
|
|
45050
|
+
this.#client.logger.debug(
|
|
45051
|
+
"Created ephemeral Queue",
|
|
45052
|
+
"queue_id",
|
|
45053
|
+
resp.queueId
|
|
45054
|
+
);
|
|
44972
45055
|
const ephemeralHbManager = new EphemeralHeartbeatManager(
|
|
44973
45056
|
() => this.#client.cpClient.queueHeartbeat({ queueId: resp.queueId })
|
|
44974
45057
|
);
|
|
@@ -44983,6 +45066,13 @@ var QueueService = class {
|
|
|
44983
45066
|
objectCreationType: params.createIfMissing ? 1 /* OBJECT_CREATION_TYPE_CREATE_IF_MISSING */ : void 0,
|
|
44984
45067
|
environmentName: this.#client.environmentName(params.environment)
|
|
44985
45068
|
});
|
|
45069
|
+
this.#client.logger.debug(
|
|
45070
|
+
"Retrieved Queue",
|
|
45071
|
+
"queue_id",
|
|
45072
|
+
resp.queueId,
|
|
45073
|
+
"queue_name",
|
|
45074
|
+
name
|
|
45075
|
+
);
|
|
44986
45076
|
return new Queue(this.#client, resp.queueId, name);
|
|
44987
45077
|
}
|
|
44988
45078
|
/**
|
|
@@ -45694,6 +45784,11 @@ var SandboxService = class {
|
|
|
45694
45784
|
}
|
|
45695
45785
|
throw err;
|
|
45696
45786
|
}
|
|
45787
|
+
this.#client.logger.debug(
|
|
45788
|
+
"Created Sandbox",
|
|
45789
|
+
"sandbox_id",
|
|
45790
|
+
createResp.sandboxId
|
|
45791
|
+
);
|
|
45697
45792
|
return new Sandbox2(this.#client, createResp.sandboxId);
|
|
45698
45793
|
}
|
|
45699
45794
|
/** Returns a running {@link Sandbox} object from an ID.
|
|
@@ -45954,6 +46049,15 @@ var Sandbox2 = class _Sandbox {
|
|
|
45954
46049
|
mergedParams
|
|
45955
46050
|
);
|
|
45956
46051
|
const resp = await this.#client.cpClient.containerExec(req);
|
|
46052
|
+
this.#client.logger.debug(
|
|
46053
|
+
"Created ContainerProcess",
|
|
46054
|
+
"exec_id",
|
|
46055
|
+
resp.execId,
|
|
46056
|
+
"sandbox_id",
|
|
46057
|
+
this.sandboxId,
|
|
46058
|
+
"command",
|
|
46059
|
+
command
|
|
46060
|
+
);
|
|
45957
46061
|
return new ContainerProcess(this.#client, resp.execId, params);
|
|
45958
46062
|
}
|
|
45959
46063
|
async #getTaskId() {
|
|
@@ -45986,7 +46090,17 @@ var Sandbox2 = class _Sandbox {
|
|
|
45986
46090
|
timeout: 10
|
|
45987
46091
|
});
|
|
45988
46092
|
if (resp.result) {
|
|
45989
|
-
|
|
46093
|
+
const returnCode = _Sandbox.#getReturnCode(resp.result);
|
|
46094
|
+
this.#client.logger.debug(
|
|
46095
|
+
"Sandbox wait completed",
|
|
46096
|
+
"sandbox_id",
|
|
46097
|
+
this.sandboxId,
|
|
46098
|
+
"status",
|
|
46099
|
+
resp.result.status,
|
|
46100
|
+
"return_code",
|
|
46101
|
+
returnCode
|
|
46102
|
+
);
|
|
46103
|
+
return returnCode;
|
|
45990
46104
|
}
|
|
45991
46105
|
}
|
|
45992
46106
|
}
|
|
@@ -46251,6 +46365,13 @@ var VolumeService = class {
|
|
|
46251
46365
|
environmentName: this.#client.environmentName(params?.environment),
|
|
46252
46366
|
objectCreationType: params?.createIfMissing ? 1 /* OBJECT_CREATION_TYPE_CREATE_IF_MISSING */ : 0 /* OBJECT_CREATION_TYPE_UNSPECIFIED */
|
|
46253
46367
|
});
|
|
46368
|
+
this.#client.logger.debug(
|
|
46369
|
+
"Retrieved Volume",
|
|
46370
|
+
"volume_id",
|
|
46371
|
+
resp.volumeId,
|
|
46372
|
+
"volume_name",
|
|
46373
|
+
name
|
|
46374
|
+
);
|
|
46254
46375
|
return new Volume(resp.volumeId, name);
|
|
46255
46376
|
} catch (err) {
|
|
46256
46377
|
if (err instanceof ClientError8 && err.code === Status8.NOT_FOUND)
|
|
@@ -46267,6 +46388,11 @@ var VolumeService = class {
|
|
|
46267
46388
|
objectCreationType: 5 /* OBJECT_CREATION_TYPE_EPHEMERAL */,
|
|
46268
46389
|
environmentName: this.#client.environmentName(params.environment)
|
|
46269
46390
|
});
|
|
46391
|
+
this.#client.logger.debug(
|
|
46392
|
+
"Created ephemeral Volume",
|
|
46393
|
+
"volume_id",
|
|
46394
|
+
resp.volumeId
|
|
46395
|
+
);
|
|
46270
46396
|
const ephemeralHbManager = new EphemeralHeartbeatManager(
|
|
46271
46397
|
() => this.#client.cpClient.volumeHeartbeat({ volumeId: resp.volumeId })
|
|
46272
46398
|
);
|
|
@@ -46319,9 +46445,17 @@ import { readFileSync } from "node:fs";
|
|
|
46319
46445
|
import { homedir } from "node:os";
|
|
46320
46446
|
import path from "node:path";
|
|
46321
46447
|
import { parse as parseToml } from "smol-toml";
|
|
46448
|
+
function configFilePath() {
|
|
46449
|
+
const configPath = process.env["MODAL_CONFIG_PATH"];
|
|
46450
|
+
if (configPath && configPath !== "") {
|
|
46451
|
+
return configPath;
|
|
46452
|
+
}
|
|
46453
|
+
return path.join(homedir(), ".modal.toml");
|
|
46454
|
+
}
|
|
46322
46455
|
function readConfigFile() {
|
|
46323
46456
|
try {
|
|
46324
|
-
const
|
|
46457
|
+
const configPath = configFilePath();
|
|
46458
|
+
const configContent = readFileSync(configPath, {
|
|
46325
46459
|
encoding: "utf-8"
|
|
46326
46460
|
});
|
|
46327
46461
|
return parseToml(configContent);
|
|
@@ -46348,7 +46482,8 @@ function getProfile(profileName) {
|
|
|
46348
46482
|
tokenId: process.env["MODAL_TOKEN_ID"] || profileData.token_id,
|
|
46349
46483
|
tokenSecret: process.env["MODAL_TOKEN_SECRET"] || profileData.token_secret,
|
|
46350
46484
|
environment: process.env["MODAL_ENVIRONMENT"] || profileData.environment,
|
|
46351
|
-
imageBuilderVersion: process.env["MODAL_IMAGE_BUILDER_VERSION"] || profileData.imageBuilderVersion
|
|
46485
|
+
imageBuilderVersion: process.env["MODAL_IMAGE_BUILDER_VERSION"] || profileData.imageBuilderVersion,
|
|
46486
|
+
logLevel: process.env["MODAL_LOGLEVEL"] || profileData.loglevel
|
|
46352
46487
|
};
|
|
46353
46488
|
return profile;
|
|
46354
46489
|
}
|
|
@@ -46358,13 +46493,15 @@ var REFRESH_WINDOW = 5 * 60;
|
|
|
46358
46493
|
var DEFAULT_EXPIRY_OFFSET = 20 * 60;
|
|
46359
46494
|
var AuthTokenManager = class {
|
|
46360
46495
|
client;
|
|
46496
|
+
logger;
|
|
46361
46497
|
currentToken = "";
|
|
46362
46498
|
tokenExpiry = 0;
|
|
46363
46499
|
stopped = false;
|
|
46364
46500
|
timeoutId = null;
|
|
46365
46501
|
initialTokenPromise = null;
|
|
46366
|
-
constructor(client2) {
|
|
46502
|
+
constructor(client2, logger) {
|
|
46367
46503
|
this.client = client2;
|
|
46504
|
+
this.logger = logger;
|
|
46368
46505
|
}
|
|
46369
46506
|
/**
|
|
46370
46507
|
* Returns the current cached token.
|
|
@@ -46395,9 +46532,19 @@ var AuthTokenManager = class {
|
|
|
46395
46532
|
if (exp > 0) {
|
|
46396
46533
|
this.tokenExpiry = exp;
|
|
46397
46534
|
} else {
|
|
46398
|
-
|
|
46535
|
+
this.logger.warn("x-modal-auth-token does not contain exp field");
|
|
46399
46536
|
this.tokenExpiry = Math.floor(Date.now() / 1e3) + DEFAULT_EXPIRY_OFFSET;
|
|
46400
46537
|
}
|
|
46538
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
46539
|
+
const expiresIn = this.tokenExpiry - now;
|
|
46540
|
+
const refreshIn = this.tokenExpiry - now - REFRESH_WINDOW;
|
|
46541
|
+
this.logger.debug(
|
|
46542
|
+
"Fetched auth token",
|
|
46543
|
+
"expires_in",
|
|
46544
|
+
`${expiresIn}s`,
|
|
46545
|
+
"refresh_in",
|
|
46546
|
+
`${refreshIn}s`
|
|
46547
|
+
);
|
|
46401
46548
|
}
|
|
46402
46549
|
/**
|
|
46403
46550
|
* Background loop that refreshes tokens REFRESH_WINDOW seconds before they expire.
|
|
@@ -46417,7 +46564,7 @@ var AuthTokenManager = class {
|
|
|
46417
46564
|
try {
|
|
46418
46565
|
await this.fetchToken();
|
|
46419
46566
|
} catch (error) {
|
|
46420
|
-
|
|
46567
|
+
this.logger.error("Failed to refresh auth token", "error", error);
|
|
46421
46568
|
await new Promise((resolve) => setTimeout(resolve, 5e3));
|
|
46422
46569
|
}
|
|
46423
46570
|
}
|
|
@@ -46481,7 +46628,113 @@ var AuthTokenManager = class {
|
|
|
46481
46628
|
|
|
46482
46629
|
// src/version.ts
|
|
46483
46630
|
function getSDKVersion() {
|
|
46484
|
-
return true ? "0.5.
|
|
46631
|
+
return true ? "0.5.2" : "0.0.0";
|
|
46632
|
+
}
|
|
46633
|
+
|
|
46634
|
+
// src/logger.ts
|
|
46635
|
+
var LOG_LEVELS = {
|
|
46636
|
+
debug: 0,
|
|
46637
|
+
info: 1,
|
|
46638
|
+
warn: 2,
|
|
46639
|
+
error: 3
|
|
46640
|
+
};
|
|
46641
|
+
function parseLogLevel(level) {
|
|
46642
|
+
if (!level) {
|
|
46643
|
+
return "warn";
|
|
46644
|
+
}
|
|
46645
|
+
const normalized = level.toLowerCase();
|
|
46646
|
+
if (normalized === "debug" || normalized === "info" || normalized === "warn" || normalized === "warning" || normalized === "error") {
|
|
46647
|
+
return normalized === "warning" ? "warn" : normalized;
|
|
46648
|
+
}
|
|
46649
|
+
throw new Error(
|
|
46650
|
+
`Invalid log level value: "${level}" (must be debug, info, warn, or error)`
|
|
46651
|
+
);
|
|
46652
|
+
}
|
|
46653
|
+
var DefaultLogger = class {
|
|
46654
|
+
levelValue;
|
|
46655
|
+
constructor(level = "warn") {
|
|
46656
|
+
this.levelValue = LOG_LEVELS[level];
|
|
46657
|
+
}
|
|
46658
|
+
debug(message, ...args) {
|
|
46659
|
+
if (this.levelValue <= LOG_LEVELS.debug) {
|
|
46660
|
+
console.log(this.formatMessage("DEBUG", message, args));
|
|
46661
|
+
}
|
|
46662
|
+
}
|
|
46663
|
+
info(message, ...args) {
|
|
46664
|
+
if (this.levelValue <= LOG_LEVELS.info) {
|
|
46665
|
+
console.log(this.formatMessage("INFO", message, args));
|
|
46666
|
+
}
|
|
46667
|
+
}
|
|
46668
|
+
warn(message, ...args) {
|
|
46669
|
+
if (this.levelValue <= LOG_LEVELS.warn) {
|
|
46670
|
+
console.warn(this.formatMessage("WARN", message, args));
|
|
46671
|
+
}
|
|
46672
|
+
}
|
|
46673
|
+
error(message, ...args) {
|
|
46674
|
+
if (this.levelValue <= LOG_LEVELS.error) {
|
|
46675
|
+
console.error(this.formatMessage("ERROR", message, args));
|
|
46676
|
+
}
|
|
46677
|
+
}
|
|
46678
|
+
formatMessage(level, message, args) {
|
|
46679
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
46680
|
+
let formatted = `time=${timestamp} level=${level} msg="${message}"`;
|
|
46681
|
+
if (args.length > 0) {
|
|
46682
|
+
for (let i = 0; i < args.length; i += 2) {
|
|
46683
|
+
if (i + 1 < args.length) {
|
|
46684
|
+
const key = args[i];
|
|
46685
|
+
const value = args[i + 1];
|
|
46686
|
+
formatted += ` ${key}=${this.formatValue(value)}`;
|
|
46687
|
+
}
|
|
46688
|
+
}
|
|
46689
|
+
}
|
|
46690
|
+
return formatted;
|
|
46691
|
+
}
|
|
46692
|
+
formatValue(value) {
|
|
46693
|
+
if (typeof value === "string") {
|
|
46694
|
+
return value.includes(" ") ? `"${value}"` : value;
|
|
46695
|
+
}
|
|
46696
|
+
if (value instanceof Error) {
|
|
46697
|
+
return `"${value.message}"`;
|
|
46698
|
+
}
|
|
46699
|
+
if (Array.isArray(value)) {
|
|
46700
|
+
return `[${value.join(",")}]`;
|
|
46701
|
+
}
|
|
46702
|
+
return String(value);
|
|
46703
|
+
}
|
|
46704
|
+
};
|
|
46705
|
+
var FilteredLogger = class {
|
|
46706
|
+
constructor(logger, level) {
|
|
46707
|
+
this.logger = logger;
|
|
46708
|
+
this.levelValue = LOG_LEVELS[level];
|
|
46709
|
+
}
|
|
46710
|
+
levelValue;
|
|
46711
|
+
debug(message, ...args) {
|
|
46712
|
+
if (this.levelValue <= LOG_LEVELS.debug) {
|
|
46713
|
+
this.logger.debug(message, ...args);
|
|
46714
|
+
}
|
|
46715
|
+
}
|
|
46716
|
+
info(message, ...args) {
|
|
46717
|
+
if (this.levelValue <= LOG_LEVELS.info) {
|
|
46718
|
+
this.logger.info(message, ...args);
|
|
46719
|
+
}
|
|
46720
|
+
}
|
|
46721
|
+
warn(message, ...args) {
|
|
46722
|
+
if (this.levelValue <= LOG_LEVELS.warn) {
|
|
46723
|
+
this.logger.warn(message, ...args);
|
|
46724
|
+
}
|
|
46725
|
+
}
|
|
46726
|
+
error(message, ...args) {
|
|
46727
|
+
if (this.levelValue <= LOG_LEVELS.error) {
|
|
46728
|
+
this.logger.error(message, ...args);
|
|
46729
|
+
}
|
|
46730
|
+
}
|
|
46731
|
+
};
|
|
46732
|
+
function createLogger(logger, logLevel = "") {
|
|
46733
|
+
const level = parseLogLevel(logLevel);
|
|
46734
|
+
if (logger) {
|
|
46735
|
+
return new FilteredLogger(logger, level);
|
|
46736
|
+
}
|
|
46737
|
+
return new DefaultLogger(level);
|
|
46485
46738
|
}
|
|
46486
46739
|
|
|
46487
46740
|
// src/client.ts
|
|
@@ -46499,8 +46752,10 @@ var ModalClient = class {
|
|
|
46499
46752
|
/** @ignore */
|
|
46500
46753
|
cpClient;
|
|
46501
46754
|
profile;
|
|
46755
|
+
logger;
|
|
46502
46756
|
ipClients;
|
|
46503
46757
|
authTokenManager = null;
|
|
46758
|
+
customMiddleware;
|
|
46504
46759
|
constructor(params) {
|
|
46505
46760
|
checkForRenamedParams(params, { timeout: "timeoutMs" });
|
|
46506
46761
|
const baseProfile = getProfile(process.env["MODAL_PROFILE"]);
|
|
@@ -46510,8 +46765,19 @@ var ModalClient = class {
|
|
|
46510
46765
|
...params?.tokenSecret && { tokenSecret: params.tokenSecret },
|
|
46511
46766
|
...params?.environment && { environment: params.environment }
|
|
46512
46767
|
};
|
|
46768
|
+
const logLevelValue = params?.logLevel || this.profile.logLevel || "";
|
|
46769
|
+
this.logger = createLogger(params?.logger, logLevelValue);
|
|
46770
|
+
this.logger.debug(
|
|
46771
|
+
"Initializing Modal client",
|
|
46772
|
+
"version",
|
|
46773
|
+
getSDKVersion(),
|
|
46774
|
+
"server_url",
|
|
46775
|
+
this.profile.serverUrl
|
|
46776
|
+
);
|
|
46777
|
+
this.customMiddleware = params?.grpcMiddleware ?? [];
|
|
46513
46778
|
this.ipClients = /* @__PURE__ */ new Map();
|
|
46514
46779
|
this.cpClient = params?.cpClient ?? this.createClient(this.profile);
|
|
46780
|
+
this.logger.debug("Modal client initialized successfully");
|
|
46515
46781
|
this.apps = new AppService(this);
|
|
46516
46782
|
this.cls = new ClsService(this);
|
|
46517
46783
|
this.functions = new FunctionService(this);
|
|
@@ -46535,16 +46801,19 @@ var ModalClient = class {
|
|
|
46535
46801
|
if (existing) {
|
|
46536
46802
|
return existing;
|
|
46537
46803
|
}
|
|
46804
|
+
this.logger.debug("Creating input plane client", "server_url", serverUrl);
|
|
46538
46805
|
const profile = { ...this.profile, serverUrl };
|
|
46539
46806
|
const newClient = this.createClient(profile);
|
|
46540
46807
|
this.ipClients.set(serverUrl, newClient);
|
|
46541
46808
|
return newClient;
|
|
46542
46809
|
}
|
|
46543
46810
|
close() {
|
|
46811
|
+
this.logger.debug("Closing Modal client");
|
|
46544
46812
|
if (this.authTokenManager) {
|
|
46545
46813
|
this.authTokenManager.stop();
|
|
46546
46814
|
this.authTokenManager = null;
|
|
46547
46815
|
}
|
|
46816
|
+
this.logger.debug("Modal client closed");
|
|
46548
46817
|
}
|
|
46549
46818
|
version() {
|
|
46550
46819
|
return getSDKVersion();
|
|
@@ -46555,12 +46824,101 @@ var ModalClient = class {
|
|
|
46555
46824
|
"grpc.max_send_message_length": 100 * 1024 * 1024,
|
|
46556
46825
|
"grpc-node.flow_control_window": 64 * 1024 * 1024
|
|
46557
46826
|
});
|
|
46558
|
-
|
|
46827
|
+
let factory = createClientFactory().use(this.authMiddleware(profile)).use(this.retryMiddleware()).use(timeoutMiddleware);
|
|
46828
|
+
for (const middleware of this.customMiddleware) {
|
|
46829
|
+
factory = factory.use(middleware);
|
|
46830
|
+
}
|
|
46831
|
+
return factory.create(ModalClientDefinition, channel);
|
|
46832
|
+
}
|
|
46833
|
+
/** Middleware to retry transient errors and timeouts for unary requests. */
|
|
46834
|
+
retryMiddleware() {
|
|
46835
|
+
const logger = this.logger;
|
|
46836
|
+
return async function* retryMiddleware(call, options) {
|
|
46837
|
+
const {
|
|
46838
|
+
retries = 3,
|
|
46839
|
+
baseDelay = 100,
|
|
46840
|
+
maxDelay = 1e3,
|
|
46841
|
+
delayFactor = 2,
|
|
46842
|
+
additionalStatusCodes = [],
|
|
46843
|
+
signal,
|
|
46844
|
+
...restOptions
|
|
46845
|
+
} = options;
|
|
46846
|
+
if (call.requestStream || call.responseStream || !retries) {
|
|
46847
|
+
return yield* call.next(call.request, restOptions);
|
|
46848
|
+
}
|
|
46849
|
+
const retryableCodes = /* @__PURE__ */ new Set([
|
|
46850
|
+
...retryableGrpcStatusCodes,
|
|
46851
|
+
...additionalStatusCodes
|
|
46852
|
+
]);
|
|
46853
|
+
const idempotencyKey = uuidv4();
|
|
46854
|
+
const startTime = Date.now();
|
|
46855
|
+
let attempt = 0;
|
|
46856
|
+
let delayMs = baseDelay;
|
|
46857
|
+
logger.debug("Sending gRPC request", "method", call.method.path);
|
|
46858
|
+
while (true) {
|
|
46859
|
+
const metadata = new Metadata(restOptions.metadata ?? {});
|
|
46860
|
+
metadata.set("x-idempotency-key", idempotencyKey);
|
|
46861
|
+
metadata.set("x-retry-attempt", String(attempt));
|
|
46862
|
+
if (attempt > 0) {
|
|
46863
|
+
metadata.set(
|
|
46864
|
+
"x-retry-delay",
|
|
46865
|
+
((Date.now() - startTime) / 1e3).toFixed(3)
|
|
46866
|
+
);
|
|
46867
|
+
}
|
|
46868
|
+
try {
|
|
46869
|
+
return yield* call.next(call.request, {
|
|
46870
|
+
...restOptions,
|
|
46871
|
+
metadata,
|
|
46872
|
+
signal
|
|
46873
|
+
});
|
|
46874
|
+
} catch (err) {
|
|
46875
|
+
if (!(err instanceof ClientError9) || !retryableCodes.has(err.code) || attempt >= retries) {
|
|
46876
|
+
if (attempt === retries && attempt > 0) {
|
|
46877
|
+
logger.debug(
|
|
46878
|
+
"Final retry attempt failed",
|
|
46879
|
+
"error",
|
|
46880
|
+
err,
|
|
46881
|
+
"retries",
|
|
46882
|
+
attempt,
|
|
46883
|
+
"delay",
|
|
46884
|
+
delayMs,
|
|
46885
|
+
"method",
|
|
46886
|
+
call.method.path,
|
|
46887
|
+
"idempotency_key",
|
|
46888
|
+
idempotencyKey.substring(0, 8)
|
|
46889
|
+
);
|
|
46890
|
+
}
|
|
46891
|
+
throw err;
|
|
46892
|
+
}
|
|
46893
|
+
if (attempt > 0) {
|
|
46894
|
+
logger.debug(
|
|
46895
|
+
"Retryable failure",
|
|
46896
|
+
"error",
|
|
46897
|
+
err,
|
|
46898
|
+
"retries",
|
|
46899
|
+
attempt,
|
|
46900
|
+
"delay",
|
|
46901
|
+
delayMs,
|
|
46902
|
+
"method",
|
|
46903
|
+
call.method.path,
|
|
46904
|
+
"idempotency_key",
|
|
46905
|
+
idempotencyKey.substring(0, 8)
|
|
46906
|
+
);
|
|
46907
|
+
}
|
|
46908
|
+
await sleep(delayMs, signal);
|
|
46909
|
+
delayMs = Math.min(delayMs * delayFactor, maxDelay);
|
|
46910
|
+
attempt += 1;
|
|
46911
|
+
}
|
|
46912
|
+
}
|
|
46913
|
+
};
|
|
46559
46914
|
}
|
|
46560
46915
|
authMiddleware(profile) {
|
|
46561
46916
|
const getOrCreateAuthTokenManager = () => {
|
|
46562
46917
|
if (!this.authTokenManager) {
|
|
46563
|
-
this.authTokenManager = new AuthTokenManager(
|
|
46918
|
+
this.authTokenManager = new AuthTokenManager(
|
|
46919
|
+
this.cpClient,
|
|
46920
|
+
this.logger
|
|
46921
|
+
);
|
|
46564
46922
|
this.authTokenManager.start();
|
|
46565
46923
|
}
|
|
46566
46924
|
return this.authTokenManager;
|
|
@@ -46650,53 +47008,6 @@ var sleep = (ms, signal) => new Promise((resolve, reject) => {
|
|
|
46650
47008
|
{ once: true }
|
|
46651
47009
|
);
|
|
46652
47010
|
});
|
|
46653
|
-
var retryMiddleware = async function* retryMiddleware2(call, options) {
|
|
46654
|
-
const {
|
|
46655
|
-
retries = 3,
|
|
46656
|
-
baseDelay = 100,
|
|
46657
|
-
maxDelay = 1e3,
|
|
46658
|
-
delayFactor = 2,
|
|
46659
|
-
additionalStatusCodes = [],
|
|
46660
|
-
signal,
|
|
46661
|
-
...restOptions
|
|
46662
|
-
} = options;
|
|
46663
|
-
if (call.requestStream || call.responseStream || !retries) {
|
|
46664
|
-
return yield* call.next(call.request, restOptions);
|
|
46665
|
-
}
|
|
46666
|
-
const retryableCodes = /* @__PURE__ */ new Set([
|
|
46667
|
-
...retryableGrpcStatusCodes,
|
|
46668
|
-
...additionalStatusCodes
|
|
46669
|
-
]);
|
|
46670
|
-
const idempotencyKey = uuidv4();
|
|
46671
|
-
const startTime = Date.now();
|
|
46672
|
-
let attempt = 0;
|
|
46673
|
-
let delayMs = baseDelay;
|
|
46674
|
-
while (true) {
|
|
46675
|
-
const metadata = new Metadata(restOptions.metadata ?? {});
|
|
46676
|
-
metadata.set("x-idempotency-key", idempotencyKey);
|
|
46677
|
-
metadata.set("x-retry-attempt", String(attempt));
|
|
46678
|
-
if (attempt > 0) {
|
|
46679
|
-
metadata.set(
|
|
46680
|
-
"x-retry-delay",
|
|
46681
|
-
((Date.now() - startTime) / 1e3).toFixed(3)
|
|
46682
|
-
);
|
|
46683
|
-
}
|
|
46684
|
-
try {
|
|
46685
|
-
return yield* call.next(call.request, {
|
|
46686
|
-
...restOptions,
|
|
46687
|
-
metadata,
|
|
46688
|
-
signal
|
|
46689
|
-
});
|
|
46690
|
-
} catch (err) {
|
|
46691
|
-
if (!(err instanceof ClientError9) || !retryableCodes.has(err.code) || attempt >= retries) {
|
|
46692
|
-
throw err;
|
|
46693
|
-
}
|
|
46694
|
-
await sleep(delayMs, signal);
|
|
46695
|
-
delayMs = Math.min(delayMs * delayFactor, maxDelay);
|
|
46696
|
-
attempt += 1;
|
|
46697
|
-
}
|
|
46698
|
-
}
|
|
46699
|
-
};
|
|
46700
47011
|
var defaultClient;
|
|
46701
47012
|
var defaultClientOptions;
|
|
46702
47013
|
function getDefaultClient() {
|
|
@@ -46740,6 +47051,13 @@ var AppService = class {
|
|
|
46740
47051
|
environmentName: this.#client.environmentName(params.environment),
|
|
46741
47052
|
objectCreationType: params.createIfMissing ? 1 /* OBJECT_CREATION_TYPE_CREATE_IF_MISSING */ : 0 /* OBJECT_CREATION_TYPE_UNSPECIFIED */
|
|
46742
47053
|
});
|
|
47054
|
+
this.#client.logger.debug(
|
|
47055
|
+
"Retrieved App",
|
|
47056
|
+
"app_id",
|
|
47057
|
+
resp.appId,
|
|
47058
|
+
"app_name",
|
|
47059
|
+
name
|
|
47060
|
+
);
|
|
46743
47061
|
return new App2(resp.appId, name);
|
|
46744
47062
|
} catch (err) {
|
|
46745
47063
|
if (err instanceof ClientError10 && err.code === Status10.NOT_FOUND)
|