@hot-updater/aws 1.2.0-rc.7 → 1.2.0-rc.8
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.cjs +31 -5
- package/dist/index.d.cts +22 -4
- package/dist/index.d.mts +22 -4
- package/dist/index.mjs +32 -6
- package/dist/init/index.cjs +40 -28
- package/dist/init/index.mjs +42 -30
- package/dist/lambda/index.cjs +36 -6
- package/package.json +7 -7
package/dist/index.cjs
CHANGED
|
@@ -315,10 +315,30 @@ async apply() {
|
|
|
315
315
|
};
|
|
316
316
|
};
|
|
317
317
|
//#endregion
|
|
318
|
+
//#region src/lazyCredentials.ts
|
|
319
|
+
/**
|
|
320
|
+
* `credentials` as the AWS SDK takes them: access keys with a lazy field
|
|
321
|
+
* become a provider, which the SDK calls once, on its first request.
|
|
322
|
+
*/
|
|
323
|
+
const toSdkCredentials = (credentials) => {
|
|
324
|
+
if (credentials === void 0 || typeof credentials === "function") return credentials;
|
|
325
|
+
const { accessKeyId, secretAccessKey, sessionToken, ...rest } = credentials;
|
|
326
|
+
if (typeof accessKeyId !== "function" && typeof secretAccessKey !== "function" && typeof sessionToken !== "function") return credentials;
|
|
327
|
+
return async () => ({
|
|
328
|
+
...rest,
|
|
329
|
+
accessKeyId: await (0, _hot_updater_plugin_core.resolveLazy)(accessKeyId),
|
|
330
|
+
secretAccessKey: await (0, _hot_updater_plugin_core.resolveLazy)(secretAccessKey),
|
|
331
|
+
...sessionToken === void 0 ? {} : { sessionToken: await (0, _hot_updater_plugin_core.resolveLazy)(sessionToken) }
|
|
332
|
+
});
|
|
333
|
+
};
|
|
334
|
+
//#endregion
|
|
318
335
|
//#region src/dynamoDB.ts
|
|
319
336
|
/** The DynamoDB client ignores the CloudFront and batching settings. */
|
|
320
|
-
const adapterOf = ({ tableName, ...clientConfig }) => {
|
|
321
|
-
const client = new _aws_sdk_client_dynamodb.DynamoDBClient(
|
|
337
|
+
const adapterOf = ({ tableName, credentials, ...clientConfig }) => {
|
|
338
|
+
const client = new _aws_sdk_client_dynamodb.DynamoDBClient({
|
|
339
|
+
...clientConfig,
|
|
340
|
+
credentials: toSdkCredentials(credentials)
|
|
341
|
+
});
|
|
322
342
|
const store = createDynamoDBStore({
|
|
323
343
|
client,
|
|
324
344
|
tableName
|
|
@@ -353,7 +373,10 @@ const marked = (target) => ({ [DATABASE_TARGET]: target });
|
|
|
353
373
|
*/
|
|
354
374
|
const dynamoDB = (config) => {
|
|
355
375
|
const { client, adapter } = adapterOf(config);
|
|
356
|
-
const cloudFront = createUpdateRouteInvalidation(
|
|
376
|
+
const cloudFront = createUpdateRouteInvalidation({
|
|
377
|
+
...config,
|
|
378
|
+
credentials: toSdkCredentials(config.credentials)
|
|
379
|
+
});
|
|
357
380
|
return {
|
|
358
381
|
...(0, _hot_updater_plugin_core.createEngineDatabase)({
|
|
359
382
|
name: "dynamoDB",
|
|
@@ -500,8 +523,11 @@ const cloudFrontDownloadUrl = (config) => {
|
|
|
500
523
|
const PRESIGNED_URL_EXPIRES_IN_SECONDS = 3600;
|
|
501
524
|
const isObjectNotFoundError = (error) => error instanceof Error && (error.name === "NotFound" || error.name === "NoSuchKey");
|
|
502
525
|
function s3Storage(config) {
|
|
503
|
-
const { bucketName, basePath, getDownloadUrl, ...s3Config } = config;
|
|
504
|
-
const client = new _aws_sdk_client_s3.S3Client(applyS3RuntimeAwsConfig(
|
|
526
|
+
const { bucketName, basePath, getDownloadUrl, credentials, ...s3Config } = config;
|
|
527
|
+
const client = new _aws_sdk_client_s3.S3Client(applyS3RuntimeAwsConfig({
|
|
528
|
+
...s3Config,
|
|
529
|
+
credentials: toSdkCredentials(credentials)
|
|
530
|
+
}));
|
|
505
531
|
const normalizedBasePath = basePath?.replace(/^\/+|\/+$/g, "") ?? "";
|
|
506
532
|
const getStorageKey = (0, _hot_updater_plugin_core.createStorageKeyBuilder)(normalizedBasePath);
|
|
507
533
|
const getListPrefix = (prefix = "") => {
|
package/dist/index.d.cts
CHANGED
|
@@ -1,8 +1,24 @@
|
|
|
1
1
|
import { DynamoDBClientConfig } from "@aws-sdk/client-dynamodb";
|
|
2
|
-
import { EngineDatabase, PluginTables, SecretsAdapter, StorageAdapter, StorageAdapterWith } from "@hot-updater/plugin-core";
|
|
2
|
+
import { EngineDatabase, Lazy, PluginTables, SecretsAdapter, StorageAdapter, StorageAdapterWith } from "@hot-updater/plugin-core";
|
|
3
3
|
import { S3ClientConfig } from "@aws-sdk/client-s3";
|
|
4
|
+
//#region src/lazyCredentials.d.ts
|
|
5
|
+
type SdkCredentials = S3ClientConfig["credentials"];
|
|
6
|
+
/**
|
|
7
|
+
* Access keys whose fields may each be a function that returns them, such
|
|
8
|
+
* as `secret("<name>")` in `hot-updater.config.ts`, called on first use.
|
|
9
|
+
*/
|
|
10
|
+
interface LazyAwsCredentials {
|
|
11
|
+
readonly accessKeyId: Lazy<string>;
|
|
12
|
+
readonly secretAccessKey: Lazy<string>;
|
|
13
|
+
readonly sessionToken?: Lazy<string>;
|
|
14
|
+
}
|
|
15
|
+
/** The credentials the AWS SDK takes, or access keys with lazy fields. */
|
|
16
|
+
type AwsCredentialsOption = SdkCredentials | LazyAwsCredentials;
|
|
17
|
+
//#endregion
|
|
4
18
|
//#region src/dynamoDB.d.ts
|
|
5
|
-
interface DynamoDBConfig extends DynamoDBClientConfig {
|
|
19
|
+
interface DynamoDBConfig extends Omit<DynamoDBClientConfig, "credentials"> {
|
|
20
|
+
/** The SDK's credentials, or access keys whose fields are lazy. */
|
|
21
|
+
readonly credentials?: AwsCredentialsOption;
|
|
6
22
|
readonly apiBasePath?: string;
|
|
7
23
|
readonly cloudfrontDistributionId?: string;
|
|
8
24
|
readonly shouldWaitForInvalidation?: boolean;
|
|
@@ -59,7 +75,9 @@ declare const cloudFrontDownloadUrl: (config: CloudFrontDownloadUrlOptions) => (
|
|
|
59
75
|
}>;
|
|
60
76
|
//#endregion
|
|
61
77
|
//#region src/s3Storage.d.ts
|
|
62
|
-
interface S3StorageConfig extends S3ClientConfig {
|
|
78
|
+
interface S3StorageConfig extends Omit<S3ClientConfig, "credentials"> {
|
|
79
|
+
/** The SDK's credentials, or access keys whose fields are lazy. */
|
|
80
|
+
credentials?: AwsCredentialsOption;
|
|
63
81
|
bucketName: string;
|
|
64
82
|
/** Base path where bundles will be stored in the bucket. */
|
|
65
83
|
basePath?: string;
|
|
@@ -85,7 +103,7 @@ interface SecretsManagerOptions {
|
|
|
85
103
|
/** The AWS region the secrets are in, such as `"us-east-1"`. */
|
|
86
104
|
readonly region: string;
|
|
87
105
|
/**
|
|
88
|
-
* Put before every name to make its secret's name, so `secret
|
|
106
|
+
* Put before every name to make its secret's name, so `secret("asc-api-key")`
|
|
89
107
|
* reads the secret `hot-updater/asc-api-key` and one IAM resource,
|
|
90
108
|
* `secret:hot-updater/*`, covers them all. Letters, digits, and
|
|
91
109
|
* `/_+=.@-`.
|
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,24 @@
|
|
|
1
1
|
import { DynamoDBClientConfig } from "@aws-sdk/client-dynamodb";
|
|
2
|
-
import { EngineDatabase, PluginTables, SecretsAdapter, StorageAdapter, StorageAdapterWith } from "@hot-updater/plugin-core";
|
|
2
|
+
import { EngineDatabase, Lazy, PluginTables, SecretsAdapter, StorageAdapter, StorageAdapterWith } from "@hot-updater/plugin-core";
|
|
3
3
|
import { S3ClientConfig } from "@aws-sdk/client-s3";
|
|
4
|
+
//#region src/lazyCredentials.d.ts
|
|
5
|
+
type SdkCredentials = S3ClientConfig["credentials"];
|
|
6
|
+
/**
|
|
7
|
+
* Access keys whose fields may each be a function that returns them, such
|
|
8
|
+
* as `secret("<name>")` in `hot-updater.config.ts`, called on first use.
|
|
9
|
+
*/
|
|
10
|
+
interface LazyAwsCredentials {
|
|
11
|
+
readonly accessKeyId: Lazy<string>;
|
|
12
|
+
readonly secretAccessKey: Lazy<string>;
|
|
13
|
+
readonly sessionToken?: Lazy<string>;
|
|
14
|
+
}
|
|
15
|
+
/** The credentials the AWS SDK takes, or access keys with lazy fields. */
|
|
16
|
+
type AwsCredentialsOption = SdkCredentials | LazyAwsCredentials;
|
|
17
|
+
//#endregion
|
|
4
18
|
//#region src/dynamoDB.d.ts
|
|
5
|
-
interface DynamoDBConfig extends DynamoDBClientConfig {
|
|
19
|
+
interface DynamoDBConfig extends Omit<DynamoDBClientConfig, "credentials"> {
|
|
20
|
+
/** The SDK's credentials, or access keys whose fields are lazy. */
|
|
21
|
+
readonly credentials?: AwsCredentialsOption;
|
|
6
22
|
readonly apiBasePath?: string;
|
|
7
23
|
readonly cloudfrontDistributionId?: string;
|
|
8
24
|
readonly shouldWaitForInvalidation?: boolean;
|
|
@@ -59,7 +75,9 @@ declare const cloudFrontDownloadUrl: (config: CloudFrontDownloadUrlOptions) => (
|
|
|
59
75
|
}>;
|
|
60
76
|
//#endregion
|
|
61
77
|
//#region src/s3Storage.d.ts
|
|
62
|
-
interface S3StorageConfig extends S3ClientConfig {
|
|
78
|
+
interface S3StorageConfig extends Omit<S3ClientConfig, "credentials"> {
|
|
79
|
+
/** The SDK's credentials, or access keys whose fields are lazy. */
|
|
80
|
+
credentials?: AwsCredentialsOption;
|
|
63
81
|
bucketName: string;
|
|
64
82
|
/** Base path where bundles will be stored in the bucket. */
|
|
65
83
|
basePath?: string;
|
|
@@ -85,7 +103,7 @@ interface SecretsManagerOptions {
|
|
|
85
103
|
/** The AWS region the secrets are in, such as `"us-east-1"`. */
|
|
86
104
|
readonly region: string;
|
|
87
105
|
/**
|
|
88
|
-
* Put before every name to make its secret's name, so `secret
|
|
106
|
+
* Put before every name to make its secret's name, so `secret("asc-api-key")`
|
|
89
107
|
* reads the secret `hot-updater/asc-api-key` and one IAM resource,
|
|
90
108
|
* `secret:hot-updater/*`, covers them all. Letters, digits, and
|
|
91
109
|
* `/_+=.@-`.
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CreateTableCommand, DescribeTableCommand, DescribeTimeToLiveCommand, DynamoDBClient, UpdateTimeToLiveCommand, waitUntilTableExists } from "@aws-sdk/client-dynamodb";
|
|
2
|
-
import { BUNDLE_STORAGE_PREFIX, CONTENT_ADDRESSED_ASSET_PREFIX, createEngineDatabase, createKvAdapter, createStorageAdapter, createStorageKeyBuilder, createStorageUri, migrateCoreSchema, parseStorageUri } from "@hot-updater/plugin-core";
|
|
2
|
+
import { BUNDLE_STORAGE_PREFIX, CONTENT_ADDRESSED_ASSET_PREFIX, createEngineDatabase, createKvAdapter, createStorageAdapter, createStorageKeyBuilder, createStorageUri, migrateCoreSchema, parseStorageUri, resolveLazy } from "@hot-updater/plugin-core";
|
|
3
3
|
import { CloudFrontClient, CreateInvalidationCommand, GetInvalidationCommand } from "@aws-sdk/client-cloudfront";
|
|
4
4
|
import { BatchGetCommand, BatchWriteCommand, DynamoDBDocumentClient, QueryCommand, TransactWriteCommand } from "@aws-sdk/lib-dynamodb";
|
|
5
5
|
import { SSM } from "@aws-sdk/client-ssm";
|
|
@@ -314,10 +314,30 @@ async apply() {
|
|
|
314
314
|
};
|
|
315
315
|
};
|
|
316
316
|
//#endregion
|
|
317
|
+
//#region src/lazyCredentials.ts
|
|
318
|
+
/**
|
|
319
|
+
* `credentials` as the AWS SDK takes them: access keys with a lazy field
|
|
320
|
+
* become a provider, which the SDK calls once, on its first request.
|
|
321
|
+
*/
|
|
322
|
+
const toSdkCredentials = (credentials) => {
|
|
323
|
+
if (credentials === void 0 || typeof credentials === "function") return credentials;
|
|
324
|
+
const { accessKeyId, secretAccessKey, sessionToken, ...rest } = credentials;
|
|
325
|
+
if (typeof accessKeyId !== "function" && typeof secretAccessKey !== "function" && typeof sessionToken !== "function") return credentials;
|
|
326
|
+
return async () => ({
|
|
327
|
+
...rest,
|
|
328
|
+
accessKeyId: await resolveLazy(accessKeyId),
|
|
329
|
+
secretAccessKey: await resolveLazy(secretAccessKey),
|
|
330
|
+
...sessionToken === void 0 ? {} : { sessionToken: await resolveLazy(sessionToken) }
|
|
331
|
+
});
|
|
332
|
+
};
|
|
333
|
+
//#endregion
|
|
317
334
|
//#region src/dynamoDB.ts
|
|
318
335
|
/** The DynamoDB client ignores the CloudFront and batching settings. */
|
|
319
|
-
const adapterOf = ({ tableName, ...clientConfig }) => {
|
|
320
|
-
const client = new DynamoDBClient(
|
|
336
|
+
const adapterOf = ({ tableName, credentials, ...clientConfig }) => {
|
|
337
|
+
const client = new DynamoDBClient({
|
|
338
|
+
...clientConfig,
|
|
339
|
+
credentials: toSdkCredentials(credentials)
|
|
340
|
+
});
|
|
321
341
|
const store = createDynamoDBStore({
|
|
322
342
|
client,
|
|
323
343
|
tableName
|
|
@@ -352,7 +372,10 @@ const marked = (target) => ({ [DATABASE_TARGET]: target });
|
|
|
352
372
|
*/
|
|
353
373
|
const dynamoDB = (config) => {
|
|
354
374
|
const { client, adapter } = adapterOf(config);
|
|
355
|
-
const cloudFront = createUpdateRouteInvalidation(
|
|
375
|
+
const cloudFront = createUpdateRouteInvalidation({
|
|
376
|
+
...config,
|
|
377
|
+
credentials: toSdkCredentials(config.credentials)
|
|
378
|
+
});
|
|
356
379
|
return {
|
|
357
380
|
...createEngineDatabase({
|
|
358
381
|
name: "dynamoDB",
|
|
@@ -499,8 +522,11 @@ const cloudFrontDownloadUrl = (config) => {
|
|
|
499
522
|
const PRESIGNED_URL_EXPIRES_IN_SECONDS = 3600;
|
|
500
523
|
const isObjectNotFoundError = (error) => error instanceof Error && (error.name === "NotFound" || error.name === "NoSuchKey");
|
|
501
524
|
function s3Storage(config) {
|
|
502
|
-
const { bucketName, basePath, getDownloadUrl, ...s3Config } = config;
|
|
503
|
-
const client = new S3Client(applyS3RuntimeAwsConfig(
|
|
525
|
+
const { bucketName, basePath, getDownloadUrl, credentials, ...s3Config } = config;
|
|
526
|
+
const client = new S3Client(applyS3RuntimeAwsConfig({
|
|
527
|
+
...s3Config,
|
|
528
|
+
credentials: toSdkCredentials(credentials)
|
|
529
|
+
}));
|
|
504
530
|
const normalizedBasePath = basePath?.replace(/^\/+|\/+$/g, "") ?? "";
|
|
505
531
|
const getStorageKey = createStorageKeyBuilder(normalizedBasePath);
|
|
506
532
|
const getListPrefix = (prefix = "") => {
|
package/dist/init/index.cjs
CHANGED
|
@@ -6579,10 +6579,30 @@ async apply() {
|
|
|
6579
6579
|
};
|
|
6580
6580
|
};
|
|
6581
6581
|
//#endregion
|
|
6582
|
+
//#region src/lazyCredentials.ts
|
|
6583
|
+
/**
|
|
6584
|
+
* `credentials` as the AWS SDK takes them: access keys with a lazy field
|
|
6585
|
+
* become a provider, which the SDK calls once, on its first request.
|
|
6586
|
+
*/
|
|
6587
|
+
const toSdkCredentials = (credentials) => {
|
|
6588
|
+
if (credentials === void 0 || typeof credentials === "function") return credentials;
|
|
6589
|
+
const { accessKeyId, secretAccessKey, sessionToken, ...rest } = credentials;
|
|
6590
|
+
if (typeof accessKeyId !== "function" && typeof secretAccessKey !== "function" && typeof sessionToken !== "function") return credentials;
|
|
6591
|
+
return async () => ({
|
|
6592
|
+
...rest,
|
|
6593
|
+
accessKeyId: await (0, _hot_updater_plugin_core.resolveLazy)(accessKeyId),
|
|
6594
|
+
secretAccessKey: await (0, _hot_updater_plugin_core.resolveLazy)(secretAccessKey),
|
|
6595
|
+
...sessionToken === void 0 ? {} : { sessionToken: await (0, _hot_updater_plugin_core.resolveLazy)(sessionToken) }
|
|
6596
|
+
});
|
|
6597
|
+
};
|
|
6598
|
+
//#endregion
|
|
6582
6599
|
//#region src/dynamoDB.ts
|
|
6583
6600
|
/** The DynamoDB client ignores the CloudFront and batching settings. */
|
|
6584
|
-
const adapterOf = ({ tableName, ...clientConfig }) => {
|
|
6585
|
-
const client = new _aws_sdk_client_dynamodb.DynamoDBClient(
|
|
6601
|
+
const adapterOf = ({ tableName, credentials, ...clientConfig }) => {
|
|
6602
|
+
const client = new _aws_sdk_client_dynamodb.DynamoDBClient({
|
|
6603
|
+
...clientConfig,
|
|
6604
|
+
credentials: toSdkCredentials(credentials)
|
|
6605
|
+
});
|
|
6586
6606
|
const store = createDynamoDBStore({
|
|
6587
6607
|
client,
|
|
6588
6608
|
tableName
|
|
@@ -6617,7 +6637,10 @@ const marked = (target) => ({ [DATABASE_TARGET]: target });
|
|
|
6617
6637
|
*/
|
|
6618
6638
|
const dynamoDB = (config) => {
|
|
6619
6639
|
const { client, adapter } = adapterOf(config);
|
|
6620
|
-
const cloudFront = createUpdateRouteInvalidation(
|
|
6640
|
+
const cloudFront = createUpdateRouteInvalidation({
|
|
6641
|
+
...config,
|
|
6642
|
+
credentials: toSdkCredentials(config.credentials)
|
|
6643
|
+
});
|
|
6621
6644
|
return {
|
|
6622
6645
|
...(0, _hot_updater_plugin_core.createEngineDatabase)({
|
|
6623
6646
|
name: "dynamoDB",
|
|
@@ -8419,10 +8442,11 @@ var SSMKeyPairManager = class {
|
|
|
8419
8442
|
//#region iac/templates.ts
|
|
8420
8443
|
/**
|
|
8421
8444
|
* The config init writes. With the `resources` init set up, it names them,
|
|
8422
|
-
* and an account's access keys are read with `
|
|
8445
|
+
* and an account's access keys are read with `secret()`, from the
|
|
8423
8446
|
* environment and `.env.hotupdater`, then the config's `secrets` adapter.
|
|
8424
|
-
* Without them, as the agent scaffold writes it
|
|
8425
|
-
*
|
|
8447
|
+
* Without them, as the agent scaffold writes it before the agent creates the
|
|
8448
|
+
* resources, it reads their names from the environment, where the agent
|
|
8449
|
+
* records them. A profile or SSO sign-in is each person's own.
|
|
8426
8450
|
*/
|
|
8427
8451
|
const getConfigScaffold = (build, authMode, resources) => {
|
|
8428
8452
|
const value = (envKey, resolved) => resolved === void 0 ? `process.env.${envKey}!` : JSON.stringify(resolved);
|
|
@@ -8478,31 +8502,19 @@ const awsOptions = {
|
|
|
8478
8502
|
};`.trim()
|
|
8479
8503
|
}];
|
|
8480
8504
|
break;
|
|
8481
|
-
case "account":
|
|
8482
|
-
|
|
8483
|
-
|
|
8484
|
-
|
|
8485
|
-
|
|
8486
|
-
code: resources === void 0 ? `
|
|
8505
|
+
case "account": helperStatements = [{
|
|
8506
|
+
name: "awsOptions",
|
|
8507
|
+
strategy: "merge-object",
|
|
8508
|
+
replaceIncompatibleProperties: ["credentials"],
|
|
8509
|
+
code: `
|
|
8487
8510
|
const awsOptions = {
|
|
8488
8511
|
region: ${region},
|
|
8489
8512
|
credentials: {
|
|
8490
|
-
accessKeyId:
|
|
8491
|
-
secretAccessKey:
|
|
8492
|
-
},
|
|
8493
|
-
};`.trim() : `
|
|
8494
|
-
const awsOptions = {
|
|
8495
|
-
region: ${region},
|
|
8496
|
-
credentials: async () => {
|
|
8497
|
-
const env = await deploySecrets();
|
|
8498
|
-
return {
|
|
8499
|
-
accessKeyId: env.HOT_UPDATER_S3_ACCESS_KEY_ID,
|
|
8500
|
-
secretAccessKey: env.HOT_UPDATER_S3_SECRET_ACCESS_KEY,
|
|
8501
|
-
};
|
|
8513
|
+
accessKeyId: secret("HOT_UPDATER_S3_ACCESS_KEY_ID"),
|
|
8514
|
+
secretAccessKey: secret("HOT_UPDATER_S3_SECRET_ACCESS_KEY"),
|
|
8502
8515
|
},
|
|
8503
8516
|
};`.trim()
|
|
8504
|
-
|
|
8505
|
-
if (resources !== void 0) helperStatements.unshift((0, _hot_updater_cli_tools.secretEnvHelper)("deploySecrets", ["HOT_UPDATER_S3_ACCESS_KEY_ID", "HOT_UPDATER_S3_SECRET_ACCESS_KEY"]));
|
|
8517
|
+
}];
|
|
8506
8518
|
}
|
|
8507
8519
|
const builder = new _hot_updater_cli_tools.ConfigBuilder().setBuildType(build).setStorage(storageConfig).setDatabase(databaseConfig).setPlugins({
|
|
8508
8520
|
imports: [{
|
|
@@ -8528,9 +8540,9 @@ const awsOptions = {
|
|
|
8528
8540
|
named: [authMode.profile ? "fromIni" : "fromNodeProviderChain"]
|
|
8529
8541
|
});
|
|
8530
8542
|
break;
|
|
8531
|
-
case "account":
|
|
8543
|
+
case "account": builder.addImport({
|
|
8532
8544
|
pkg: "hot-updater",
|
|
8533
|
-
named: ["
|
|
8545
|
+
named: ["secret"]
|
|
8534
8546
|
});
|
|
8535
8547
|
}
|
|
8536
8548
|
return (0, _hot_updater_cli_tools.createHotUpdaterConfigScaffoldFromBuilder)(builder, { helperStatements });
|
package/dist/init/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
-
import { ConfigBuilder, InitError, MissingInitInputsError, assembleServer, assertInfrastructureGenerationAtUrl, assertInfrastructureGenerationPayload, assertInitProviderInputs, colors, confirmInitInputPersistence, copyDirToTmp, createHotUpdaterConfigScaffoldFromBuilder, createZip, ensureInstallPackages, getCwd, getHotUpdaterInitInputEnv, getInitProviderEnvVars, getInitProviderTextPromptValues, link, makeEnv, p, printAppSetup, provisionClientCredential, readHotUpdaterInitEnv, resolveInitProviderInput,
|
|
2
|
+
import { ConfigBuilder, InitError, MissingInitInputsError, assembleServer, assertInfrastructureGenerationAtUrl, assertInfrastructureGenerationPayload, assertInitProviderInputs, colors, confirmInitInputPersistence, copyDirToTmp, createHotUpdaterConfigScaffoldFromBuilder, createZip, ensureInstallPackages, getCwd, getHotUpdaterInitInputEnv, getInitProviderEnvVars, getInitProviderTextPromptValues, link, makeEnv, p, printAppSetup, provisionClientCredential, readHotUpdaterInitEnv, resolveInitProviderInput, transformEnv, writeHotUpdaterFiles } from "@hot-updater/cli-tools";
|
|
3
3
|
import { apiKeys, insights, remoteConfig } from "@hot-updater/server/plugins";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { ChildProcess, execFile, spawn, spawnSync } from "node:child_process";
|
|
@@ -18,7 +18,7 @@ import { finished } from "node:stream/promises";
|
|
|
18
18
|
import { Duplex, PassThrough, Readable, Transform, Writable, getDefaultHighWaterMark } from "node:stream";
|
|
19
19
|
import { Buffer as Buffer$1 } from "node:buffer";
|
|
20
20
|
import { CreateTableCommand, DescribeTableCommand, DescribeTimeToLiveCommand, DynamoDB, DynamoDBClient, UpdateTimeToLiveCommand, waitUntilTableExists } from "@aws-sdk/client-dynamodb";
|
|
21
|
-
import { SETTINGS_TABLE, aggregateBatchingTables, createEngineDatabase, createKvAdapter, encodeKvKey, migrateCoreSchema, toolingTargetOf } from "@hot-updater/plugin-core";
|
|
21
|
+
import { SETTINGS_TABLE, aggregateBatchingTables, createEngineDatabase, createKvAdapter, encodeKvKey, migrateCoreSchema, resolveLazy, toolingTargetOf } from "@hot-updater/plugin-core";
|
|
22
22
|
import { CloudFront, CloudFrontClient, CreateInvalidationCommand, GetInvalidationCommand } from "@aws-sdk/client-cloudfront";
|
|
23
23
|
import { BatchGetCommand, BatchWriteCommand, DynamoDBDocumentClient, QueryCommand, TransactWriteCommand } from "@aws-sdk/lib-dynamodb";
|
|
24
24
|
import { fromIni, fromNodeProviderChain, fromSSO } from "@aws-sdk/credential-providers";
|
|
@@ -6574,10 +6574,30 @@ async apply() {
|
|
|
6574
6574
|
};
|
|
6575
6575
|
};
|
|
6576
6576
|
//#endregion
|
|
6577
|
+
//#region src/lazyCredentials.ts
|
|
6578
|
+
/**
|
|
6579
|
+
* `credentials` as the AWS SDK takes them: access keys with a lazy field
|
|
6580
|
+
* become a provider, which the SDK calls once, on its first request.
|
|
6581
|
+
*/
|
|
6582
|
+
const toSdkCredentials = (credentials) => {
|
|
6583
|
+
if (credentials === void 0 || typeof credentials === "function") return credentials;
|
|
6584
|
+
const { accessKeyId, secretAccessKey, sessionToken, ...rest } = credentials;
|
|
6585
|
+
if (typeof accessKeyId !== "function" && typeof secretAccessKey !== "function" && typeof sessionToken !== "function") return credentials;
|
|
6586
|
+
return async () => ({
|
|
6587
|
+
...rest,
|
|
6588
|
+
accessKeyId: await resolveLazy(accessKeyId),
|
|
6589
|
+
secretAccessKey: await resolveLazy(secretAccessKey),
|
|
6590
|
+
...sessionToken === void 0 ? {} : { sessionToken: await resolveLazy(sessionToken) }
|
|
6591
|
+
});
|
|
6592
|
+
};
|
|
6593
|
+
//#endregion
|
|
6577
6594
|
//#region src/dynamoDB.ts
|
|
6578
6595
|
/** The DynamoDB client ignores the CloudFront and batching settings. */
|
|
6579
|
-
const adapterOf = ({ tableName, ...clientConfig }) => {
|
|
6580
|
-
const client = new DynamoDBClient(
|
|
6596
|
+
const adapterOf = ({ tableName, credentials, ...clientConfig }) => {
|
|
6597
|
+
const client = new DynamoDBClient({
|
|
6598
|
+
...clientConfig,
|
|
6599
|
+
credentials: toSdkCredentials(credentials)
|
|
6600
|
+
});
|
|
6581
6601
|
const store = createDynamoDBStore({
|
|
6582
6602
|
client,
|
|
6583
6603
|
tableName
|
|
@@ -6612,7 +6632,10 @@ const marked = (target) => ({ [DATABASE_TARGET]: target });
|
|
|
6612
6632
|
*/
|
|
6613
6633
|
const dynamoDB = (config) => {
|
|
6614
6634
|
const { client, adapter } = adapterOf(config);
|
|
6615
|
-
const cloudFront = createUpdateRouteInvalidation(
|
|
6635
|
+
const cloudFront = createUpdateRouteInvalidation({
|
|
6636
|
+
...config,
|
|
6637
|
+
credentials: toSdkCredentials(config.credentials)
|
|
6638
|
+
});
|
|
6616
6639
|
return {
|
|
6617
6640
|
...createEngineDatabase({
|
|
6618
6641
|
name: "dynamoDB",
|
|
@@ -8414,10 +8437,11 @@ var SSMKeyPairManager = class {
|
|
|
8414
8437
|
//#region iac/templates.ts
|
|
8415
8438
|
/**
|
|
8416
8439
|
* The config init writes. With the `resources` init set up, it names them,
|
|
8417
|
-
* and an account's access keys are read with `
|
|
8440
|
+
* and an account's access keys are read with `secret()`, from the
|
|
8418
8441
|
* environment and `.env.hotupdater`, then the config's `secrets` adapter.
|
|
8419
|
-
* Without them, as the agent scaffold writes it
|
|
8420
|
-
*
|
|
8442
|
+
* Without them, as the agent scaffold writes it before the agent creates the
|
|
8443
|
+
* resources, it reads their names from the environment, where the agent
|
|
8444
|
+
* records them. A profile or SSO sign-in is each person's own.
|
|
8421
8445
|
*/
|
|
8422
8446
|
const getConfigScaffold = (build, authMode, resources) => {
|
|
8423
8447
|
const value = (envKey, resolved) => resolved === void 0 ? `process.env.${envKey}!` : JSON.stringify(resolved);
|
|
@@ -8473,31 +8497,19 @@ const awsOptions = {
|
|
|
8473
8497
|
};`.trim()
|
|
8474
8498
|
}];
|
|
8475
8499
|
break;
|
|
8476
|
-
case "account":
|
|
8477
|
-
|
|
8478
|
-
|
|
8479
|
-
|
|
8480
|
-
|
|
8481
|
-
code: resources === void 0 ? `
|
|
8500
|
+
case "account": helperStatements = [{
|
|
8501
|
+
name: "awsOptions",
|
|
8502
|
+
strategy: "merge-object",
|
|
8503
|
+
replaceIncompatibleProperties: ["credentials"],
|
|
8504
|
+
code: `
|
|
8482
8505
|
const awsOptions = {
|
|
8483
8506
|
region: ${region},
|
|
8484
8507
|
credentials: {
|
|
8485
|
-
accessKeyId:
|
|
8486
|
-
secretAccessKey:
|
|
8487
|
-
},
|
|
8488
|
-
};`.trim() : `
|
|
8489
|
-
const awsOptions = {
|
|
8490
|
-
region: ${region},
|
|
8491
|
-
credentials: async () => {
|
|
8492
|
-
const env = await deploySecrets();
|
|
8493
|
-
return {
|
|
8494
|
-
accessKeyId: env.HOT_UPDATER_S3_ACCESS_KEY_ID,
|
|
8495
|
-
secretAccessKey: env.HOT_UPDATER_S3_SECRET_ACCESS_KEY,
|
|
8496
|
-
};
|
|
8508
|
+
accessKeyId: secret("HOT_UPDATER_S3_ACCESS_KEY_ID"),
|
|
8509
|
+
secretAccessKey: secret("HOT_UPDATER_S3_SECRET_ACCESS_KEY"),
|
|
8497
8510
|
},
|
|
8498
8511
|
};`.trim()
|
|
8499
|
-
|
|
8500
|
-
if (resources !== void 0) helperStatements.unshift(secretEnvHelper("deploySecrets", ["HOT_UPDATER_S3_ACCESS_KEY_ID", "HOT_UPDATER_S3_SECRET_ACCESS_KEY"]));
|
|
8512
|
+
}];
|
|
8501
8513
|
}
|
|
8502
8514
|
const builder = new ConfigBuilder().setBuildType(build).setStorage(storageConfig).setDatabase(databaseConfig).setPlugins({
|
|
8503
8515
|
imports: [{
|
|
@@ -8523,9 +8535,9 @@ const awsOptions = {
|
|
|
8523
8535
|
named: [authMode.profile ? "fromIni" : "fromNodeProviderChain"]
|
|
8524
8536
|
});
|
|
8525
8537
|
break;
|
|
8526
|
-
case "account":
|
|
8538
|
+
case "account": builder.addImport({
|
|
8527
8539
|
pkg: "hot-updater",
|
|
8528
|
-
named: ["
|
|
8540
|
+
named: ["secret"]
|
|
8529
8541
|
});
|
|
8530
8542
|
}
|
|
8531
8543
|
return createHotUpdaterConfigScaffoldFromBuilder(builder, { helperStatements });
|
package/dist/lambda/index.cjs
CHANGED
|
@@ -1437,6 +1437,10 @@ const semverSatisfies = (targetAppVersion, currentVersion) => {
|
|
|
1437
1437
|
return satisfies(currentCoerce, targetAppVersion);
|
|
1438
1438
|
};
|
|
1439
1439
|
//#endregion
|
|
1440
|
+
//#region ../plugin-core/dist/types/index.mjs
|
|
1441
|
+
/** The value of a `Lazy`, calling its function. */
|
|
1442
|
+
const resolveLazy = async (value) => typeof value === "function" ? await value() : value;
|
|
1443
|
+
//#endregion
|
|
1440
1444
|
//#region ../plugin-core/dist/serverPlugin/definePlugin.mjs
|
|
1441
1445
|
/** Declares a plugin; Hot Updater's own plugins and third-party ones use the same contract. */
|
|
1442
1446
|
const definePlugin = (plugin) => plugin;
|
|
@@ -4707,7 +4711,7 @@ const createKvAdapter = ({ store, tablePrefix = "" }) => {
|
|
|
4707
4711
|
};
|
|
4708
4712
|
//#endregion
|
|
4709
4713
|
//#region ../../packages/server/dist/version.mjs
|
|
4710
|
-
const HOT_UPDATER_SERVER_VERSION = "1.2.0-rc.
|
|
4714
|
+
const HOT_UPDATER_SERVER_VERSION = "1.2.0-rc.8";
|
|
4711
4715
|
//#endregion
|
|
4712
4716
|
//#region ../../packages/server/dist/handlerVersionRoutes.mjs
|
|
4713
4717
|
/**
|
|
@@ -14295,10 +14299,30 @@ async apply() {
|
|
|
14295
14299
|
};
|
|
14296
14300
|
};
|
|
14297
14301
|
//#endregion
|
|
14302
|
+
//#region src/lazyCredentials.ts
|
|
14303
|
+
/**
|
|
14304
|
+
* `credentials` as the AWS SDK takes them: access keys with a lazy field
|
|
14305
|
+
* become a provider, which the SDK calls once, on its first request.
|
|
14306
|
+
*/
|
|
14307
|
+
const toSdkCredentials = (credentials) => {
|
|
14308
|
+
if (credentials === void 0 || typeof credentials === "function") return credentials;
|
|
14309
|
+
const { accessKeyId, secretAccessKey, sessionToken, ...rest } = credentials;
|
|
14310
|
+
if (typeof accessKeyId !== "function" && typeof secretAccessKey !== "function" && typeof sessionToken !== "function") return credentials;
|
|
14311
|
+
return async () => ({
|
|
14312
|
+
...rest,
|
|
14313
|
+
accessKeyId: await resolveLazy(accessKeyId),
|
|
14314
|
+
secretAccessKey: await resolveLazy(secretAccessKey),
|
|
14315
|
+
...sessionToken === void 0 ? {} : { sessionToken: await resolveLazy(sessionToken) }
|
|
14316
|
+
});
|
|
14317
|
+
};
|
|
14318
|
+
//#endregion
|
|
14298
14319
|
//#region src/dynamoDB.ts
|
|
14299
14320
|
/** The DynamoDB client ignores the CloudFront and batching settings. */
|
|
14300
|
-
const adapterOf = ({ tableName, ...clientConfig }) => {
|
|
14301
|
-
const client = new _aws_sdk_client_dynamodb.DynamoDBClient(
|
|
14321
|
+
const adapterOf = ({ tableName, credentials, ...clientConfig }) => {
|
|
14322
|
+
const client = new _aws_sdk_client_dynamodb.DynamoDBClient({
|
|
14323
|
+
...clientConfig,
|
|
14324
|
+
credentials: toSdkCredentials(credentials)
|
|
14325
|
+
});
|
|
14302
14326
|
const store = createDynamoDBStore({
|
|
14303
14327
|
client,
|
|
14304
14328
|
tableName
|
|
@@ -14323,7 +14347,10 @@ const marked = (target) => ({ [DATABASE_TARGET]: target });
|
|
|
14323
14347
|
*/
|
|
14324
14348
|
const dynamoDB = (config) => {
|
|
14325
14349
|
const { client, adapter } = adapterOf(config);
|
|
14326
|
-
const cloudFront = createUpdateRouteInvalidation(
|
|
14350
|
+
const cloudFront = createUpdateRouteInvalidation({
|
|
14351
|
+
...config,
|
|
14352
|
+
credentials: toSdkCredentials(config.credentials)
|
|
14353
|
+
});
|
|
14327
14354
|
return {
|
|
14328
14355
|
...createEngineDatabase({
|
|
14329
14356
|
name: "dynamoDB",
|
|
@@ -14345,8 +14372,11 @@ const dynamoDB = (config) => {
|
|
|
14345
14372
|
const PRESIGNED_URL_EXPIRES_IN_SECONDS = 3600;
|
|
14346
14373
|
const isObjectNotFoundError = (error) => error instanceof Error && (error.name === "NotFound" || error.name === "NoSuchKey");
|
|
14347
14374
|
function s3Storage(config) {
|
|
14348
|
-
const { bucketName, basePath, getDownloadUrl, ...s3Config } = config;
|
|
14349
|
-
const client = new _aws_sdk_client_s3.S3Client(applyS3RuntimeAwsConfig(
|
|
14375
|
+
const { bucketName, basePath, getDownloadUrl, credentials, ...s3Config } = config;
|
|
14376
|
+
const client = new _aws_sdk_client_s3.S3Client(applyS3RuntimeAwsConfig({
|
|
14377
|
+
...s3Config,
|
|
14378
|
+
credentials: toSdkCredentials(credentials)
|
|
14379
|
+
}));
|
|
14350
14380
|
const normalizedBasePath = basePath?.replace(/^\/+|\/+$/g, "") ?? "";
|
|
14351
14381
|
const getStorageKey = createStorageKeyBuilder(normalizedBasePath);
|
|
14352
14382
|
const getListPrefix = (prefix = "") => {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hot-updater/aws",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.2.0-rc.
|
|
4
|
+
"version": "1.2.0-rc.8",
|
|
5
5
|
"description": "React Native OTA solution for self-hosted",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
7
7
|
"module": "dist/index.mjs",
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
"es-toolkit": "^1.32.0",
|
|
46
46
|
"execa": "9.5.2",
|
|
47
47
|
"mime": "^4.0.4",
|
|
48
|
-
"@hot-updater/protocol": "1.2.0-rc.
|
|
49
|
-
"@hot-updater/
|
|
50
|
-
"@hot-updater/
|
|
48
|
+
"@hot-updater/protocol": "1.2.0-rc.8",
|
|
49
|
+
"@hot-updater/test-utils": "1.2.0-rc.8",
|
|
50
|
+
"@hot-updater/mock": "1.2.0-rc.8"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
53
|
"@aws-sdk/client-cloudfront": "3.1066.0",
|
|
@@ -64,9 +64,9 @@
|
|
|
64
64
|
"@aws-sdk/lib-dynamodb": "3.1066.0",
|
|
65
65
|
"@aws-sdk/s3-request-presigner": "3.1066.0",
|
|
66
66
|
"hono": "4.12.34",
|
|
67
|
-
"@hot-updater/cli-tools": "1.2.0-rc.
|
|
68
|
-
"@hot-updater/plugin-core": "1.2.0-rc.
|
|
69
|
-
"@hot-updater/server": "1.2.0-rc.
|
|
67
|
+
"@hot-updater/cli-tools": "1.2.0-rc.8",
|
|
68
|
+
"@hot-updater/plugin-core": "1.2.0-rc.8",
|
|
69
|
+
"@hot-updater/server": "1.2.0-rc.8"
|
|
70
70
|
},
|
|
71
71
|
"scripts": {
|
|
72
72
|
"build": "tsdown",
|