@awsless/awsless 0.0.465 → 0.0.467

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/bin.js CHANGED
@@ -713,11 +713,11 @@ var FunctionDefaultSchema = z9.object({
713
713
  // container
714
714
  warm: WarmSchema.default(0),
715
715
  vpc: VPCSchema.default(false),
716
- log: LogSchema.default(true).transform((log15) => ({
717
- retention: log15.retention ?? days(7),
718
- level: "level" in log15 ? log15.level : "error",
719
- system: "system" in log15 ? log15.system : "warn",
720
- format: "format" in log15 ? log15.format : "json"
716
+ log: LogSchema.default(true).transform((log16) => ({
717
+ retention: log16.retention ?? days(7),
718
+ level: "level" in log16 ? log16.level : "error",
719
+ system: "system" in log16 ? log16.system : "warn",
720
+ format: "format" in log16 ? log16.format : "json"
721
721
  })),
722
722
  timeout: TimeoutSchema.default("10 seconds"),
723
723
  memorySize: MemorySizeSchema.default("128 MB"),
@@ -3772,7 +3772,7 @@ var createPrebuildLambdaFunction = (group, ctx, ns, id, props) => {
3772
3772
  };
3773
3773
 
3774
3774
  // src/feature/rpc/index.ts
3775
- import { days as days4, seconds as seconds5, toSeconds as toSeconds5 } from "@awsless/duration";
3775
+ import { days as days4, minutes as minutes4, seconds as seconds5, toSeconds as toSeconds5 } from "@awsless/duration";
3776
3776
  var __dirname = dirname6(fileURLToPath(import.meta.url));
3777
3777
  var rpcFeature = defineFeature({
3778
3778
  name: "rpc",
@@ -3830,13 +3830,18 @@ var rpcFeature = defineFeature({
3830
3830
  bundleFile: join10(__dirname, "/prebuild/rpc/bundle.zip"),
3831
3831
  bundleHash: join10(__dirname, "/prebuild/rpc/HASH"),
3832
3832
  memorySize: mebibytes3(256),
3833
+ timeout: minutes4(3),
3833
3834
  handler: "index.default",
3834
3835
  runtime: "nodejs22.x",
3835
3836
  warm: 3,
3836
3837
  log: props.log
3837
3838
  });
3838
- const table2 = new $13.aws.dynamodb.Table(group, "schema", {
3839
- name,
3839
+ const schemaTable = new $13.aws.dynamodb.Table(group, "schema", {
3840
+ name: formatGlobalResourceName({
3841
+ appName: ctx.app.name,
3842
+ resourceType: "rpc-schema",
3843
+ resourceName: id
3844
+ }),
3840
3845
  hashKey: "query",
3841
3846
  billingMode: "PAY_PER_REQUEST",
3842
3847
  attribute: [
@@ -3846,13 +3851,38 @@ var rpcFeature = defineFeature({
3846
3851
  }
3847
3852
  ]
3848
3853
  });
3849
- result.setEnvironment("SCHEMA_TABLE", table2.name);
3854
+ result.setEnvironment("SCHEMA_TABLE", schemaTable.name);
3850
3855
  result.addPermission({
3851
3856
  effect: "allow",
3852
3857
  actions: ["dynamodb:GetItem"],
3853
- resources: [table2.arn]
3858
+ resources: [schemaTable.arn]
3859
+ });
3860
+ ctx.shared.add("rpc", `schema-table`, id, schemaTable);
3861
+ const lockTable = new $13.aws.dynamodb.Table(group, "lock", {
3862
+ name: formatGlobalResourceName({
3863
+ appName: ctx.app.name,
3864
+ resourceType: "rpc-lock",
3865
+ resourceName: id
3866
+ }),
3867
+ hashKey: "key",
3868
+ billingMode: "PAY_PER_REQUEST",
3869
+ ttl: {
3870
+ enabled: true,
3871
+ attributeName: "ttl"
3872
+ },
3873
+ attribute: [
3874
+ {
3875
+ name: "key",
3876
+ type: "S"
3877
+ }
3878
+ ]
3879
+ });
3880
+ result.setEnvironment("LOCK_TABLE", lockTable.name);
3881
+ result.addPermission({
3882
+ effect: "allow",
3883
+ actions: ["dynamodb:UpdateItem", "dynamodb:DeleteItem"],
3884
+ resources: [lockTable.arn]
3854
3885
  });
3855
- ctx.shared.add("rpc", `schema-table`, id, table2);
3856
3886
  if (props.auth) {
3857
3887
  const authGroup = new Group13(group, "auth", "authorizer");
3858
3888
  const auth2 = createLambdaFunction(authGroup, ctx, "rpc", `${id}-auth`, props.auth);
@@ -6226,8 +6256,8 @@ var CustomReporter = class {
6226
6256
  this.cache = cache;
6227
6257
  }
6228
6258
  }
6229
- onUserConsoleLog(log15) {
6230
- this.logs.push(log15.content.trimEnd());
6259
+ onUserConsoleLog(log16) {
6260
+ this.logs.push(log16.content.trimEnd());
6231
6261
  }
6232
6262
  runningTask(tasks) {
6233
6263
  return tasks.find((t) => t.result?.state === "run");
@@ -6324,7 +6354,7 @@ var logTestLogs = (event) => {
6324
6354
  log9.message(color.info.bold.inverse(" LOGS "), {
6325
6355
  symbol: color.dim(icon.dot)
6326
6356
  });
6327
- log9.message(event.logs.map((log15) => wrap(log15, { hard: true })).join("\n"));
6357
+ log9.message(event.logs.map((log16) => wrap(log16, { hard: true })).join("\n"));
6328
6358
  }
6329
6359
  };
6330
6360
  var logTestErrors = (event) => {
@@ -7047,6 +7077,144 @@ var domain = (program2) => {
7047
7077
  commands6.forEach((cb) => cb(command));
7048
7078
  };
7049
7079
 
7080
+ // src/cli/command/logs.ts
7081
+ import { CloudWatchLogsClient, StartLiveTailCommand } from "@aws-sdk/client-cloudwatch-logs";
7082
+ import { log as log15 } from "@clack/prompts";
7083
+ import chalk7 from "chalk";
7084
+ import chunk from "chunk";
7085
+ import { formatDate } from "date-fns";
7086
+ import wildstring6 from "wildstring";
7087
+ var logs = (program2) => {
7088
+ program2.command("logs").argument(`<stacks...>`, "Provide a list of stacks to stream logs from.").description("Stream the latest logs from you app.").action(async (filters) => {
7089
+ await layout(`logs`, async ({ appConfig, stackConfigs }) => {
7090
+ const region = appConfig.region;
7091
+ const profile = appConfig.profile;
7092
+ const credentials = getCredentials(profile);
7093
+ const accountId = await getAccountId(credentials, region);
7094
+ const { app } = createApp({ appConfig, stackConfigs, accountId });
7095
+ const { workspace } = await createWorkSpace({
7096
+ credentials,
7097
+ accountId,
7098
+ profile,
7099
+ region
7100
+ });
7101
+ await workspace.hydrate(app);
7102
+ const logGroupArns = [];
7103
+ for (const stack of app.stacks) {
7104
+ if (filters.find((f) => wildstring6.match(f, stack.name))) {
7105
+ for (const resource2 of stack.resources) {
7106
+ if (resource2.$.type === "aws_cloudwatch_log_group") {
7107
+ const logGroup = resource2;
7108
+ logGroupArns.push(await logGroup.arn);
7109
+ }
7110
+ }
7111
+ }
7112
+ }
7113
+ const client = new CloudWatchLogsClient({
7114
+ credentials,
7115
+ region
7116
+ });
7117
+ const abort = new AbortController();
7118
+ process.once("exit", () => {
7119
+ abort.abort();
7120
+ });
7121
+ process.once("SIGINT", () => {
7122
+ abort.abort();
7123
+ });
7124
+ const streams = await task("Connecting to the log stream...", async (update) => {
7125
+ const result = await Promise.all(
7126
+ chunk(logGroupArns, 10).map(async (arns) => {
7127
+ const command = new StartLiveTailCommand({
7128
+ logGroupIdentifiers: arns
7129
+ });
7130
+ const response = await client.send(command, {
7131
+ abortSignal: abort.signal
7132
+ });
7133
+ if (!response.responseStream) {
7134
+ throw new Error("Failed to connect to the log stream.");
7135
+ }
7136
+ return response.responseStream;
7137
+ })
7138
+ );
7139
+ update(
7140
+ `Connected to ${result.length} log stream${plural(result.length)} for ${logGroupArns.length} function${plural(logGroupArns.length)}.`
7141
+ );
7142
+ return result;
7143
+ });
7144
+ await Promise.all(
7145
+ streams.map(async (stream) => {
7146
+ for await (const event of stream) {
7147
+ if (event.sessionUpdate) {
7148
+ for (const result of event.sessionUpdate.sessionResults ?? []) {
7149
+ const group = result.logGroupIdentifier?.split(":").at(1) ?? "";
7150
+ const timestamp = result.timestamp ?? Date.now();
7151
+ const date = new Date(timestamp);
7152
+ const message = result.message ?? "";
7153
+ const data = parseJsonLog(message);
7154
+ formatLog(data.level, data.date ?? date, group, data.message);
7155
+ }
7156
+ }
7157
+ }
7158
+ })
7159
+ );
7160
+ });
7161
+ });
7162
+ };
7163
+ var plural = (count) => {
7164
+ return count > 1 ? "s" : "";
7165
+ };
7166
+ var formatLog = (level, date, group, message) => {
7167
+ const levels = {
7168
+ INFO: chalk7.cyan,
7169
+ DEBUG: chalk7.cyan,
7170
+ TRACE: chalk7.cyan,
7171
+ WARN: chalk7.yellow,
7172
+ ERROR: chalk7.red,
7173
+ FATAL: chalk7.magenta,
7174
+ SYSTEM: chalk7.blue
7175
+ };
7176
+ const levelColor = levels[level] ?? chalk7.cyan;
7177
+ log15.message(
7178
+ [
7179
+ [
7180
+ //
7181
+ levelColor(level),
7182
+ color.dim(formatDate(date, "HH:mm:ss")),
7183
+ color.info(group)
7184
+ ].join(" "),
7185
+ wrap(message)
7186
+ ].join("\n"),
7187
+ {
7188
+ symbol: levelColor(icon.dot)
7189
+ }
7190
+ );
7191
+ };
7192
+ var parseJsonLog = (message) => {
7193
+ let json3;
7194
+ try {
7195
+ json3 = JSON.parse(message);
7196
+ } catch (error) {
7197
+ }
7198
+ if ("level" in json3 && typeof json3.level === "string" && "message" in json3 && typeof json3.message === "string" && "timestamp" in json3 && typeof json3.timestamp === "string") {
7199
+ return {
7200
+ level: json3.level,
7201
+ message: json3.message,
7202
+ date: new Date(json3.timestamp)
7203
+ };
7204
+ }
7205
+ if ("type" in json3 && typeof json3.type === "string" && json3.type.startsWith("platform") && "time" in json3 && typeof json3.time === "string" && "record" in json3) {
7206
+ return {
7207
+ level: "SYSTEM",
7208
+ message: JSON.stringify(json3.record, void 0, 2),
7209
+ date: new Date(json3.time)
7210
+ };
7211
+ }
7212
+ return {
7213
+ level: "INFO",
7214
+ message: JSON.stringify(json3, void 0, 2)
7215
+ };
7216
+ };
7217
+
7050
7218
  // src/cli/command/index.ts
7051
7219
  var commands7 = [
7052
7220
  bootstrap,
@@ -7058,6 +7226,7 @@ var commands7 = [
7058
7226
  dev,
7059
7227
  bind,
7060
7228
  run,
7229
+ logs,
7061
7230
  auth,
7062
7231
  domain,
7063
7232
  state,
@@ -1 +1 @@
1
- 1b67cb66296cd56b7cc9cbddf3e7859cc9d3fad9
1
+ 483f8461993bfc3a205450c45d2a96bd1be0f53c
Binary file
package/dist/server.d.ts CHANGED
@@ -132,6 +132,7 @@ type RpcAuthorizerResponse = {
132
132
  } | {
133
133
  authorized: true;
134
134
  context?: unknown;
135
+ lockKey?: string;
135
136
  ttl: DurationFormat;
136
137
  };
137
138
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@awsless/awsless",
3
- "version": "0.0.465",
3
+ "version": "0.0.467",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -32,12 +32,12 @@
32
32
  "@awsless/iot": "^0.0.3",
33
33
  "@awsless/json": "^0.0.8",
34
34
  "@awsless/lambda": "^0.0.32",
35
- "@awsless/mqtt": "^0.0.2",
36
35
  "@awsless/open-search": "^0.0.17",
36
+ "@awsless/mqtt": "^0.0.2",
37
+ "@awsless/sns": "^0.0.10",
37
38
  "@awsless/redis": "^0.0.14",
38
39
  "@awsless/s3": "^0.0.20",
39
40
  "@awsless/sqs": "^0.0.8",
40
- "@awsless/sns": "^0.0.10",
41
41
  "@awsless/ssm": "^0.0.7",
42
42
  "@awsless/validate": "^0.0.19",
43
43
  "@awsless/weak-cache": "^0.0.1"
@@ -47,6 +47,7 @@
47
47
  "@aws-appsync/utils": "^1.5.0",
48
48
  "@aws-sdk/client-cloudformation": "^3.369.0",
49
49
  "@aws-sdk/client-cloudfront": "^3.425.0",
50
+ "@aws-sdk/client-cloudwatch-logs": "^3.806.0",
50
51
  "@aws-sdk/client-cognito-identity-provider": "^3.441.0",
51
52
  "@aws-sdk/client-dynamodb": "3.363.0",
52
53
  "@aws-sdk/client-lambda": "3.329.0",
@@ -118,14 +119,14 @@
118
119
  "zip-a-folder": "^3.1.6",
119
120
  "zod": "^3.24.2",
120
121
  "zod-to-json-schema": "^3.24.3",
122
+ "@awsless/duration": "^0.0.3",
121
123
  "@awsless/code": "^0.0.10",
122
- "@awsless/formation": "^0.0.72",
123
- "@awsless/graphql": "^0.0.9",
124
+ "@awsless/formation": "^0.0.73",
124
125
  "@awsless/json": "^0.0.8",
126
+ "@awsless/graphql": "^0.0.9",
125
127
  "@awsless/size": "^0.0.2",
126
128
  "@awsless/ts-file-cache": "^0.0.12",
127
- "@awsless/validate": "^0.0.19",
128
- "@awsless/duration": "^0.0.3"
129
+ "@awsless/validate": "^0.0.19"
129
130
  },
130
131
  "devDependencies": {
131
132
  "@node-rs/bcrypt": "^1.10.5"