@awsless/cli 0.0.46-next.2 → 0.0.46-next.21

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.
@@ -1,104 +0,0 @@
1
- // src/feature/icon/server/handle.ts
2
- import { getObject, putObject } from "@awsless/s3";
3
- import { getRouteEnv, invokeRoute } from "awsless";
4
- import { optimize } from "svgo/browser";
5
- import svgstore from "svgstore";
6
- var handle_default = async (event) => {
7
- try {
8
- const path = event.rawPath.startsWith("/") ? event.rawPath.slice(1) : event.rawPath;
9
- const bucket = getRouteEnv("ICON_BUCKET");
10
- const folder = getRouteEnv("ICON_FOLDER") ?? "";
11
- const cacheKey = `${folder}cache/${path}`;
12
- if (bucket) {
13
- const cachedIcon = await getObject({
14
- bucket,
15
- key: cacheKey
16
- });
17
- if (cachedIcon) {
18
- const cachedIconData = await cachedIcon.body.transformToByteArray();
19
- return {
20
- statusCode: 200,
21
- body: Buffer.from(cachedIconData).toString("base64"),
22
- isBase64Encoded: true,
23
- headers: {
24
- "Content-Type": "image/svg+xml",
25
- "Cache-Control": "public, max-age=31536000, immutable"
26
- }
27
- };
28
- }
29
- }
30
- const configsEnv = getRouteEnv("ICON_CONFIG");
31
- if (!configsEnv) {
32
- throw new Error("Icon config not found in environment variables");
33
- }
34
- const config = JSON.parse(configsEnv);
35
- let baseIcon;
36
- if (getRouteEnv("ICON_ORIGIN_S3")) {
37
- const result = await getObject({
38
- bucket,
39
- key: `${folder}origin/${path}`
40
- });
41
- if (result?.body) {
42
- const data2 = await result.body.transformToByteArray();
43
- baseIcon = Buffer.from(data2);
44
- }
45
- }
46
- const originRoute = getRouteEnv("ICON_ORIGIN");
47
- if (!baseIcon && originRoute) {
48
- const result = await invokeRoute(originRoute, { path });
49
- if (typeof result === "string") {
50
- baseIcon = Buffer.from(result);
51
- } else if (result === undefined) {
52
- return { statusCode: 404 };
53
- } else {
54
- throw new Error("Invalid response from icon origin lambda");
55
- }
56
- }
57
- if (!baseIcon) {
58
- return { statusCode: 404 };
59
- }
60
- const { data } = optimize(baseIcon.toString("utf-8"), {
61
- multipass: true,
62
- plugins: [
63
- {
64
- name: "preset-default",
65
- params: {
66
- overrides: {
67
- ...config.preserveIds ? {
68
- cleanupIds: false
69
- } : {}
70
- }
71
- }
72
- }
73
- ]
74
- });
75
- let icon = data;
76
- if (config.symbols) {
77
- const symbols = svgstore();
78
- symbols.add("default", data);
79
- icon = symbols.toString({ inline: true });
80
- }
81
- await putObject({
82
- bucket,
83
- key: cacheKey,
84
- body: icon,
85
- contentType: "image/svg+xml",
86
- cacheControl: "public, max-age=31536000, immutable"
87
- });
88
- return {
89
- statusCode: 200,
90
- body: Buffer.from(icon).toString("base64"),
91
- isBase64Encoded: true,
92
- headers: {
93
- "Content-Type": "image/svg+xml",
94
- "Cache-Control": "public, max-age=31536000, immutable"
95
- }
96
- };
97
- } catch (error) {
98
- console.error(error);
99
- return { statusCode: 500 };
100
- }
101
- };
102
- export {
103
- handle_default as default
104
- };
@@ -1,216 +0,0 @@
1
- // src/feature/on-failure/server/handle.ts
2
- import { parse as parse2, patch } from "@awsless/json";
3
- import { invoke } from "@awsless/lambda";
4
- import { deleteObject, getObject } from "@awsless/s3";
5
- import { formatRoutePayload, getRouteEnv } from "awsless";
6
-
7
- // src/feature/on-failure/server/util.ts
8
- import { parse } from "@awsless/json";
9
- var isDynamoDBFailureEvent = (event) => {
10
- return "DDBStreamBatchInfo" in event;
11
- };
12
- var logicalResourceName = (physical) => {
13
- const segments = physical.replace(/\.fifo$/, "").split("--");
14
- if (segments.length === 4) {
15
- return `${segments[1]}:${segments[2]}:${segments[3]}`;
16
- }
17
- if (segments.length === 3) {
18
- return `${segments[1]}:${segments[2]}`;
19
- }
20
- return physical;
21
- };
22
- var getFailureSource = (payload) => {
23
- const record = getDeliveryRecord(payload);
24
- if (!record) {
25
- return;
26
- }
27
- if (isTopicRecord(record)) {
28
- return {
29
- resource: record.Sns.TopicArn ? logicalResourceName(lastArnSegment(record.Sns.TopicArn)) : "topic",
30
- event: parseEvent(record.Sns.Message)
31
- };
32
- }
33
- if (isStreamRecord(record)) {
34
- const table = record.eventSourceARN.split("/")[1];
35
- return {
36
- resource: table ? logicalResourceName(table) : "table-stream"
37
- };
38
- }
39
- if (isQueueRecord(record)) {
40
- return {
41
- resource: logicalResourceName(lastArnSegment(record.eventSourceARN)),
42
- event: parseEvent(record.body)
43
- };
44
- }
45
- return;
46
- };
47
- var getDeliveryRecord = (payload) => {
48
- if (!payload || typeof payload !== "object") {
49
- return;
50
- }
51
- const records = payload.Records;
52
- const record = Array.isArray(records) ? records[0] : undefined;
53
- return record && typeof record === "object" ? record : undefined;
54
- };
55
- var isTopicRecord = (record) => {
56
- return "Sns" in record && typeof record.Sns === "object" && record.Sns !== null;
57
- };
58
- var isStreamRecord = (record) => {
59
- return "eventSource" in record && record.eventSource === "aws:dynamodb" && "eventSourceARN" in record;
60
- };
61
- var isQueueRecord = (record) => {
62
- return "eventSource" in record && record.eventSource === "aws:sqs" && "eventSourceARN" in record;
63
- };
64
- var lastArnSegment = (arn) => {
65
- return arn.split(":").at(-1);
66
- };
67
- var parseEvent = (value) => {
68
- if (typeof value !== "string") {
69
- return value;
70
- }
71
- try {
72
- return parse(value);
73
- } catch {
74
- return value;
75
- }
76
- };
77
-
78
- // src/feature/on-failure/server/handle.ts
79
- var handle_default = async (event, context) => {
80
- if (!Array.isArray(event.Records)) {
81
- throw new TypeError(`Unknown Event Type: ${JSON.stringify(event)}`);
82
- }
83
- await Promise.all(event.Records.map((record) => {
84
- return unknownRecord(record, context);
85
- }));
86
- };
87
- var unknownRecord = (record, context) => {
88
- if (typeof record.eventSource === "string") {
89
- if (record.eventSource.startsWith("aws:sqs")) {
90
- return sqsRecord(record, context);
91
- }
92
- if (record.eventSource.startsWith("aws:s3")) {
93
- return s3Record(record, context);
94
- }
95
- }
96
- throw new TypeError(`Unknown Record Type: ${JSON.stringify(record)}`);
97
- };
98
- var sqsRecord = async (record, context) => {
99
- const s3Records = parseS3Records(record.body);
100
- if (s3Records) {
101
- await Promise.all(s3Records.map((record2) => s3Record(record2, context)));
102
- return;
103
- }
104
- const queueName = record.messageAttributes.queueName?.stringValue;
105
- const body = parsePayload(record.body);
106
- const payload = {
107
- type: "queue",
108
- id: record.messageId,
109
- date: new Date(Number(record.attributes.SentTimestamp)),
110
- payload: body,
111
- source: queueName ? { resource: logicalResourceName(queueName), event: body } : undefined,
112
- queue: {
113
- name: queueName,
114
- url: record.messageAttributes.queueUrl?.stringValue
115
- }
116
- };
117
- await invokeConsumer(payload, context);
118
- };
119
- var parseS3Records = (body) => {
120
- try {
121
- const event = JSON.parse(body);
122
- if (event?.Event === "s3:TestEvent") {
123
- return [];
124
- }
125
- if (Array.isArray(event?.Records) && event.Records[0]?.eventSource === "aws:s3") {
126
- return event.Records;
127
- }
128
- } catch {}
129
- return;
130
- };
131
- var s3Record = async (record, context) => {
132
- const key = decodeURIComponent(record.s3.object.key.replace(/\+/g, " "));
133
- const object = await getObject({
134
- bucket: record.s3.bucket.name,
135
- key
136
- });
137
- if (!object) {
138
- return;
139
- }
140
- const json = await object.body.transformToString();
141
- const unknownEvent = JSON.parse(json);
142
- const payload = formatUnknownFailureEvent(unknownEvent);
143
- await invokeConsumer(payload, context);
144
- await deleteObject({
145
- bucket: record.s3.bucket.name,
146
- key
147
- });
148
- };
149
- var formatUnknownFailureEvent = (event) => {
150
- if (isDynamoDBFailureEvent(event)) {
151
- return formatDynamoDBStreamFailureEvent(event);
152
- }
153
- return formatAsyncLambdaFailureEvent(event);
154
- };
155
- var formatAsyncLambdaFailureEvent = (event) => {
156
- const payload = patchPayload(event.requestPayload);
157
- const route = payload && typeof payload === "object" ? payload["$awsless-route"] : undefined;
158
- return {
159
- type: "async-lambda",
160
- date: new Date(event.timestamp),
161
- id: event.requestContext.requestId,
162
- function: {
163
- name: typeof route === "string" ? route : event.requestContext.functionArn.split(":")[6]
164
- },
165
- payload: typeof route === "string" ? payload.event ?? {} : payload,
166
- source: typeof route === "string" ? { resource: route, event: payload.event ?? {} } : getFailureSource(payload),
167
- error: {
168
- type: event.responsePayload.errorType,
169
- message: event.responsePayload.errorMessage,
170
- stackTrace: event.responsePayload.stackTrace
171
- }
172
- };
173
- };
174
- var formatDynamoDBStreamFailureEvent = (event) => {
175
- const payload = parsePayload(event.payload);
176
- const streamArn = event.DDBStreamBatchInfo?.streamArn;
177
- const table = streamArn?.split("/")[1];
178
- return {
179
- type: "dynamodb-stream",
180
- date: new Date(event.timestamp),
181
- id: event.requestContext.requestId,
182
- function: {
183
- name: event.requestContext.functionArn.split(":")[6]
184
- },
185
- payload,
186
- source: table ? { resource: logicalResourceName(table) } : getFailureSource(payload)
187
- };
188
- };
189
- var parsePayload = (payload) => {
190
- try {
191
- return parse2(payload);
192
- } catch {
193
- return payload;
194
- }
195
- };
196
- var patchPayload = (payload) => {
197
- try {
198
- return patch(payload);
199
- } catch {
200
- return payload;
201
- }
202
- };
203
- var invokeConsumer = async (payload, context) => {
204
- const consumerRoute = getRouteEnv("CONSUMER");
205
- if (!consumerRoute) {
206
- throw new Error("The CONSUMER route env is not set");
207
- }
208
- await invoke({
209
- name: context.invokedFunctionArn,
210
- type: "RequestResponse",
211
- payload: formatRoutePayload(consumerRoute, payload)
212
- });
213
- };
214
- export {
215
- handle_default as default
216
- };
@@ -1,43 +0,0 @@
1
- // src/feature/pubsub/publisher/handle.ts
2
- import { stringify } from "@awsless/json";
3
- import { lambda } from "@awsless/lambda";
4
- import { maxLength, minLength, object, optional, pipe, string, unknown } from "@awsless/validate";
5
- import { getRouteEnv } from "awsless";
6
- import { Redis } from "ioredis";
7
- var createClient = () => {
8
- return new Redis({
9
- host: getRouteEnv("REDIS_HOST"),
10
- port: Number(getRouteEnv("REDIS_PORT") ?? 6379),
11
- tls: {},
12
- lazyConnect: true,
13
- keepAlive: 0,
14
- noDelay: true,
15
- enableReadyCheck: false,
16
- maxRetriesPerRequest: 3,
17
- connectTimeout: 5000,
18
- commandTimeout: 5000
19
- });
20
- };
21
- var handle_default = lambda({
22
- schema: object({
23
- topic: pipe(string(), minLength(1), maxLength(128)),
24
- event: pipe(string(), minLength(1), maxLength(64)),
25
- payload: optional(unknown())
26
- }),
27
- async handle({ topic, event, payload }, ctx) {
28
- const redis = createClient();
29
- ctx.onFinally(() => {
30
- return redis.quit().catch(() => {
31
- redis.disconnect();
32
- });
33
- });
34
- await redis.publish(getRouteEnv("CHANNEL"), stringify({
35
- topic,
36
- event,
37
- payload: typeof payload === "undefined" ? undefined : stringify(payload)
38
- }));
39
- }
40
- });
41
- export {
42
- handle_default as default
43
- };