sst 2.8.23 → 2.8.24

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/constructs/Job.js CHANGED
@@ -249,13 +249,13 @@ export class Job extends Construct {
249
249
  // in the Console.
250
250
  const fn = new Function(this, this.node.id, {
251
251
  runtime: "nodejs16.x",
252
- timeout: "15 minutes",
253
252
  memorySize: 1024,
254
253
  environment: {
255
254
  ...this.props.environment,
256
255
  SST_DEBUG_TYPE: "job",
257
256
  },
258
257
  ...this.props,
258
+ timeout: "15 minutes",
259
259
  });
260
260
  fn._doNotAllowOthersToBind = true;
261
261
  return fn;
@@ -16,6 +16,11 @@ export interface NextjsSiteProps extends Omit<SsrSiteProps, "nodejs"> {
16
16
  */
17
17
  memorySize?: number | Size;
18
18
  };
19
+ /**
20
+ * The number of server functions to keep warm. This option is only supported for the regional mode.
21
+ * @default Server function is not kept warm
22
+ */
23
+ warm?: number;
19
24
  }
20
25
  /**
21
26
  * The `NextjsSite` construct is a higher level CDK construct that makes it easy to create a Next.js app.
@@ -46,6 +51,7 @@ export declare class NextjsSite extends SsrSite {
46
51
  protected createFunctionForRegional(): CdkFunction;
47
52
  protected createFunctionForEdge(): EdgeFunction;
48
53
  private createImageOptimizationFunction;
54
+ private createWarmer;
49
55
  protected createCloudFrontDistributionForRegional(): Distribution;
50
56
  protected createCloudFrontDistributionForEdge(): Distribution;
51
57
  private buildServerBehaviorForRegional;
@@ -1,16 +1,19 @@
1
1
  import fs from "fs";
2
2
  import url from "url";
3
3
  import path from "path";
4
- import { Fn, Duration as CdkDuration, RemovalPolicy } from "aws-cdk-lib";
4
+ import { Fn, Duration as CdkDuration, RemovalPolicy, CustomResource, } from "aws-cdk-lib";
5
+ import { Effect, Policy, PolicyStatement } from "aws-cdk-lib/aws-iam";
5
6
  import { RetentionDays } from "aws-cdk-lib/aws-logs";
6
7
  import { Function as CdkFunction, Code, Runtime, Architecture, FunctionUrlAuthType, } from "aws-cdk-lib/aws-lambda";
7
8
  import { Distribution, ViewerProtocolPolicy, AllowedMethods, LambdaEdgeEventType, CachedMethods, CachePolicy, } from "aws-cdk-lib/aws-cloudfront";
8
9
  import { S3Origin, HttpOrigin, OriginGroup, } from "aws-cdk-lib/aws-cloudfront-origins";
10
+ import { Rule, Schedule } from "aws-cdk-lib/aws-events";
11
+ import { LambdaFunction } from "aws-cdk-lib/aws-events-targets";
12
+ import { Stack } from "./Stack.js";
9
13
  import { SsrFunction } from "./SsrFunction.js";
10
14
  import { EdgeFunction } from "./EdgeFunction.js";
11
15
  import { SsrSite } from "./SsrSite.js";
12
16
  import { toCdkSize } from "./util/size.js";
13
- import { PolicyStatement } from "aws-cdk-lib/aws-iam";
14
17
  const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
15
18
  /**
16
19
  * The `NextjsSite` construct is a higher level CDK construct that makes it easy to create a Next.js app.
@@ -26,9 +29,10 @@ const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
26
29
  export class NextjsSite extends SsrSite {
27
30
  constructor(scope, id, props) {
28
31
  super(scope, id, {
29
- buildCommand: "npx --yes open-next@~1.2.0 build",
32
+ buildCommand: "npx --yes open-next@~1.3.0 build",
30
33
  ...props,
31
34
  });
35
+ this.createWarmer();
32
36
  }
33
37
  initBuildConfig() {
34
38
  return {
@@ -41,7 +45,7 @@ export class NextjsSite extends SsrSite {
41
45
  createFunctionForRegional() {
42
46
  const { runtime, timeout, memorySize, bind, permissions, environment, cdk, } = this.props;
43
47
  const ssrFn = new SsrFunction(this, `ServerFunction`, {
44
- description: "Server handler for Next.js",
48
+ description: "Next.js server",
45
49
  bundle: path.join(this.props.path, ".open-next", "server-function"),
46
50
  handler: "index.handler",
47
51
  runtime,
@@ -70,7 +74,7 @@ export class NextjsSite extends SsrSite {
70
74
  createImageOptimizationFunction() {
71
75
  const { imageOptimization, path: sitePath } = this.props;
72
76
  return new CdkFunction(this, `ImageFunction`, {
73
- description: "Image optimization handler for Next.js",
77
+ description: "Next.js image optimizer",
74
78
  handler: "index.handler",
75
79
  currentVersionOptions: {
76
80
  removalPolicy: RemovalPolicy.DESTROY,
@@ -96,6 +100,56 @@ export class NextjsSite extends SsrSite {
96
100
  ],
97
101
  });
98
102
  }
103
+ createWarmer() {
104
+ const { warm, edge } = this.props;
105
+ if (!warm)
106
+ return;
107
+ if (warm && edge) {
108
+ throw new Error(`Warming is currently supported only for the regional mode.`);
109
+ }
110
+ if (!this.serverLambdaForRegional)
111
+ return;
112
+ // Create warmer function
113
+ const warmer = new CdkFunction(this, "WarmerFunction", {
114
+ description: "Next.js warmer",
115
+ code: Code.fromAsset(path.join(this.props.path, ".open-next/warmer-function")),
116
+ runtime: Runtime.NODEJS_18_X,
117
+ handler: "index.handler",
118
+ timeout: CdkDuration.minutes(15),
119
+ memorySize: 1024,
120
+ environment: {
121
+ FUNCTION_NAME: this.serverLambdaForRegional.functionName,
122
+ CONCURRENCY: warm.toString(),
123
+ },
124
+ });
125
+ this.serverLambdaForRegional.grantInvoke(warmer);
126
+ // Create cron job
127
+ new Rule(this, "WarmerRule", {
128
+ schedule: Schedule.rate(CdkDuration.minutes(5)),
129
+ targets: [new LambdaFunction(warmer, { retryAttempts: 0 })],
130
+ });
131
+ // Create custom resource to prewarm on deploy
132
+ const stack = Stack.of(this);
133
+ const policy = new Policy(this, "PrewarmerPolicy", {
134
+ statements: [
135
+ new PolicyStatement({
136
+ effect: Effect.ALLOW,
137
+ actions: ["lambda:InvokeFunction"],
138
+ resources: [warmer.functionArn],
139
+ }),
140
+ ],
141
+ });
142
+ stack.customResourceHandler.role?.attachInlinePolicy(policy);
143
+ const resource = new CustomResource(this, "Prewarmer", {
144
+ serviceToken: stack.customResourceHandler.functionArn,
145
+ resourceType: "Custom::FunctionInvoker",
146
+ properties: {
147
+ version: Date.now().toString(),
148
+ functionName: warmer.functionName,
149
+ },
150
+ });
151
+ resource.node.addDependency(policy);
152
+ }
99
153
  createCloudFrontDistributionForRegional() {
100
154
  /**
101
155
  * Next.js requests
@@ -15,7 +15,7 @@ export interface WebSocketApiAccessLogProps extends apigV2AccessLog.AccessLogPro
15
15
  }
16
16
  export interface WebSocketApiProps {
17
17
  /**
18
- * The routes for the Websocket API
18
+ * The routes for the WebSocket API
19
19
  *
20
20
  * @example
21
21
  * ```js
@@ -195,12 +195,16 @@ export class WebSocketApi extends Construct {
195
195
  /** @internal */
196
196
  getFunctionBinding() {
197
197
  return {
198
- clientPackage: "api",
198
+ clientPackage: "websocket-api",
199
199
  variables: {
200
200
  url: {
201
201
  type: "plain",
202
202
  value: this.customDomainUrl || this.url,
203
203
  },
204
+ httpsUrl: {
205
+ type: "plain",
206
+ value: (this.customDomainUrl || this.url).replace("wss://", "https://"),
207
+ },
204
208
  },
205
209
  permissions: {
206
210
  "execute-api:ManageConnections": [this._connectionsArn],
@@ -1,16 +1,25 @@
1
- import { APIGatewayProxyEventV2, APIGatewayProxyStructuredResultV2, Context as LambdaContext, SQSBatchResponse, SQSEvent } from "aws-lambda";
1
+ import { APIGatewayProxyEventHeaders, APIGatewayProxyEventMultiValueHeaders, APIGatewayProxyEventMultiValueQueryStringParameters, APIGatewayProxyEventQueryStringParameters, APIGatewayProxyEventV2, APIGatewayProxyResultV2, APIGatewayProxyStructuredResultV2, APIGatewayProxyWebsocketEventV2, Context as LambdaContext, SQSBatchResponse, SQSEvent } from "aws-lambda";
2
2
  export interface Handlers {
3
3
  api: {
4
4
  event: APIGatewayProxyEventV2;
5
5
  response: APIGatewayProxyStructuredResultV2 | void;
6
6
  };
7
+ ws: {
8
+ event: APIGatewayProxyWebsocketEventV2 & {
9
+ headers?: APIGatewayProxyEventHeaders;
10
+ multiValueHeaders?: APIGatewayProxyEventMultiValueHeaders;
11
+ queryStringParameters?: APIGatewayProxyEventQueryStringParameters | null;
12
+ multiValueQueryStringParameters?: APIGatewayProxyEventMultiValueQueryStringParameters | null;
13
+ };
14
+ response: APIGatewayProxyResultV2;
15
+ };
7
16
  sqs: {
8
17
  event: SQSEvent;
9
18
  response: SQSBatchResponse;
10
19
  };
11
20
  }
12
- type HandlerTypes = keyof Handlers;
21
+ export type HandlerTypes = keyof Handlers;
22
+ export declare function useContextType(): HandlerTypes;
13
23
  export declare function useEvent<Type extends HandlerTypes>(type: Type): Handlers[Type]["event"];
14
24
  export declare function useLambdaContext(): LambdaContext;
15
25
  export declare function Handler<Type extends HandlerTypes, Event = Handlers[Type]["event"], Response = Handlers[Type]["response"]>(type: Type, cb: (evt: Event, ctx: LambdaContext) => Promise<Response>): (event: Event, context: LambdaContext) => Promise<Response>;
16
- export {};
@@ -1,5 +1,9 @@
1
1
  import { Context } from "./context.js";
2
2
  const RequestContext = Context.create("RequestContext");
3
+ export function useContextType() {
4
+ const ctx = RequestContext.use();
5
+ return ctx.type;
6
+ }
3
7
  export function useEvent(type) {
4
8
  const ctx = RequestContext.use();
5
9
  if (ctx.type !== type)
@@ -1,4 +1,4 @@
1
- import { Handler } from "../../context/handler.js";
1
+ import { Handler, HandlerTypes } from "../../context/handler.js";
2
2
  import { APIGatewayProxyStructuredResultV2 } from "aws-lambda";
3
3
  export interface ApiResources {
4
4
  }
@@ -6,12 +6,10 @@ export interface AppSyncApiResources {
6
6
  }
7
7
  export interface ApiGatewayV1ApiResources {
8
8
  }
9
- export interface WebSocketApiResources {
10
- }
9
+ export type ApiHandlerTypes = Extract<HandlerTypes, "api" | "ws">;
11
10
  export declare const Api: ApiResources;
12
11
  export declare const AppSyncApi: AppSyncApiResources;
13
12
  export declare const ApiGatewayV1Api: ApiGatewayV1ApiResources;
14
- export declare const WebSocketApi: WebSocketApiResources;
15
13
  /**
16
14
  * Create a new api handler that can be used to create an authenticated session.
17
15
  *
package/node/api/index.js CHANGED
@@ -1,13 +1,11 @@
1
1
  import { createProxy } from "../util/index.js";
2
2
  import { Context } from "../../context/context.js";
3
- import { useEvent, Handler } from "../../context/handler.js";
3
+ import { useEvent, Handler, useContextType, } from "../../context/handler.js";
4
4
  export const Api = /* @__PURE__ */ createProxy("Api");
5
5
  export const AppSyncApi =
6
6
  /* @__PURE__ */ createProxy("AppSyncApi");
7
7
  export const ApiGatewayV1Api =
8
8
  /* @__PURE__ */ createProxy("ApiGatewayV1Api");
9
- export const WebSocketApi =
10
- /* @__PURE__ */ createProxy("WebSocketApi");
11
9
  /**
12
10
  * Create a new api handler that can be used to create an authenticated session.
13
11
  *
@@ -34,7 +32,8 @@ export function useCookie(name) {
34
32
  return cookies[name];
35
33
  }
36
34
  export const useBody = /* @__PURE__ */ Context.memo(() => {
37
- const evt = useEvent("api");
35
+ const type = useContextType();
36
+ const evt = useEvent(type);
38
37
  if (!evt.body)
39
38
  return;
40
39
  const body = evt.isBase64Encoded
@@ -118,7 +117,8 @@ export const useResponse = /* @__PURE__ */ Context.memo(() => {
118
117
  return result;
119
118
  });
120
119
  export function useDomainName() {
121
- const evt = useEvent("api");
120
+ const type = useContextType();
121
+ const evt = useEvent(type);
122
122
  return evt.requestContext.domainName;
123
123
  }
124
124
  export function useMethod() {
@@ -126,7 +126,8 @@ export function useMethod() {
126
126
  return evt.requestContext.http.method;
127
127
  }
128
128
  export function useHeaders() {
129
- const evt = useEvent("api");
129
+ const type = useContextType();
130
+ const evt = useEvent(type);
130
131
  return evt.headers || {};
131
132
  }
132
133
  export function useHeader(key) {
@@ -138,7 +139,8 @@ export function useFormValue(name) {
138
139
  return params?.get(name);
139
140
  }
140
141
  export function useQueryParams() {
141
- const evt = useEvent("api");
142
+ const type = useContextType();
143
+ const evt = useEvent(type);
142
144
  const query = evt.queryStringParameters || {};
143
145
  return query;
144
146
  }
@@ -2,14 +2,26 @@ import { createSigner, createVerifier } from "fast-jwt";
2
2
  import { Context } from "../../context/context.js";
3
3
  import { useCookie, useHeader } from "../api/index.js";
4
4
  import { getPrivateKey, getPublicKey } from "./auth.js";
5
+ import { useContextType } from "../../context/handler.js";
5
6
  const SessionMemo = /* @__PURE__ */ Context.memo(() => {
7
+ // Get the context type and hooks that match that type
6
8
  let token = "";
7
9
  const header = useHeader("authorization");
8
10
  if (header)
9
11
  token = header.substring(7);
10
- const cookie = useCookie("auth-token");
12
+ const ctxType = useContextType();
13
+ const cookie = ctxType === "api" ? useCookie("auth-token") : undefined;
11
14
  if (cookie)
12
15
  token = cookie;
16
+ // WebSocket may also set the token in the protocol header
17
+ // TODO: Once https://github.com/serverless-stack/sst/pull/2838 is merged,
18
+ // then we should no longer need to check both casing for the header.
19
+ const wsProtocol = ctxType === "ws"
20
+ ? useHeader("sec-websocket-protocol") ||
21
+ useHeader("Sec-WebSocket-Protocol")
22
+ : undefined;
23
+ if (wsProtocol)
24
+ token = wsProtocol.split(",")[0].trim();
13
25
  if (token) {
14
26
  const jwt = createVerifier({
15
27
  algorithms: ["RS512"],
@@ -0,0 +1,20 @@
1
+ import { OidcBasicConfig } from "./oidc.js";
2
+ type MicrosoftConfig = OidcBasicConfig & {
3
+ mode: "oidc";
4
+ };
5
+ export declare function MicrosoftAdapter(config: MicrosoftConfig): () => Promise<{
6
+ type: "success";
7
+ properties: {
8
+ tokenset: import("openid-client").TokenSet;
9
+ client: import("openid-client").BaseClient;
10
+ };
11
+ } | {
12
+ type: "step";
13
+ properties: {
14
+ statusCode: number;
15
+ headers: {
16
+ location: string;
17
+ };
18
+ };
19
+ }>;
20
+ export {};
@@ -0,0 +1,14 @@
1
+ import { Issuer } from "openid-client";
2
+ import { OidcAdapter } from "./oidc.js";
3
+ // These are the different Microsoft auth urls for different types of accounts:
4
+ // Common: https://login.microsoftonline.com/common/v2.0 (both business and private)
5
+ // Business: https://login.microsoftonline.com/{tenant}/v2.0
6
+ // Private: https://login.microsoftonline.com/consumers/v2.0
7
+ const issuer = await Issuer.discover("https://login.microsoftonline.com/common/v2.0");
8
+ export function MicrosoftAdapter(config) {
9
+ return OidcAdapter({
10
+ issuer,
11
+ scope: "openid email profile",
12
+ ...config,
13
+ });
14
+ }
@@ -6,6 +6,7 @@ export * from "./adapter/google.js";
6
6
  export * from "./adapter/link.js";
7
7
  export * from "./adapter/github.js";
8
8
  export * from "./adapter/facebook.js";
9
+ export * from "./adapter/microsoft.js";
9
10
  export * from "./adapter/oauth.js";
10
11
  export type { Adapter } from "./adapter/adapter.js";
11
12
  export * from "./session.js";
@@ -5,6 +5,7 @@ export * from "./adapter/google.js";
5
5
  export * from "./adapter/link.js";
6
6
  export * from "./adapter/github.js";
7
7
  export * from "./adapter/facebook.js";
8
+ export * from "./adapter/microsoft.js";
8
9
  export * from "./adapter/oauth.js";
9
10
  export * from "./session.js";
10
11
  export * from "./handler.js";
@@ -3,14 +3,26 @@ import { Context } from "../../../context/context.js";
3
3
  import { useCookie, useHeader } from "../../api/index.js";
4
4
  import { Auth } from "../../auth/index.js";
5
5
  import { Config } from "../../config/index.js";
6
+ import { useContextType } from "../../../context/handler.js";
6
7
  const SessionMemo = /* @__PURE__ */ Context.memo(() => {
8
+ // Get the context type and hooks that match that type
7
9
  let token = "";
8
10
  const header = useHeader("authorization");
9
11
  if (header)
10
12
  token = header.substring(7);
11
- const cookie = useCookie("sst_auth_token");
13
+ const ctxType = useContextType();
14
+ const cookie = ctxType === "api" ? useCookie("sst_auth_token") : undefined;
12
15
  if (cookie)
13
16
  token = cookie;
17
+ // WebSocket may also set the token in the protocol header
18
+ // TODO: Once https://github.com/serverless-stack/sst/pull/2838 is merged,
19
+ // then we should no longer need to check both casing for the header.
20
+ const wsProtocol = ctxType === "ws"
21
+ ? useHeader("sec-websocket-protocol") ||
22
+ useHeader("Sec-WebSocket-Protocol")
23
+ : undefined;
24
+ if (wsProtocol)
25
+ token = wsProtocol.split(",")[0].trim();
14
26
  if (token) {
15
27
  return Session.verify(token);
16
28
  }
@@ -0,0 +1,23 @@
1
+ import { Handler } from "../../context/handler.js";
2
+ export interface WebSocketApiResources {
3
+ }
4
+ export declare const WebSocketApi: WebSocketApiResources;
5
+ /**
6
+ * Create a new WebSocketApi handler that can be used to create an
7
+ * authenticated session.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * export const handler = WebSocketApiHandler({
12
+ * })
13
+ * ```
14
+ */
15
+ export declare function WebSocketApiHandler(cb: Parameters<typeof Handler<"ws">>[1]): (event: import("aws-lambda").APIGatewayProxyWebsocketEventV2 & {
16
+ headers?: import("aws-lambda").APIGatewayProxyEventHeaders | undefined;
17
+ multiValueHeaders?: import("aws-lambda").APIGatewayProxyEventMultiValueHeaders | undefined;
18
+ queryStringParameters?: import("aws-lambda").APIGatewayProxyEventQueryStringParameters | null | undefined;
19
+ multiValueQueryStringParameters?: import("aws-lambda").APIGatewayProxyEventMultiValueQueryStringParameters | null | undefined;
20
+ }, context: import("aws-lambda").Context) => Promise<any>;
21
+ export declare function useRequestContext(): import("aws-lambda").APIGatewayEventWebsocketRequestContextV2;
22
+ export declare function useConnectionId(): string;
23
+ export declare function useEventType(): "CONNECT" | "MESSAGE" | "DISCONNECT";
@@ -0,0 +1,48 @@
1
+ import { Handler, useEvent } from "../../context/handler.js";
2
+ import { useHeader } from "../api/index.js";
3
+ import { createProxy } from "../util/index.js";
4
+ export const WebSocketApi =
5
+ /* @__PURE__ */ createProxy("WebSocketApi");
6
+ /**
7
+ * Create a new WebSocketApi handler that can be used to create an
8
+ * authenticated session.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * export const handler = WebSocketApiHandler({
13
+ * })
14
+ * ```
15
+ */
16
+ export function WebSocketApiHandler(cb) {
17
+ return Handler("ws", async (evt, ctx) => {
18
+ const result = await cb(evt, ctx);
19
+ // TODO: Once https://github.com/serverless-stack/sst/pull/2838 is merged,
20
+ // then we should no longer need to check both casing for the header.
21
+ const token = useHeader("Sec-WebSocket-Protocol") ||
22
+ useHeader("sec-websocket-protocol");
23
+ // If a token was set as part of the sec-websocket-protocol, we need to
24
+ // return it as a header in the response.
25
+ // https://docs.aws.amazon.com/apigateway/latest/developerguide/websocket-connect-route-subprotocol.html
26
+ if (token) {
27
+ return {
28
+ ...(result || {}),
29
+ headers: {
30
+ "Sec-WebSocket-Protocol": token,
31
+ },
32
+ };
33
+ }
34
+ return result;
35
+ });
36
+ }
37
+ export function useRequestContext() {
38
+ const evt = useEvent("ws");
39
+ return evt.requestContext;
40
+ }
41
+ export function useConnectionId() {
42
+ const requestContext = useRequestContext();
43
+ return requestContext.connectionId;
44
+ }
45
+ export function useEventType() {
46
+ const requestContext = useRequestContext();
47
+ return requestContext.eventType;
48
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "sideEffects": false,
3
3
  "name": "sst",
4
- "version": "2.8.23",
4
+ "version": "2.8.24",
5
5
  "bin": {
6
6
  "sst": "cli/sst.js"
7
7
  },
@@ -48,6 +48,7 @@
48
48
  "@babel/core": "^7.0.0-0",
49
49
  "@babel/generator": "^7.20.5",
50
50
  "@trpc/server": "9.16.0",
51
+ "adm-zip": "^0.5.10",
51
52
  "aws-cdk-lib": "2.72.1",
52
53
  "aws-iot-device-sdk": "^2.2.12",
53
54
  "aws-sdk": "^2.1326.0",
@@ -85,8 +86,7 @@
85
86
  "undici": "^5.12.0",
86
87
  "uuid": "^9.0.0",
87
88
  "ws": "^8.11.0",
88
- "yargs": "^17.6.2",
89
- "zip-local": "^0.3.5"
89
+ "yargs": "^17.6.2"
90
90
  },
91
91
  "devDependencies": {
92
92
  "@aws-sdk/client-api-gateway": "^3.208.0",
@@ -110,7 +110,6 @@
110
110
  "@types/uuid": "^8.3.4",
111
111
  "@types/ws": "^8.5.3",
112
112
  "@types/yargs": "^17.0.13",
113
- "adm-zip": "^0.5.10",
114
113
  "archiver": "^5.3.1",
115
114
  "tsx": "^3.12.1",
116
115
  "typescript": "^4.9.5",
@@ -4,13 +4,13 @@ import os from "os";
4
4
  import { useRuntimeHandlers } from "../handlers.js";
5
5
  import { useRuntimeWorkers } from "../workers.js";
6
6
  import { Context } from "../../context/context.js";
7
- import zipLocal from "zip-local";
8
7
  import { spawn } from "child_process";
9
8
  import { useRuntimeServerConfig } from "../server.js";
10
9
  import { existsAsync, findBelow, isChild } from "../../util/fs.js";
11
10
  import { useProject } from "../../project.js";
12
11
  import { execAsync } from "../../util/process.js";
13
12
  import url from "url";
13
+ import AdmZip from "adm-zip";
14
14
  export const useJavaHandler = Context.memo(async () => {
15
15
  const workers = await useRuntimeWorkers();
16
16
  const server = await useRuntimeServerConfig();
@@ -74,7 +74,7 @@ export const useJavaHandler = Context.memo(async () => {
74
74
  });
75
75
  const buildOutput = path.join(srcPath, "build", outputDir);
76
76
  const zip = (await fs.readdir(buildOutput)).find((f) => f.endsWith(".zip"));
77
- zipLocal.sync.unzip(path.join(buildOutput, zip)).save(input.out);
77
+ new AdmZip(path.join(buildOutput, zip)).extractAllTo(input.out);
78
78
  return {
79
79
  type: "success",
80
80
  handler: input.props.handler,
package/sst.mjs CHANGED
@@ -4848,9 +4848,9 @@ __export(java_exports, {
4848
4848
  import path13 from "path";
4849
4849
  import fs12 from "fs/promises";
4850
4850
  import os5 from "os";
4851
- import zipLocal from "zip-local";
4852
4851
  import { spawn as spawn5 } from "child_process";
4853
4852
  import url7 from "url";
4853
+ import AdmZip from "adm-zip";
4854
4854
  async function getGradleBinary(srcPath) {
4855
4855
  const gradleWrapperPath = path13.resolve(path13.join(srcPath, "gradlew"));
4856
4856
  return await existsAsync(gradleWrapperPath) ? gradleWrapperPath : "gradle";
@@ -4940,7 +4940,7 @@ var init_java = __esm({
4940
4940
  const zip = (await fs12.readdir(buildOutput)).find(
4941
4941
  (f) => f.endsWith(".zip")
4942
4942
  );
4943
- zipLocal.sync.unzip(path13.join(buildOutput, zip)).save(input.out);
4943
+ new AdmZip(path13.join(buildOutput, zip)).extractAllTo(input.out);
4944
4944
  return {
4945
4945
  type: "success",
4946
4946
  handler: input.props.handler