@stacksjs/ts-cloud 0.5.3 → 0.5.4

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.
Files changed (3) hide show
  1. package/dist/bin/cli.js +357 -357
  2. package/dist/index.js +43 -12
  3. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -26359,9 +26359,12 @@ function composeServerlessAppTemplate(opts) {
26359
26359
  };
26360
26360
  }
26361
26361
  if (hasVpc && needsDataVpc) {
26362
+ if (!app.vpc?.id)
26363
+ throw new Error("serverless app: data services (elasticache / aurora-serverless / rdsProxy / efs) need app.vpc.id (the VPC id) so the managed security group is created in the right VPC.");
26362
26364
  resources.DataSecurityGroup = {
26363
26365
  Type: "AWS::EC2::SecurityGroup",
26364
26366
  Properties: {
26367
+ VpcId: app.vpc.id,
26365
26368
  GroupDescription: `${slug}-${environment} serverless data access`,
26366
26369
  SecurityGroupIngress: [{ IpProtocol: "-1", CidrIp: "10.0.0.0/8" }]
26367
26370
  }
@@ -26442,6 +26445,7 @@ function composeServerlessAppTemplate(opts) {
26442
26445
  Engine: "aurora-mysql",
26443
26446
  EngineMode: "provisioned",
26444
26447
  DBClusterIdentifier: `${slug}-${environment}-db`,
26448
+ DatabaseName: "app",
26445
26449
  MasterUsername: Fn2.sub("{{resolve:secretsmanager:${DbSecret}:SecretString:username}}"),
26446
26450
  MasterUserPassword: Fn2.sub("{{resolve:secretsmanager:${DbSecret}:SecretString:password}}"),
26447
26451
  ServerlessV2ScalingConfiguration: { MinCapacity: 0.5, MaxCapacity: 4 },
@@ -26488,6 +26492,15 @@ function composeServerlessAppTemplate(opts) {
26488
26492
  RequireTLS: false
26489
26493
  }
26490
26494
  };
26495
+ resources.DbProxyTargetGroup = {
26496
+ Type: "AWS::RDS::DBProxyTargetGroup",
26497
+ DependsOn: ["DbInstance"],
26498
+ Properties: {
26499
+ DBProxyName: Fn2.ref("DbProxy"),
26500
+ TargetGroupName: "default",
26501
+ DBClusterIdentifiers: [Fn2.ref("DbCluster")]
26502
+ }
26503
+ };
26491
26504
  outputs.DbProxyEndpoint = { Description: "RDS Proxy endpoint", Value: Fn2.getAtt("DbProxy", "Endpoint") };
26492
26505
  }
26493
26506
  outputs.HttpFunctionName = { Description: "HTTP function name", Value: Fn2.ref("HttpFunction") };
@@ -57435,7 +57448,7 @@ var exports_serverless_image = {};
57435
57448
  __export(exports_serverless_image, {
57436
57449
  buildAndPushServerlessImage: () => buildAndPushServerlessImage
57437
57450
  });
57438
- import { execFileSync as execFileSync3, execSync as execSync3 } from "node:child_process";
57451
+ import { execFileSync as execFileSync3 } from "node:child_process";
57439
57452
  import { mkdirSync as mkdirSync7, mkdtempSync as mkdtempSync4, rmSync as rmSync4, writeFileSync as writeFileSync10 } from "node:fs";
57440
57453
  import { tmpdir as tmpdir4 } from "node:os";
57441
57454
  import { dirname as dirname7, join as join15 } from "node:path";
@@ -57497,12 +57510,17 @@ async function buildAndPushServerlessImage(opts) {
57497
57510
  throw new Error(`could not resolve ECR repository URI for ${repository}`);
57498
57511
  const imageUri = `${repoUri}:${tag}`;
57499
57512
  step2("docker build");
57500
- execFileSync3("docker", ["build", "--platform", platform, "-t", imageUri, stage], { stdio: "inherit" });
57501
- step2("ecr login");
57502
- const loginCmd = await ecr2.getDockerLoginCommand();
57503
- execSync3(loginCmd, { stdio: "inherit" });
57504
- step2("docker push");
57505
- execFileSync3("docker", ["push", imageUri], { stdio: "inherit" });
57513
+ execFileSync3("docker", ["build", "--platform", platform, "--provenance=false", "--sbom=false", "-t", imageUri, stage], { stdio: "inherit" });
57514
+ step2("ecr auth + push");
57515
+ const auth = await ecr2.getAuthorizationToken();
57516
+ const data = auth.authorizationData?.[0];
57517
+ if (!data?.authorizationToken || !data.proxyEndpoint)
57518
+ throw new Error("failed to get an ECR authorization token");
57519
+ const registry = data.proxyEndpoint.replace(/^https?:\/\//, "");
57520
+ const dockerConfig = join15(stage, ".docker");
57521
+ mkdirSync7(dockerConfig, { recursive: true });
57522
+ writeFileSync10(join15(dockerConfig, "config.json"), JSON.stringify({ auths: { [registry]: { auth: data.authorizationToken } } }));
57523
+ execFileSync3("docker", ["push", imageUri], { stdio: "inherit", env: { ...process.env, DOCKER_CONFIG: dockerConfig } });
57506
57524
  info(`Image: ${imageUri}`);
57507
57525
  return { imageUri, tag, handlers };
57508
57526
  } finally {
@@ -83385,6 +83403,19 @@ async function deployServerlessApp(config6, environment, opts = {}) {
83385
83403
  }
83386
83404
  step("Resolving secrets");
83387
83405
  const secrets = await resolveSecrets(app, region);
83406
+ if (app.database?.connection === "aurora-serverless") {
83407
+ try {
83408
+ const sm = new SecretsManagerClient(region);
83409
+ const v = await sm.getSecretValue({ SecretId: `${slug}/${environment}/db` });
83410
+ const creds = JSON.parse(v.SecretString ?? "{}");
83411
+ if (creds.username)
83412
+ secrets.DB_USERNAME = creds.username;
83413
+ if (creds.password)
83414
+ secrets.DB_PASSWORD = creds.password;
83415
+ } catch (err) {
83416
+ warn(`Could not resolve Aurora DB credentials: ${err.message}`);
83417
+ }
83418
+ }
83388
83419
  if (!await s32.bucketExists(artifactBucket)) {
83389
83420
  await s32.createBucket(artifactBucket);
83390
83421
  }
@@ -83584,7 +83615,7 @@ function planServices(services) {
83584
83615
  const packages = [];
83585
83616
  const names = [];
83586
83617
  if (enabled(services.mysql)) {
83587
- packages.push("mysql.com");
83618
+ packages.push(typeof services.mysql === "object" && services.mysql.version ? `mysql.com@${services.mysql.version}` : "mysql.com@8.0.43");
83588
83619
  names.push("mysql");
83589
83620
  } else if (enabled(services.mariadb)) {
83590
83621
  packages.push(PANTRY_PACKAGES.mariadb);
@@ -84785,7 +84816,7 @@ await init_dist2();
84785
84816
  import { existsSync as existsSync18, readFileSync as readFileSync15 } from "node:fs";
84786
84817
  import { homedir as homedir7 } from "node:os";
84787
84818
  import { join as join18 } from "node:path";
84788
- import { execSync as execSync5 } from "node:child_process";
84819
+ import { execSync as execSync3 } from "node:child_process";
84789
84820
 
84790
84821
  // src/drivers/hetzner/client.ts
84791
84822
  var DEFAULT_API_URL = "https://api.hetzner.cloud/v1";
@@ -85721,7 +85752,7 @@ class HetznerDriver {
85721
85752
  let lastErr;
85722
85753
  while (Date.now() - start < sshTimeoutMs) {
85723
85754
  try {
85724
- execSync5(`ssh ${this.sshBaseArgs(host, ["-o", "ConnectTimeout=5"]).map((a) => `"${a.replace(/"/g, "\\\"")}"`).join(" ")} true`, {
85755
+ execSync3(`ssh ${this.sshBaseArgs(host, ["-o", "ConnectTimeout=5"]).map((a) => `"${a.replace(/"/g, "\\\"")}"`).join(" ")} true`, {
85725
85756
  stdio: "pipe",
85726
85757
  maxBuffer: SSH_MAX_BUFFER
85727
85758
  });
@@ -85781,7 +85812,7 @@ ${out}`);
85781
85812
  ];
85782
85813
  }
85783
85814
  scpToHost(host, localPath, remotePath) {
85784
- execSync5([
85815
+ execSync3([
85785
85816
  "scp",
85786
85817
  "-i",
85787
85818
  this.sshPrivateKeyPath,
@@ -85794,7 +85825,7 @@ ${out}`);
85794
85825
  }
85795
85826
  sshExec(host, script) {
85796
85827
  const escaped = script.replace(/'/g, `'\\''`);
85797
- return execSync5(`ssh ${this.sshBaseArgs(host).map((a) => `"${a.replace(/"/g, "\\\"")}"`).join(" ")} '${escaped}'`, {
85828
+ return execSync3(`ssh ${this.sshBaseArgs(host).map((a) => `"${a.replace(/"/g, "\\\"")}"`).join(" ")} '${escaped}'`, {
85798
85829
  encoding: "utf8",
85799
85830
  stdio: ["pipe", "pipe", "pipe"],
85800
85831
  maxBuffer: SSH_MAX_BUFFER
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stacksjs/ts-cloud",
3
3
  "type": "module",
4
- "version": "0.5.3",
4
+ "version": "0.5.4",
5
5
  "description": "A lightweight, performant infrastructure-as-code library and CLI for deploying both server-based (EC2) and serverless applications.",
6
6
  "author": "Chris Breuer <chris@stacksjs.com>",
7
7
  "license": "MIT",
@@ -89,8 +89,8 @@
89
89
  "test": "bun test"
90
90
  },
91
91
  "dependencies": {
92
- "@ts-cloud/aws-types": "0.5.3",
93
- "@ts-cloud/core": "0.5.3",
92
+ "@ts-cloud/aws-types": "0.5.4",
93
+ "@ts-cloud/core": "0.5.4",
94
94
  "@stacksjs/ts-xml": "^0.1.0"
95
95
  },
96
96
  "devDependencies": {