@intelligems/sst 2.49.3 → 2.49.6-ig.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.
@@ -92,9 +92,10 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
92
92
  return;
93
93
  if (info.enableLiveDev === false)
94
94
  return;
95
+ const buildType = evt.properties.monoBundle ? "(mono-bundle)" : "(individual)";
95
96
  Colors.line(info.runtime === "container"
96
- ? Colors.dim(Colors.prefix, "Built", info.handler, "container")
97
- : Colors.dim(Colors.prefix, "Built", info.handler));
97
+ ? Colors.dim(Colors.prefix, "Built", info.handler, "container", buildType)
98
+ : Colors.dim(Colors.prefix, "Built", info.handler, buildType));
98
99
  });
99
100
  bus.subscribe("function.build.failed", async (evt) => {
100
101
  const info = useFunctions().fromID(evt.properties.functionID);
@@ -24,6 +24,7 @@ declare const supportedRuntimes: {
24
24
  "python3.10": CDKRuntime;
25
25
  "python3.11": CDKRuntime;
26
26
  "python3.12": CDKRuntime;
27
+ "python3.13": CDKRuntime;
27
28
  "dotnetcore3.1": CDKRuntime;
28
29
  dotnet6: CDKRuntime;
29
30
  dotnet8: CDKRuntime;
@@ -798,7 +799,7 @@ export declare class Function extends CDKFunction implements SSTConstruct {
798
799
  type: "Function";
799
800
  data: {
800
801
  arn: string;
801
- runtime: "container" | "rust" | "nodejs16.x" | "nodejs18.x" | "nodejs20.x" | "nodejs22.x" | "python3.7" | "python3.8" | "python3.9" | "python3.10" | "python3.11" | "python3.12" | "dotnetcore3.1" | "dotnet6" | "dotnet8" | "java8" | "java11" | "java17" | "java21" | "go1.x" | "go" | undefined;
802
+ runtime: "container" | "rust" | "nodejs16.x" | "nodejs18.x" | "nodejs20.x" | "nodejs22.x" | "python3.7" | "python3.8" | "python3.9" | "python3.10" | "python3.11" | "python3.12" | "python3.13" | "dotnetcore3.1" | "dotnet6" | "dotnet8" | "java8" | "java11" | "java17" | "java21" | "go1.x" | "go" | undefined;
802
803
  handler: string | undefined;
803
804
  missingSourcemap: boolean | undefined;
804
805
  localId: string;
@@ -43,6 +43,7 @@ const supportedRuntimes = {
43
43
  "python3.10": CDKRuntime.PYTHON_3_10,
44
44
  "python3.11": CDKRuntime.PYTHON_3_11,
45
45
  "python3.12": CDKRuntime.PYTHON_3_12,
46
+ "python3.13": CDKRuntime.PYTHON_3_13,
46
47
  "dotnetcore3.1": CDKRuntime.DOTNET_CORE_3_1,
47
48
  dotnet6: CDKRuntime.DOTNET_6,
48
49
  dotnet8: CDKRuntime.DOTNET_8,
@@ -216,18 +217,18 @@ export class Function extends CDKFunction {
216
217
  ? {
217
218
  code: Code.fromInline("export function placeholder() {}"),
218
219
  handler: "index.placeholder",
219
- runtime: CDKRuntime.NODEJS_20_X,
220
+ runtime: CDKRuntime.NODEJS_22_X,
220
221
  layers: undefined,
221
222
  }
222
223
  : props.code ? {
223
224
  code: props.code,
224
225
  handler: "index.handler",
225
- runtime: CDKRuntime.NODEJS_20_X,
226
+ runtime: CDKRuntime.NODEJS_22_X,
226
227
  layers: Function.buildLayers(scope, id, props),
227
228
  } : {
228
229
  code: Code.fromInline("export function placeholder() {}"),
229
230
  handler: "index.placeholder",
230
- runtime: CDKRuntime.NODEJS_20_X,
231
+ runtime: CDKRuntime.NODEJS_22_X,
231
232
  layers: Function.buildLayers(scope, id, props),
232
233
  }),
233
234
  architecture,
package/credentials.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import path from "path";
2
+ import { fileURLToPath, pathToFileURL } from "url";
2
3
  import { fromNodeProviderChain } from "@aws-sdk/credential-providers";
3
4
  import { GetCallerIdentityCommand, STSClient } from "@aws-sdk/client-sts";
4
5
  import { Logger } from "./logger.js";
@@ -121,9 +122,9 @@ export function useAWSClient(client, force = false) {
121
122
  }
122
123
  export const useAWSProvider = lazy(async () => {
123
124
  const cdkToolkitUrl = await import.meta.resolve("@aws-cdk/toolkit-lib");
124
- const cdkToolkitPath = new URL(cdkToolkitUrl).pathname;
125
- const { SdkProvider } = await import(path.resolve(cdkToolkitPath, "..", "api", "aws-auth", "sdk-provider.js"));
126
- const { IoHelper } = await import(path.resolve(cdkToolkitPath, "..", "api", "io", "private", "io-helper.js"));
125
+ const cdkToolkitPath = fileURLToPath(cdkToolkitUrl);
126
+ const { SdkProvider } = await import(pathToFileURL(path.resolve(cdkToolkitPath, "..", "api", "aws-auth", "sdk-provider.js")).href);
127
+ const { IoHelper } = await import(pathToFileURL(path.resolve(cdkToolkitPath, "..", "api", "io", "private", "io-helper.js")).href);
127
128
  const project = useProject();
128
129
  return new SdkProvider(useAWSCredentialsProvider(), project.config.region, {
129
130
  ioHelper: IoHelper.fromActionAwareIoHost({
package/iot.js CHANGED
@@ -1,6 +1,8 @@
1
1
  import { IoTClient, DescribeEndpointCommand } from "@aws-sdk/client-iot";
2
2
  import { useAWSClient, useAWSCredentials } from "./credentials.js";
3
3
  import { VisibleError } from "./error.js";
4
+ import { lazy } from "./util/lazy.js";
5
+ import { Logger } from "./logger.js";
4
6
  export const useIOTEndpoint = lazy(async () => {
5
7
  const iot = useAWSClient(IoTClient);
6
8
  Logger.debug("Getting IoT endpoint");
@@ -15,10 +17,8 @@ export const useIOTEndpoint = lazy(async () => {
15
17
  import iot from "aws-iot-device-sdk";
16
18
  import { useBus } from "./bus.js";
17
19
  import { useProject } from "./project.js";
18
- import { Logger } from "./logger.js";
19
20
  import { useBootstrap } from "./bootstrap.js";
20
21
  import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
21
- import { lazy } from "./util/lazy.js";
22
22
  export const useIOT = lazy(async () => {
23
23
  const bus = useBus();
24
24
  const endpoint = await useIOTEndpoint();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "sideEffects": false,
3
3
  "name": "@intelligems/sst",
4
- "version": "2.49.3",
4
+ "version": "2.49.6-ig.2",
5
5
  "bin": {
6
6
  "sst": "cli/sst.js"
7
7
  },
package/package.json.bak CHANGED
@@ -5,7 +5,7 @@
5
5
  },
6
6
  "sideEffects": false,
7
7
  "name": "@intelligems/sst",
8
- "version": "2.49.3",
8
+ "version": "2.49.6-ig.2",
9
9
  "bin": {
10
10
  "sst": "cli/sst.js"
11
11
  },
@@ -61,6 +61,38 @@ export const useNodeHandler = () => {
61
61
  await worker?.terminate();
62
62
  },
63
63
  build: async (input) => {
64
+ // Check for dev mode mono-bundle: if .mono-build/index.mjs exists, skip individual builds
65
+ const monoBundleDir = path.join(project.paths.root, ".mono-build");
66
+ const monoBundlePath = path.join(monoBundleDir, "index.mjs");
67
+ const monoBundleExists = fsSync.existsSync(monoBundlePath);
68
+ console.log(`[MONO-BUNDLE] mode=${input.mode}, exists=${monoBundleExists}, handler=${input.props.handler}`);
69
+ if (input.mode === "start" && monoBundleExists) {
70
+ console.log(`[MONO-BUNDLE] Using mono-bundle for: ${input.props.handler}`);
71
+ Logger.debug("Using mono-bundle for dev mode:", monoBundlePath);
72
+ // Symlink node_modules to mono-bundle dir for external dependencies
73
+ // Use the same approach as individual builds: find nearest package.json above the handler
74
+ // handler-functions.ts lives in web/node-backend/src/, so start from there
75
+ const handlerFunctionsDir = path.join(project.paths.root, "web/node-backend/src");
76
+ const root = await findAbove(handlerFunctionsDir, "package.json");
77
+ if (root) {
78
+ const sourceNodeModules = path.join(root, "node_modules");
79
+ const monoBundleNodeModules = path.join(monoBundleDir, "node_modules");
80
+ try {
81
+ // Remove existing node_modules in mono-build (might be stale from deploy build)
82
+ await fs.rm(monoBundleNodeModules, { recursive: true, force: true });
83
+ await fs.symlink(path.resolve(sourceNodeModules), monoBundleNodeModules, "dir");
84
+ Logger.debug("Symlinked node_modules for mono-bundle from:", sourceNodeModules);
85
+ }
86
+ catch (err) {
87
+ Logger.debug("Failed to symlink node_modules for mono-bundle:", err);
88
+ }
89
+ }
90
+ return {
91
+ type: "success",
92
+ handler: "index.handler",
93
+ out: monoBundleDir,
94
+ };
95
+ }
64
96
  const parsed = path.parse(input.props.handler);
65
97
  const file = [
66
98
  ".ts",
@@ -6,6 +6,7 @@ declare module "../bus.js" {
6
6
  };
7
7
  "function.build.success": {
8
8
  functionID: string;
9
+ monoBundle?: boolean;
9
10
  };
10
11
  "function.build.failed": {
11
12
  functionID: string;
@@ -41,6 +42,7 @@ export interface RuntimeHandler {
41
42
  type: "success";
42
43
  handler: string;
43
44
  sourcemap?: string;
45
+ out?: string;
44
46
  } | {
45
47
  type: "error";
46
48
  errors: string[];
@@ -57,10 +59,10 @@ export declare const useRuntimeHandlers: () => {
57
59
  type: "error";
58
60
  errors: string[];
59
61
  } | {
60
- out: string;
61
- sourcemap: string | undefined;
62
62
  type: "success";
63
63
  handler: string;
64
+ out: string;
65
+ sourcemap: string | undefined;
64
66
  }>;
65
67
  };
66
68
  interface Artifact {
@@ -48,6 +48,26 @@ export const useRuntimeHandlers = lazy(() => {
48
48
  };
49
49
  const handler = result.for(func.runtime);
50
50
  const out = path.join(project.paths.artifacts, functionID);
51
+ // Check for mono-bundle mode by doing a preliminary build call
52
+ // In mono-bundle mode, handler returns its own out path immediately without building
53
+ const monoBundleCheck = await handler.build({
54
+ functionID,
55
+ out,
56
+ mode,
57
+ props: func,
58
+ });
59
+ // If mono-bundle detected (handler returned custom out), skip all artifact work
60
+ if (monoBundleCheck.type === "success" && monoBundleCheck.out) {
61
+ bus.publish("function.build.started", { functionID });
62
+ bus.publish("function.build.success", { functionID, monoBundle: true });
63
+ return {
64
+ type: "success",
65
+ handler: monoBundleCheck.handler,
66
+ out: monoBundleCheck.out,
67
+ sourcemap: monoBundleCheck.sourcemap,
68
+ };
69
+ }
70
+ // Non-mono-bundle: follow original flow
51
71
  await fs.rm(out, { recursive: true, force: true });
52
72
  await fs.mkdir(out, { recursive: true });
53
73
  bus.publish("function.build.started", { functionID });
package/stacks/deploy.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import path from "path";
2
+ import { fileURLToPath, pathToFileURL } from "url";
2
3
  import { useBus } from "../bus.js";
3
4
  import { useProject } from "../project.js";
4
5
  import { useAWSClient, useAWSProvider } from "../credentials.js";
@@ -7,6 +8,7 @@ import { filterOutputs, isFailed, monitor, } from "./monitor.js";
7
8
  import { VisibleError } from "../error.js";
8
9
  export async function publishAssets(stacks) {
9
10
  Logger.debug("Publishing assets");
11
+ const { cdk } = useProject().config;
10
12
  const results = {};
11
13
  for (const stackArtifact of stacks) {
12
14
  const cfnStack = await getCloudFormationStack(stackArtifact);
@@ -15,7 +17,7 @@ export async function publishAssets(stacks) {
15
17
  await buildAndPublishAssets(deployment, stackArtifact);
16
18
  results[stackArtifact.stackName] = {
17
19
  isUpdate: cfnStack && cfnStack.StackStatus !== "REVIEW_IN_PROGRESS",
18
- params: await buildCloudFormationStackParams(deployment, stackArtifact),
20
+ params: await buildCloudFormationStackParams(deployment, stackArtifact, cdk),
19
21
  };
20
22
  }
21
23
  return results;
@@ -87,7 +89,7 @@ export async function deploy(stack) {
87
89
  cfnStack?.StackStatus === "ROLLBACK_FAILED") {
88
90
  await deleteCloudFormationStack(stack.stackName);
89
91
  }
90
- const stackParams = await buildCloudFormationStackParams(deployment, stack);
92
+ const stackParams = await buildCloudFormationStackParams(deployment, stack, cdk);
91
93
  try {
92
94
  cfnStack && cfnStack.StackStatus !== "REVIEW_IN_PROGRESS"
93
95
  ? await updateCloudFormationStack(stackParams)
@@ -192,9 +194,9 @@ async function addInUseExports(stackArtifact, cfnStack) {
192
194
  }
193
195
  async function createCdkDeployments() {
194
196
  const cdkToolkitUrl = await import.meta.resolve("@aws-cdk/toolkit-lib");
195
- const cdkToolkitPath = new URL(cdkToolkitUrl).pathname;
196
- const { Deployments } = await import(path.resolve(cdkToolkitPath, "..", "api", "deployments", "deployments.js"));
197
- const { IoHelper } = await import(path.resolve(cdkToolkitPath, "..", "api", "io", "private", "io-helper.js"));
197
+ const cdkToolkitPath = fileURLToPath(cdkToolkitUrl);
198
+ const { Deployments } = await import(pathToFileURL(path.resolve(cdkToolkitPath, "..", "api", "deployments", "deployments.js")).href);
199
+ const { IoHelper } = await import(pathToFileURL(path.resolve(cdkToolkitPath, "..", "api", "io", "private", "io-helper.js")).href);
198
200
  const provider = await useAWSProvider();
199
201
  await useAWSProvider();
200
202
  const ioHelper = IoHelper.fromActionAwareIoHost({
@@ -227,17 +229,19 @@ async function buildAndPublishAssets(deployment, stackArtifact) {
227
229
  }
228
230
  }
229
231
  }
230
- async function buildCloudFormationStackParams(deployment, stack) {
231
- const resolvedEnv = await deployment.resolveEnvironment(stack);
232
+ async function buildCloudFormationStackParams(deployment, stack, cdkOptions) {
233
+ const env = await deployment.envs.accessStackForMutableStackOperations(stack);
234
+ const executionRoleArn = cdkOptions?.cloudFormationExecutionRole ?? await env.replacePlaceholders(stack.cloudFormationExecutionRoleArn);
232
235
  const s3Url = stack
233
- .stackTemplateAssetObjectUrl.replace("${AWS::AccountId}", resolvedEnv.account)
236
+ .stackTemplateAssetObjectUrl.replace("${AWS::AccountId}", env.resolvedEnvironment.account)
234
237
  .match(/s3:\/\/([^/]+)\/(.*)$/);
235
238
  const templateUrl = s3Url
236
- ? `https://s3.${resolvedEnv.region}.amazonaws.com/${s3Url[1]}/${s3Url[2]}`
239
+ ? `https://s3.${env.resolvedEnvironment.region}.amazonaws.com/${s3Url[1]}/${s3Url[2]}`
237
240
  : stack.stackTemplateAssetObjectUrl;
238
241
  return {
239
242
  StackName: stack.stackName,
240
243
  TemplateURL: templateUrl,
244
+ RoleARN: executionRoleArn,
241
245
  //TemplateBody: bodyParameter.TemplateBody,
242
246
  //Parameters: stackParams.apiParameters,
243
247
  Parameters: [],
@@ -257,7 +261,7 @@ async function getCloudFormationStack(stack) {
257
261
  const client = useAWSClient(CloudFormationClient);
258
262
  try {
259
263
  const { Stacks: stacks } = await client.send(new DescribeStacksCommand({
260
- StackName: stack.id,
264
+ StackName: stack.stackName,
261
265
  }));
262
266
  if (!stacks || stacks.length === 0)
263
267
  return;
package/stacks/synth.js CHANGED
@@ -2,6 +2,7 @@ import { Logger } from "../logger.js";
2
2
  import { useProject } from "../project.js";
3
3
  import { useAWSProvider, useSTSIdentity } from "../credentials.js";
4
4
  import path from "path";
5
+ import { fileURLToPath, pathToFileURL } from "url";
5
6
  import { VisibleError } from "../error.js";
6
7
  import { Semaphore } from "../util/semaphore.js";
7
8
  import { Configuration } from "../util/user-configuration.js";
@@ -11,10 +12,10 @@ export async function synth(opts) {
11
12
  const { App } = await import("../constructs/App.js");
12
13
  const cxapi = await import("@aws-cdk/cx-api");
13
14
  const cdkToolkitUrl = await import.meta.resolve("@aws-cdk/toolkit-lib");
14
- const cdkToolkitPath = new URL(cdkToolkitUrl).pathname;
15
- const { IoHelper } = await import(path.resolve(cdkToolkitPath, "..", "api", "io", "private", "io-helper.js"));
16
- const { PluginHost } = await import(path.resolve(cdkToolkitPath, "..", "api", "plugin", "plugin.js"));
17
- const { provideContextValues } = await import(path.resolve(cdkToolkitPath, "..", "context-providers", "index.js"));
15
+ const cdkToolkitPath = fileURLToPath(cdkToolkitUrl);
16
+ const { IoHelper } = await import(pathToFileURL(path.resolve(cdkToolkitPath, "..", "api", "io", "private", "io-helper.js")).href);
17
+ const { PluginHost } = await import(pathToFileURL(path.resolve(cdkToolkitPath, "..", "api", "plugin", "plugin.js")).href);
18
+ const { provideContextValues } = await import(pathToFileURL(path.resolve(cdkToolkitPath, "..", "context-providers", "index.js")).href);
18
19
  const project = useProject();
19
20
  const cwd = process.cwd();
20
21
  process.chdir(project.paths.root);
@@ -7,10 +7,22 @@ import fs from "fs";
7
7
  import http from "http";
8
8
  import url from "url";
9
9
  var input = workerData;
10
- var parsed = path.parse(input.handler);
11
- var file = [".js", ".jsx", ".mjs", ".cjs"].map((ext) => path.join(input.out, parsed.dir, parsed.name + ext)).find((file2) => {
12
- return fs.existsSync(file2);
13
- });
10
+ var monoBundlePath = path.join(input.out, "index.mjs");
11
+ var useMonoBundle = input.handler === "index.handler" && fs.existsSync(monoBundlePath);
12
+ var file;
13
+ var handlerName;
14
+ if (useMonoBundle) {
15
+ file = monoBundlePath;
16
+ handlerName = "handler";
17
+ } else {
18
+ const parsed = path.parse(input.handler);
19
+ const foundFile = [".js", ".jsx", ".mjs", ".cjs"].map((ext) => path.join(input.out, parsed.dir, parsed.name + ext)).find((f) => fs.existsSync(f));
20
+ if (!foundFile) {
21
+ throw new Error(`Could not find handler file for "${input.handler}"`);
22
+ }
23
+ file = foundFile;
24
+ handlerName = parsed.ext.substring(1);
25
+ }
14
26
  var fn;
15
27
  function fetch(req) {
16
28
  return new Promise((resolve, reject) => {
@@ -44,11 +56,10 @@ function fetch(req) {
44
56
  try {
45
57
  const { href } = url.pathToFileURL(file);
46
58
  const mod = await import(href);
47
- const handler = parsed.ext.substring(1);
48
- fn = mod[handler];
59
+ fn = mod[handlerName];
49
60
  if (!fn) {
50
61
  throw new Error(
51
- `Function "${handler}" not found in "${input.handler}". Found ${Object.keys(mod).join(", ")}`
62
+ useMonoBundle ? `Mono-bundle handler "${handlerName}" not found in "${file}". Found: ${Object.keys(mod).join(", ")}` : `Function "${handlerName}" not found in "${input.handler}". Found: ${Object.keys(mod).join(", ")}`
52
63
  );
53
64
  }
54
65
  } catch (ex) {
@@ -1,16 +1,28 @@
1
- // @ts-nocheck
2
1
  import * as os from "os";
3
2
  import * as fs_path from "path";
4
3
  import * as fs from "fs";
4
+ import { fileURLToPath, pathToFileURL } from "url";
5
5
  export const PROJECT_CONFIG = "cdk.json";
6
6
  export const USER_DEFAULTS = "~/.cdk.json";
7
7
  const CONTEXT_KEY = "context";
8
- const cdkToolkitUrl = await import.meta.resolve("@aws-cdk/toolkit-lib");
9
- const cdkToolkitPath = new URL(cdkToolkitUrl).pathname;
10
- const { ToolkitError } = await import(cdkToolkitPath);
11
- const { Context, PROJECT_CONTEXT } = await import(fs_path.resolve(cdkToolkitPath, "..", "api", "context.js"));
12
- const { Settings } = await import(fs_path.resolve(cdkToolkitPath, "..", "api", "settings.js"));
13
- const { Tags } = await import(fs_path.resolve(cdkToolkitPath, "..", "api", "tags", "index.js"));
8
+ let cdkToolkitPath = "";
9
+ let cdkToolkitUrl = "";
10
+ try {
11
+ cdkToolkitUrl = await import.meta.resolve("@aws-cdk/toolkit-lib");
12
+ cdkToolkitPath = fileURLToPath(cdkToolkitUrl);
13
+ }
14
+ catch (e) {
15
+ // Fallback for test environment where import.meta.resolve is not available
16
+ const module = await import("module");
17
+ const require = module.createRequire(import.meta.url);
18
+ cdkToolkitPath = require.resolve("@aws-cdk/toolkit-lib");
19
+ cdkToolkitUrl = pathToFileURL(cdkToolkitPath).href;
20
+ }
21
+ const { ToolkitError } = await import(cdkToolkitUrl);
22
+ const { Context, PROJECT_CONTEXT } = await import(pathToFileURL(fs_path.resolve(cdkToolkitPath, "..", "api", "context.js")).href);
23
+ const { Settings } = await import(pathToFileURL(fs_path.resolve(cdkToolkitPath, "..", "api", "settings.js"))
24
+ .href);
25
+ const { Tags } = await import(pathToFileURL(fs_path.resolve(cdkToolkitPath, "..", "api", "tags", "index.js")).href);
14
26
  export var Command;
15
27
  (function (Command) {
16
28
  Command["LS"] = "ls";