@awsless/awsless 0.0.30 → 0.0.32

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.cjs CHANGED
@@ -1021,6 +1021,7 @@ var hasOnFailure = (config) => {
1021
1021
  };
1022
1022
 
1023
1023
  // src/plugins/function.ts
1024
+ var import_change_case3 = require("change-case");
1024
1025
  var MemorySizeSchema = SizeSchema.refine(sizeMin(Size.megaBytes(128)), "Minimum memory size is 128 MB").refine(sizeMax(Size.gigaBytes(10)), "Minimum memory size is 10 GB");
1025
1026
  var TimeoutSchema = DurationSchema.refine(durationMin(Duration.seconds(10)), "Minimum timeout duration is 10 seconds").refine(durationMax(Duration.minutes(15)), "Maximum timeout duration is 15 minutes");
1026
1027
  var EphemeralStorageSizeSchema = SizeSchema.refine(sizeMin(Size.megaBytes(512)), "Minimum ephemeral storage size is 512 MB").refine(sizeMax(Size.gigaBytes(10)), "Minimum ephemeral storage size is 10 GB");
@@ -1158,6 +1159,46 @@ var schema = import_zod6.z.object({
1158
1159
  var functionPlugin = definePlugin({
1159
1160
  name: "function",
1160
1161
  schema,
1162
+ onTypeGen({ config }) {
1163
+ const imports = [];
1164
+ const props = [];
1165
+ for (const stack of config.stacks) {
1166
+ const functions = [];
1167
+ for (const [name, fileOrProps] of Object.entries(stack.functions || {})) {
1168
+ const varName = (0, import_change_case3.camelCase)(`${stack.name}-${name}`);
1169
+ const file = typeof fileOrProps === "string" ? fileOrProps : fileOrProps.file;
1170
+ imports.push(`import ${varName} from '${file}'`);
1171
+ functions.push(` readonly ${(0, import_change_case3.camelCase)(name)}: Invoke<typeof ${varName}>`);
1172
+ }
1173
+ if (functions.length > 0) {
1174
+ props.push(` readonly ${(0, import_change_case3.camelCase)(stack.name)}: {
1175
+ ${functions.join("\n")}
1176
+ }`);
1177
+ }
1178
+ }
1179
+ if (imports.length === 0) {
1180
+ return;
1181
+ }
1182
+ return (
1183
+ /* TS */
1184
+ `
1185
+ ${imports.join("\n")}
1186
+
1187
+ import { InvokeOptions } from '@awsless/lambda'
1188
+
1189
+ type InvokeOptions = Omit<InvokeOptions, 'name' | 'payload'>
1190
+
1191
+ type Invoke<Func extends (...args: any[]) => any> = {
1192
+ (event: Parameters<Func>[0], options?: InvokeOptions): ReturnType<Func>
1193
+ }
1194
+
1195
+ declare module '@awsless/awsless' {
1196
+ interface Function {
1197
+ ${props.join("\n")}
1198
+ }
1199
+ }`
1200
+ );
1201
+ },
1161
1202
  onStack(ctx) {
1162
1203
  const { config, stack } = ctx;
1163
1204
  for (const [id, fileOrProps] of Object.entries(ctx.stackConfig.functions || {})) {
@@ -1183,7 +1224,7 @@ var toLambdaFunction = (ctx, id, fileOrProps) => {
1183
1224
  const stack = ctx.stack;
1184
1225
  const props = typeof fileOrProps === "string" ? { ...config.defaults?.function, file: fileOrProps } : { ...config.defaults?.function, ...fileOrProps };
1185
1226
  const lambda = new Function(id, {
1186
- name: `${config.name}-${stack.name}-${id}`,
1227
+ name: `${config.name}--${stack.name}--${id}`,
1187
1228
  code: Code.fromFile(id, props.file),
1188
1229
  ...props,
1189
1230
  vpc: void 0
@@ -1387,7 +1428,7 @@ var Queue = class extends Resource {
1387
1428
  };
1388
1429
 
1389
1430
  // src/formation/resource/lambda/event-source-mapping.ts
1390
- var import_change_case3 = require("change-case");
1431
+ var import_change_case4 = require("change-case");
1391
1432
  var EventSourceMapping = class extends Resource {
1392
1433
  constructor(logicalId, props) {
1393
1434
  super("AWS::Lambda::EventSourceMapping", logicalId);
@@ -1409,7 +1450,7 @@ var EventSourceMapping = class extends Resource {
1409
1450
  ...this.attr("ParallelizationFactor", this.props.parallelizationFactor),
1410
1451
  ...this.attr("TumblingWindowInSeconds", this.props.tumblingWindow?.toSeconds()),
1411
1452
  ...this.attr("BisectBatchOnFunctionError", this.props.bisectBatchOnError),
1412
- ...this.attr("StartingPosition", this.props.startingPosition && (0, import_change_case3.constantCase)(this.props.startingPosition)),
1453
+ ...this.attr("StartingPosition", this.props.startingPosition && (0, import_change_case4.constantCase)(this.props.startingPosition)),
1413
1454
  ...this.attr("StartingPositionTimestamp", this.props.startingPositionTimestamp),
1414
1455
  ...this.props.maxConcurrency ? {
1415
1456
  ScalingConfig: {
@@ -1585,7 +1626,7 @@ var queuePlugin = definePlugin({
1585
1626
  var import_zod9 = require("zod");
1586
1627
 
1587
1628
  // src/formation/resource/dynamodb/table.ts
1588
- var import_change_case4 = require("change-case");
1629
+ var import_change_case5 = require("change-case");
1589
1630
  var Table = class extends Resource {
1590
1631
  constructor(logicalId, props) {
1591
1632
  super("AWS::DynamoDB::Table", logicalId);
@@ -1644,21 +1685,21 @@ var Table = class extends Resource {
1644
1685
  index.sort
1645
1686
  ])
1646
1687
  ].flat().filter(Boolean));
1647
- const types = {
1688
+ const types2 = {
1648
1689
  string: "S",
1649
1690
  number: "N",
1650
1691
  binary: "B"
1651
1692
  };
1652
1693
  return [...attributes].map((name) => ({
1653
1694
  AttributeName: name,
1654
- AttributeType: types[fields[name] || "string"]
1695
+ AttributeType: types2[fields[name] || "string"]
1655
1696
  }));
1656
1697
  }
1657
1698
  properties() {
1658
1699
  return {
1659
1700
  TableName: this.name,
1660
1701
  BillingMode: "PAY_PER_REQUEST",
1661
- TableClass: (0, import_change_case4.constantCase)(this.props.class || "standard"),
1702
+ TableClass: (0, import_change_case5.constantCase)(this.props.class || "standard"),
1662
1703
  PointInTimeRecoverySpecification: {
1663
1704
  PointInTimeRecoveryEnabled: this.props.pointInTimeRecovery || false
1664
1705
  },
@@ -1669,7 +1710,7 @@ var Table = class extends Resource {
1669
1710
  AttributeDefinitions: this.attributeDefinitions(),
1670
1711
  ...this.props.stream ? {
1671
1712
  StreamSpecification: {
1672
- StreamViewType: (0, import_change_case4.constantCase)(this.props.stream)
1713
+ StreamViewType: (0, import_change_case5.constantCase)(this.props.stream)
1673
1714
  }
1674
1715
  } : {},
1675
1716
  ...this.props.timeToLiveAttribute ? {
@@ -1686,7 +1727,7 @@ var Table = class extends Resource {
1686
1727
  ...props.sort ? [{ KeyType: "RANGE", AttributeName: props.sort }] : []
1687
1728
  ],
1688
1729
  Projection: {
1689
- ProjectionType: (0, import_change_case4.constantCase)(props.projection || "all")
1730
+ ProjectionType: (0, import_change_case5.constantCase)(props.projection || "all")
1690
1731
  }
1691
1732
  }))
1692
1733
  } : {}
@@ -1859,7 +1900,7 @@ var tablePlugin = definePlugin({
1859
1900
  var import_zod10 = require("zod");
1860
1901
 
1861
1902
  // src/formation/resource/s3/bucket.ts
1862
- var import_change_case5 = require("change-case");
1903
+ var import_change_case6 = require("change-case");
1863
1904
  var Bucket = class extends Resource {
1864
1905
  constructor(logicalId, props = {}) {
1865
1906
  super("AWS::S3::Bucket", logicalId);
@@ -1894,7 +1935,7 @@ var Bucket = class extends Resource {
1894
1935
  properties() {
1895
1936
  return {
1896
1937
  BucketName: this.name,
1897
- AccessControl: (0, import_change_case5.pascalCase)(this.props.accessControl ?? "private"),
1938
+ AccessControl: (0, import_change_case6.pascalCase)(this.props.accessControl ?? "private"),
1898
1939
  ...this.props.versioned ? {
1899
1940
  VersioningConfiguration: {
1900
1941
  Status: "Enabled"
@@ -2075,12 +2116,12 @@ var extendPlugin = definePlugin({
2075
2116
  var import_zod13 = require("zod");
2076
2117
 
2077
2118
  // src/formation/resource/iot/topic-rule.ts
2078
- var import_change_case6 = require("change-case");
2119
+ var import_change_case7 = require("change-case");
2079
2120
  var TopicRule = class extends Resource {
2080
2121
  constructor(logicalId, props) {
2081
2122
  super("AWS::IoT::TopicRule", logicalId);
2082
2123
  this.props = props;
2083
- this.name = (0, import_change_case6.snakeCase)(this.props.name || logicalId);
2124
+ this.name = (0, import_change_case7.snakeCase)(this.props.name || logicalId);
2084
2125
  }
2085
2126
  name;
2086
2127
  get arn() {
@@ -2180,10 +2221,10 @@ var toArray = (value) => {
2180
2221
  };
2181
2222
 
2182
2223
  // src/plugins/graphql.ts
2183
- var import_change_case10 = require("change-case");
2224
+ var import_change_case11 = require("change-case");
2184
2225
 
2185
2226
  // src/formation/resource/appsync/graphql-api.ts
2186
- var import_change_case7 = require("change-case");
2227
+ var import_change_case8 = require("change-case");
2187
2228
  var GraphQLApi = class extends Resource {
2188
2229
  constructor(logicalId, props) {
2189
2230
  super("AWS::AppSync::GraphQLApi", logicalId);
@@ -2215,7 +2256,7 @@ var GraphQLApi = class extends Resource {
2215
2256
  properties() {
2216
2257
  return {
2217
2258
  Name: this.name,
2218
- AuthenticationType: (0, import_change_case7.constantCase)(this.props.authenticationType || "api-key"),
2259
+ AuthenticationType: (0, import_change_case8.constantCase)(this.props.authenticationType || "api-key"),
2219
2260
  AdditionalAuthenticationProviders: this.lambdaAuthProviders.map((provider) => ({
2220
2261
  AuthenticationType: "AWS_LAMBDA",
2221
2262
  LambdaAuthorizerConfig: {
@@ -2342,12 +2383,12 @@ var FileCode2 = class extends Asset {
2342
2383
  };
2343
2384
 
2344
2385
  // src/formation/resource/appsync/data-source.ts
2345
- var import_change_case8 = require("change-case");
2386
+ var import_change_case9 = require("change-case");
2346
2387
  var DataSource = class extends Resource {
2347
2388
  constructor(logicalId, props) {
2348
2389
  super("AWS::AppSync::DataSource", logicalId);
2349
2390
  this.props = props;
2350
- this.name = (0, import_change_case8.snakeCase)(this.props.name || logicalId);
2391
+ this.name = (0, import_change_case9.snakeCase)(this.props.name || logicalId);
2351
2392
  }
2352
2393
  static fromLambda(logicalId, apiId, props) {
2353
2394
  return new DataSource(logicalId, {
@@ -2387,14 +2428,14 @@ var DataSource = class extends Resource {
2387
2428
  };
2388
2429
 
2389
2430
  // src/formation/resource/appsync/function-configuration.ts
2390
- var import_change_case9 = require("change-case");
2431
+ var import_change_case10 = require("change-case");
2391
2432
  var FunctionConfiguration = class extends Resource {
2392
2433
  constructor(logicalId, props) {
2393
2434
  super("AWS::AppSync::FunctionConfiguration", logicalId, [
2394
2435
  props.code
2395
2436
  ]);
2396
2437
  this.props = props;
2397
- this.name = (0, import_change_case9.snakeCase)(this.props.name || logicalId);
2438
+ this.name = (0, import_change_case10.snakeCase)(this.props.name || logicalId);
2398
2439
  }
2399
2440
  name;
2400
2441
  get id() {
@@ -2613,7 +2654,7 @@ var graphqlPlugin = definePlugin({
2613
2654
  const apiId = bootstrap2.import(`graphql-${id}`);
2614
2655
  for (const [typeAndField, functionProps] of Object.entries(props.resolvers || {})) {
2615
2656
  const [typeName, fieldName] = typeAndField.split(/[\s]+/g);
2616
- const entryId = (0, import_change_case10.paramCase)(`${id}-${typeName}-${fieldName}`);
2657
+ const entryId = (0, import_change_case11.paramCase)(`${id}-${typeName}-${fieldName}`);
2617
2658
  const lambda = toLambdaFunction(ctx, `graphql-${entryId}`, functionProps);
2618
2659
  const source = new AppsyncEventSource(entryId, lambda, {
2619
2660
  apiId,
@@ -3297,7 +3338,7 @@ var LoadBalancer = class extends Resource {
3297
3338
  };
3298
3339
 
3299
3340
  // src/formation/resource/elb/listener.ts
3300
- var import_change_case11 = require("change-case");
3341
+ var import_change_case12 = require("change-case");
3301
3342
  var Listener = class extends Resource {
3302
3343
  constructor(logicalId, props) {
3303
3344
  super("AWS::ElasticLoadBalancingV2::Listener", logicalId);
@@ -3313,7 +3354,7 @@ var Listener = class extends Resource {
3313
3354
  return {
3314
3355
  LoadBalancerArn: this.props.loadBalancerArn,
3315
3356
  Port: this.props.port,
3316
- Protocol: (0, import_change_case11.constantCase)(this.props.protocol),
3357
+ Protocol: (0, import_change_case12.constantCase)(this.props.protocol),
3317
3358
  Certificates: this.props.certificates.map((arn) => ({
3318
3359
  CertificateArn: arn
3319
3360
  })),
@@ -4175,6 +4216,9 @@ var directories = {
4175
4216
  get asset() {
4176
4217
  return (0, import_path2.join)(this.output, "asset");
4177
4218
  },
4219
+ get types() {
4220
+ return (0, import_path2.join)(this.output, "types");
4221
+ },
4178
4222
  get template() {
4179
4223
  return (0, import_path2.join)(this.output, "template");
4180
4224
  }
@@ -4864,6 +4908,7 @@ var cleanUp = async () => {
4864
4908
  const paths = [
4865
4909
  directories.asset,
4866
4910
  directories.cache,
4911
+ directories.types,
4867
4912
  directories.template
4868
4913
  ];
4869
4914
  await Promise.all(paths.map((path) => (0, import_promises7.rm)(path, {
@@ -4893,12 +4938,39 @@ var templateBuilder = (app) => {
4893
4938
  };
4894
4939
  };
4895
4940
 
4941
+ // src/util/type-gen.ts
4942
+ var import_promises9 = require("fs/promises");
4943
+ var import_path13 = require("path");
4944
+ var generateResourceTypes = async (config) => {
4945
+ const plugins = [
4946
+ ...defaultPlugins,
4947
+ ...config.plugins || []
4948
+ ];
4949
+ for (const plugin of plugins) {
4950
+ const code = plugin.onTypeGen?.({ config });
4951
+ if (code) {
4952
+ await (0, import_promises9.mkdir)(directories.types, { recursive: true });
4953
+ await (0, import_promises9.writeFile)((0, import_path13.join)(directories.types, `${plugin.name}.d.ts`), code);
4954
+ }
4955
+ }
4956
+ };
4957
+
4958
+ // src/cli/ui/complex/types.ts
4959
+ var typesGenerator = (config) => {
4960
+ return async (term) => {
4961
+ const done = term.out.write(loadingDialog("Generate type definition files..."));
4962
+ await generateResourceTypes(config);
4963
+ done("Done generating type definition files");
4964
+ };
4965
+ };
4966
+
4896
4967
  // src/cli/command/build.ts
4897
4968
  var build = (program2) => {
4898
4969
  program2.command("build").argument("[stack...]", "Optionally filter stacks to build").description("Build your app").action(async (filters) => {
4899
4970
  await layout(async (config, write) => {
4900
4971
  const { app } = await toApp(config, filters);
4901
4972
  await cleanUp();
4973
+ await write(typesGenerator(config));
4902
4974
  await write(assetBuilder(app));
4903
4975
  await write(templateBuilder(app));
4904
4976
  });
@@ -4935,7 +5007,7 @@ var shouldDeployBootstrap = async (client, stack) => {
4935
5007
  // src/formation/client.ts
4936
5008
  var import_client_cloudformation = require("@aws-sdk/client-cloudformation");
4937
5009
  var import_client_s3 = require("@aws-sdk/client-s3");
4938
- var import_change_case12 = require("change-case");
5010
+ var import_change_case13 = require("change-case");
4939
5011
  var StackClient = class {
4940
5012
  constructor(app, account, region, credentials) {
4941
5013
  this.app = app;
@@ -4968,7 +5040,7 @@ var StackClient = class {
4968
5040
  };
4969
5041
  }
4970
5042
  stackName(stackName) {
4971
- return (0, import_change_case12.paramCase)(`${this.app.name}-${stackName}`);
5043
+ return (0, import_change_case13.paramCase)(`${this.app.name}-${stackName}`);
4972
5044
  }
4973
5045
  tags(stack) {
4974
5046
  const tags = [];
@@ -5395,8 +5467,8 @@ var status = (program2) => {
5395
5467
  };
5396
5468
 
5397
5469
  // src/cli/ui/complex/publisher.ts
5398
- var import_promises9 = require("fs/promises");
5399
- var import_path13 = require("path");
5470
+ var import_promises10 = require("fs/promises");
5471
+ var import_path15 = require("path");
5400
5472
  var import_client_s32 = require("@aws-sdk/client-s3");
5401
5473
  var assetPublisher = (config, app) => {
5402
5474
  const client = new import_client_s32.S3Client({
@@ -5409,8 +5481,8 @@ var assetPublisher = (config, app) => {
5409
5481
  await Promise.all([...stack.assets].map(async (asset) => {
5410
5482
  await asset.publish?.({
5411
5483
  async read(file) {
5412
- const path = (0, import_path13.join)(directories.asset, asset.type, app.name, stack.name, asset.id, file);
5413
- const data = await (0, import_promises9.readFile)(path);
5484
+ const path = (0, import_path15.join)(directories.asset, asset.type, app.name, stack.name, asset.id, file);
5485
+ const data = await (0, import_promises10.readFile)(path);
5414
5486
  return data;
5415
5487
  },
5416
5488
  async publish(name, data, hash) {
@@ -5474,6 +5546,7 @@ var deploy = (program2) => {
5474
5546
  throw new Cancelled();
5475
5547
  }
5476
5548
  await cleanUp();
5549
+ await write(typesGenerator(config));
5477
5550
  await write(assetBuilder(app));
5478
5551
  await write(assetPublisher(config, app));
5479
5552
  await write(templateBuilder(app));
@@ -5663,6 +5736,16 @@ var test = (program2) => {
5663
5736
  });
5664
5737
  };
5665
5738
 
5739
+ // src/cli/command/types.ts
5740
+ var types = (program2) => {
5741
+ program2.command("types").description("Generate type definition files").action(async () => {
5742
+ await layout(async (config, write) => {
5743
+ await cleanUp();
5744
+ await write(typesGenerator(config));
5745
+ });
5746
+ });
5747
+ };
5748
+
5666
5749
  // src/cli/program.ts
5667
5750
  var program = new import_commander.Command();
5668
5751
  program.name(logo().join("").replace(/\s+/, ""));
@@ -5681,6 +5764,7 @@ program.on("option:verbose", () => {
5681
5764
  var commands2 = [
5682
5765
  bootstrap,
5683
5766
  status,
5767
+ types,
5684
5768
  build,
5685
5769
  deploy,
5686
5770
  secrets,
package/dist/bin.js CHANGED
@@ -998,6 +998,7 @@ var hasOnFailure = (config) => {
998
998
  };
999
999
 
1000
1000
  // src/plugins/function.ts
1001
+ import { camelCase } from "change-case";
1001
1002
  var MemorySizeSchema = SizeSchema.refine(sizeMin(Size.megaBytes(128)), "Minimum memory size is 128 MB").refine(sizeMax(Size.gigaBytes(10)), "Minimum memory size is 10 GB");
1002
1003
  var TimeoutSchema = DurationSchema.refine(durationMin(Duration.seconds(10)), "Minimum timeout duration is 10 seconds").refine(durationMax(Duration.minutes(15)), "Maximum timeout duration is 15 minutes");
1003
1004
  var EphemeralStorageSizeSchema = SizeSchema.refine(sizeMin(Size.megaBytes(512)), "Minimum ephemeral storage size is 512 MB").refine(sizeMax(Size.gigaBytes(10)), "Minimum ephemeral storage size is 10 GB");
@@ -1135,6 +1136,46 @@ var schema = z6.object({
1135
1136
  var functionPlugin = definePlugin({
1136
1137
  name: "function",
1137
1138
  schema,
1139
+ onTypeGen({ config }) {
1140
+ const imports = [];
1141
+ const props = [];
1142
+ for (const stack of config.stacks) {
1143
+ const functions = [];
1144
+ for (const [name, fileOrProps] of Object.entries(stack.functions || {})) {
1145
+ const varName = camelCase(`${stack.name}-${name}`);
1146
+ const file = typeof fileOrProps === "string" ? fileOrProps : fileOrProps.file;
1147
+ imports.push(`import ${varName} from '${file}'`);
1148
+ functions.push(` readonly ${camelCase(name)}: Invoke<typeof ${varName}>`);
1149
+ }
1150
+ if (functions.length > 0) {
1151
+ props.push(` readonly ${camelCase(stack.name)}: {
1152
+ ${functions.join("\n")}
1153
+ }`);
1154
+ }
1155
+ }
1156
+ if (imports.length === 0) {
1157
+ return;
1158
+ }
1159
+ return (
1160
+ /* TS */
1161
+ `
1162
+ ${imports.join("\n")}
1163
+
1164
+ import { InvokeOptions } from '@awsless/lambda'
1165
+
1166
+ type InvokeOptions = Omit<InvokeOptions, 'name' | 'payload'>
1167
+
1168
+ type Invoke<Func extends (...args: any[]) => any> = {
1169
+ (event: Parameters<Func>[0], options?: InvokeOptions): ReturnType<Func>
1170
+ }
1171
+
1172
+ declare module '@awsless/awsless' {
1173
+ interface Function {
1174
+ ${props.join("\n")}
1175
+ }
1176
+ }`
1177
+ );
1178
+ },
1138
1179
  onStack(ctx) {
1139
1180
  const { config, stack } = ctx;
1140
1181
  for (const [id, fileOrProps] of Object.entries(ctx.stackConfig.functions || {})) {
@@ -1160,7 +1201,7 @@ var toLambdaFunction = (ctx, id, fileOrProps) => {
1160
1201
  const stack = ctx.stack;
1161
1202
  const props = typeof fileOrProps === "string" ? { ...config.defaults?.function, file: fileOrProps } : { ...config.defaults?.function, ...fileOrProps };
1162
1203
  const lambda = new Function(id, {
1163
- name: `${config.name}-${stack.name}-${id}`,
1204
+ name: `${config.name}--${stack.name}--${id}`,
1164
1205
  code: Code.fromFile(id, props.file),
1165
1206
  ...props,
1166
1207
  vpc: void 0
@@ -1621,14 +1662,14 @@ var Table = class extends Resource {
1621
1662
  index.sort
1622
1663
  ])
1623
1664
  ].flat().filter(Boolean));
1624
- const types = {
1665
+ const types2 = {
1625
1666
  string: "S",
1626
1667
  number: "N",
1627
1668
  binary: "B"
1628
1669
  };
1629
1670
  return [...attributes].map((name) => ({
1630
1671
  AttributeName: name,
1631
- AttributeType: types[fields[name] || "string"]
1672
+ AttributeType: types2[fields[name] || "string"]
1632
1673
  }));
1633
1674
  }
1634
1675
  properties() {
@@ -4152,6 +4193,9 @@ var directories = {
4152
4193
  get asset() {
4153
4194
  return join(this.output, "asset");
4154
4195
  },
4196
+ get types() {
4197
+ return join(this.output, "types");
4198
+ },
4155
4199
  get template() {
4156
4200
  return join(this.output, "template");
4157
4201
  }
@@ -4841,6 +4885,7 @@ var cleanUp = async () => {
4841
4885
  const paths = [
4842
4886
  directories.asset,
4843
4887
  directories.cache,
4888
+ directories.types,
4844
4889
  directories.template
4845
4890
  ];
4846
4891
  await Promise.all(paths.map((path) => rm(path, {
@@ -4870,12 +4915,39 @@ var templateBuilder = (app) => {
4870
4915
  };
4871
4916
  };
4872
4917
 
4918
+ // src/util/type-gen.ts
4919
+ import { mkdir as mkdir5, writeFile as writeFile4 } from "fs/promises";
4920
+ import { join as join6 } from "path";
4921
+ var generateResourceTypes = async (config) => {
4922
+ const plugins = [
4923
+ ...defaultPlugins,
4924
+ ...config.plugins || []
4925
+ ];
4926
+ for (const plugin of plugins) {
4927
+ const code = plugin.onTypeGen?.({ config });
4928
+ if (code) {
4929
+ await mkdir5(directories.types, { recursive: true });
4930
+ await writeFile4(join6(directories.types, `${plugin.name}.d.ts`), code);
4931
+ }
4932
+ }
4933
+ };
4934
+
4935
+ // src/cli/ui/complex/types.ts
4936
+ var typesGenerator = (config) => {
4937
+ return async (term) => {
4938
+ const done = term.out.write(loadingDialog("Generate type definition files..."));
4939
+ await generateResourceTypes(config);
4940
+ done("Done generating type definition files");
4941
+ };
4942
+ };
4943
+
4873
4944
  // src/cli/command/build.ts
4874
4945
  var build = (program2) => {
4875
4946
  program2.command("build").argument("[stack...]", "Optionally filter stacks to build").description("Build your app").action(async (filters) => {
4876
4947
  await layout(async (config, write) => {
4877
4948
  const { app } = await toApp(config, filters);
4878
4949
  await cleanUp();
4950
+ await write(typesGenerator(config));
4879
4951
  await write(assetBuilder(app));
4880
4952
  await write(templateBuilder(app));
4881
4953
  });
@@ -5373,7 +5445,7 @@ var status = (program2) => {
5373
5445
 
5374
5446
  // src/cli/ui/complex/publisher.ts
5375
5447
  import { readFile as readFile3 } from "fs/promises";
5376
- import { join as join6 } from "path";
5448
+ import { join as join7 } from "path";
5377
5449
  import { GetObjectCommand, ObjectCannedACL as ObjectCannedACL2, PutObjectCommand as PutObjectCommand2, S3Client as S3Client2, StorageClass as StorageClass2 } from "@aws-sdk/client-s3";
5378
5450
  var assetPublisher = (config, app) => {
5379
5451
  const client = new S3Client2({
@@ -5386,7 +5458,7 @@ var assetPublisher = (config, app) => {
5386
5458
  await Promise.all([...stack.assets].map(async (asset) => {
5387
5459
  await asset.publish?.({
5388
5460
  async read(file) {
5389
- const path = join6(directories.asset, asset.type, app.name, stack.name, asset.id, file);
5461
+ const path = join7(directories.asset, asset.type, app.name, stack.name, asset.id, file);
5390
5462
  const data = await readFile3(path);
5391
5463
  return data;
5392
5464
  },
@@ -5451,6 +5523,7 @@ var deploy = (program2) => {
5451
5523
  throw new Cancelled();
5452
5524
  }
5453
5525
  await cleanUp();
5526
+ await write(typesGenerator(config));
5454
5527
  await write(assetBuilder(app));
5455
5528
  await write(assetPublisher(config, app));
5456
5529
  await write(templateBuilder(app));
@@ -5640,6 +5713,16 @@ var test = (program2) => {
5640
5713
  });
5641
5714
  };
5642
5715
 
5716
+ // src/cli/command/types.ts
5717
+ var types = (program2) => {
5718
+ program2.command("types").description("Generate type definition files").action(async () => {
5719
+ await layout(async (config, write) => {
5720
+ await cleanUp();
5721
+ await write(typesGenerator(config));
5722
+ });
5723
+ });
5724
+ };
5725
+
5643
5726
  // src/cli/program.ts
5644
5727
  var program = new Command();
5645
5728
  program.name(logo().join("").replace(/\s+/, ""));
@@ -5658,6 +5741,7 @@ program.on("option:verbose", () => {
5658
5741
  var commands2 = [
5659
5742
  bootstrap,
5660
5743
  status,
5744
+ types,
5661
5745
  build,
5662
5746
  deploy,
5663
5747
  secrets,
package/dist/index.cjs CHANGED
@@ -20,6 +20,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var src_exports = {};
22
22
  __export(src_exports, {
23
+ Function: () => Function,
24
+ Table: () => Table,
23
25
  defineAppConfig: () => defineAppConfig,
24
26
  definePlugin: () => definePlugin,
25
27
  defineStackConfig: () => defineStackConfig,
@@ -40,19 +42,16 @@ module.exports = __toCommonJS(src_exports);
40
42
  var definePlugin = (plugin) => plugin;
41
43
 
42
44
  // src/node/resource.ts
45
+ var import_change_case = require("change-case");
43
46
  var APP = process.env.APP || "app";
44
47
  var STACK = process.env.STACK || "stack";
45
48
  var getLocalResourceName = (name, stack = STACK) => {
46
- return `${APP}-${stack}-${name}`;
49
+ return `${APP}--${(0, import_change_case.paramCase)(stack)}--${(0, import_change_case.paramCase)(name)}`;
47
50
  };
48
51
  var getGlobalResourceName = (name) => {
49
- return `${APP}-${name}`;
50
- };
51
- var getFunctionName = (stack, name) => {
52
- return getLocalResourceName(name, stack);
52
+ return `${APP}--${(0, import_change_case.paramCase)(name)}`;
53
53
  };
54
54
  var getSearchName = getLocalResourceName;
55
- var getTableName = getLocalResourceName;
56
55
  var getStoreName = getLocalResourceName;
57
56
  var getQueueName = getLocalResourceName;
58
57
  var getTopicName = getGlobalResourceName;
@@ -67,6 +66,46 @@ var getCacheProps = (name, stack = STACK) => {
67
66
  };
68
67
  };
69
68
 
69
+ // src/node/function.ts
70
+ var import_lambda = require("@awsless/lambda");
71
+
72
+ // src/node/util.ts
73
+ var createProxy = (cb) => {
74
+ const cache = /* @__PURE__ */ new Map();
75
+ return new Proxy({}, {
76
+ get(_, name) {
77
+ if (!cache.has(name)) {
78
+ cache.set(name, cb(name));
79
+ }
80
+ return cache.get(name);
81
+ }
82
+ });
83
+ };
84
+
85
+ // src/node/function.ts
86
+ var getFunctionName = (stack, name) => {
87
+ return getLocalResourceName(name, stack);
88
+ };
89
+ var Function = createProxy((stack) => {
90
+ return createProxy((name) => {
91
+ return (event, options = {}) => {
92
+ return (0, import_lambda.invoke)({
93
+ ...options,
94
+ name: getFunctionName(stack, name),
95
+ payload: event
96
+ });
97
+ };
98
+ });
99
+ });
100
+
101
+ // src/node/table.ts
102
+ var getTableName = getLocalResourceName;
103
+ var Table = createProxy((stack) => {
104
+ return createProxy((name) => {
105
+ return getTableName(name, stack);
106
+ });
107
+ });
108
+
70
109
  // src/index.ts
71
110
  var defineStackConfig = (config) => {
72
111
  return config;
@@ -76,6 +115,8 @@ var defineAppConfig = (config) => {
76
115
  };
77
116
  // Annotate the CommonJS export names for ESM import in node:
78
117
  0 && (module.exports = {
118
+ Function,
119
+ Table,
79
120
  defineAppConfig,
80
121
  definePlugin,
81
122
  defineStackConfig,
package/dist/index.d.ts CHANGED
@@ -2382,7 +2382,7 @@ type FunctionProps = {
2382
2382
  subnetIds: string[];
2383
2383
  };
2384
2384
  };
2385
- declare class Function extends Resource {
2385
+ declare class Function$1 extends Resource {
2386
2386
  private props;
2387
2387
  readonly name: string;
2388
2388
  private role;
@@ -2429,7 +2429,7 @@ declare class Function extends Resource {
2429
2429
  };
2430
2430
  }
2431
2431
 
2432
- type Binding = (lambda: Function) => void;
2432
+ type Binding = (lambda: Function$1) => void;
2433
2433
 
2434
2434
  type ExtendedConfigOutput<S extends AnyZodObject | undefined = undefined> = (S extends AnyZodObject ? BaseConfig & z.output<S> : BaseConfig);
2435
2435
  type ExtendedConfigInput<S extends AnyZodObject | undefined = undefined> = (S extends AnyZodObject ? AppConfigInput & z.input<S> : AppConfigInput);
@@ -2457,29 +2457,37 @@ type AppContext<S extends AnyZodObject | undefined = undefined> = {
2457
2457
  app: App;
2458
2458
  bind: (cb: Binding) => void;
2459
2459
  };
2460
+ type TypeGenContext<S extends AnyZodObject | undefined = undefined> = {
2461
+ config: ExtendedConfigOutput<S>;
2462
+ };
2460
2463
  type Plugin<S extends AnyZodObject | undefined = undefined> = {
2461
2464
  name: string;
2462
2465
  schema?: S;
2463
2466
  onApp?: (context: AppContext<S>) => void;
2464
2467
  onStack?: (context: StackContext<S>) => void;
2465
2468
  onResource?: (context: ResourceContext<S>) => void;
2469
+ onTypeGen?: (context: TypeGenContext<S>) => string | void;
2466
2470
  };
2467
2471
  declare const definePlugin: <S extends AnyZodObject | undefined = undefined>(plugin: Plugin<S>) => Plugin<S>;
2468
2472
 
2469
- declare const getLocalResourceName: <N extends string, S extends string = "stack">(name: N, stack?: S) => `app-${S}-${N}`;
2470
- declare const getGlobalResourceName: <N extends string>(name: N) => `app-${N}`;
2471
- declare const getFunctionName: (stack: string, name: string) => `app-${string}-${string}`;
2472
- declare const getSearchName: <N extends string, S extends string = "stack">(name: N, stack?: S) => `app-${S}-${N}`;
2473
- declare const getTableName: <N extends string, S extends string = "stack">(name: N, stack?: S) => `app-${S}-${N}`;
2474
- declare const getStoreName: <N extends string, S extends string = "stack">(name: N, stack?: S) => `app-${S}-${N}`;
2475
- declare const getQueueName: <N extends string, S extends string = "stack">(name: N, stack?: S) => `app-${S}-${N}`;
2476
- declare const getTopicName: <N extends string>(name: N) => `app-${N}`;
2473
+ declare const getLocalResourceName: <N extends string, S extends string = "stack">(name: N, stack?: S) => `app--${S}--${N}`;
2474
+ declare const getGlobalResourceName: <N extends string>(name: N) => `app--${N}`;
2475
+ declare const getSearchName: <N extends string, S extends string = "stack">(name: N, stack?: S) => `app--${S}--${N}`;
2476
+ declare const getStoreName: <N extends string, S extends string = "stack">(name: N, stack?: S) => `app--${S}--${N}`;
2477
+ declare const getQueueName: <N extends string, S extends string = "stack">(name: N, stack?: S) => `app--${S}--${N}`;
2478
+ declare const getTopicName: <N extends string>(name: N) => `app--${N}`;
2477
2479
  declare const getSecretName: (name: string) => string;
2478
2480
  declare const getCacheProps: (name: string, stack?: "stack") => {
2479
2481
  readonly host: string;
2480
2482
  readonly port: number;
2481
2483
  };
2482
2484
 
2485
+ declare const getFunctionName: <S extends string, N extends string>(stack: S, name: N) => `app--${S}--${N}`;
2486
+ declare const Function: {};
2487
+
2488
+ declare const getTableName: <N extends string, S extends string = "stack">(name: N, stack?: S) => `app--${S}--${N}`;
2489
+ declare const Table: {};
2490
+
2483
2491
  type AppConfig = CombinedDefaultPluginsConfigInput;
2484
2492
  type StackConfig = CombinedDefaultPluginsConfigInput['stacks'][number];
2485
2493
  declare const defineStackConfig: (config: StackConfig) => StackConfig$1 | (StackConfig$1 & {
@@ -2698,4 +2706,4 @@ declare const defineStackConfig: (config: StackConfig) => StackConfig$1 | (Stack
2698
2706
  });
2699
2707
  declare const defineAppConfig: (config: AppConfig | AppConfigFactory<AppConfig>) => CombinedDefaultPluginsConfigInput | AppConfigFactory<CombinedDefaultPluginsConfigInput>;
2700
2708
 
2701
- export { AppConfig, Plugin, StackConfig, defineAppConfig, definePlugin, defineStackConfig, getCacheProps, getFunctionName, getGlobalResourceName, getLocalResourceName, getQueueName, getSearchName, getSecretName, getStoreName, getTableName, getTopicName };
2709
+ export { AppConfig, Function, Plugin, StackConfig, Table, defineAppConfig, definePlugin, defineStackConfig, getCacheProps, getFunctionName, getGlobalResourceName, getLocalResourceName, getQueueName, getSearchName, getSecretName, getStoreName, getTableName, getTopicName };
package/dist/index.js CHANGED
@@ -3,19 +3,16 @@ import {
3
3
  } from "./chunk-PFTL6L4F.js";
4
4
 
5
5
  // src/node/resource.ts
6
+ import { paramCase } from "change-case";
6
7
  var APP = process.env.APP || "app";
7
8
  var STACK = process.env.STACK || "stack";
8
9
  var getLocalResourceName = (name, stack = STACK) => {
9
- return `${APP}-${stack}-${name}`;
10
+ return `${APP}--${paramCase(stack)}--${paramCase(name)}`;
10
11
  };
11
12
  var getGlobalResourceName = (name) => {
12
- return `${APP}-${name}`;
13
- };
14
- var getFunctionName = (stack, name) => {
15
- return getLocalResourceName(name, stack);
13
+ return `${APP}--${paramCase(name)}`;
16
14
  };
17
15
  var getSearchName = getLocalResourceName;
18
- var getTableName = getLocalResourceName;
19
16
  var getStoreName = getLocalResourceName;
20
17
  var getQueueName = getLocalResourceName;
21
18
  var getTopicName = getGlobalResourceName;
@@ -30,6 +27,46 @@ var getCacheProps = (name, stack = STACK) => {
30
27
  };
31
28
  };
32
29
 
30
+ // src/node/function.ts
31
+ import { invoke } from "@awsless/lambda";
32
+
33
+ // src/node/util.ts
34
+ var createProxy = (cb) => {
35
+ const cache = /* @__PURE__ */ new Map();
36
+ return new Proxy({}, {
37
+ get(_, name) {
38
+ if (!cache.has(name)) {
39
+ cache.set(name, cb(name));
40
+ }
41
+ return cache.get(name);
42
+ }
43
+ });
44
+ };
45
+
46
+ // src/node/function.ts
47
+ var getFunctionName = (stack, name) => {
48
+ return getLocalResourceName(name, stack);
49
+ };
50
+ var Function = createProxy((stack) => {
51
+ return createProxy((name) => {
52
+ return (event, options = {}) => {
53
+ return invoke({
54
+ ...options,
55
+ name: getFunctionName(stack, name),
56
+ payload: event
57
+ });
58
+ };
59
+ });
60
+ });
61
+
62
+ // src/node/table.ts
63
+ var getTableName = getLocalResourceName;
64
+ var Table = createProxy((stack) => {
65
+ return createProxy((name) => {
66
+ return getTableName(name, stack);
67
+ });
68
+ });
69
+
33
70
  // src/index.ts
34
71
  var defineStackConfig = (config) => {
35
72
  return config;
@@ -38,6 +75,8 @@ var defineAppConfig = (config) => {
38
75
  return config;
39
76
  };
40
77
  export {
78
+ Function,
79
+ Table,
41
80
  defineAppConfig,
42
81
  definePlugin,
43
82
  defineStackConfig,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@awsless/awsless",
3
- "version": "0.0.30",
3
+ "version": "0.0.32",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "repository": {
@@ -24,6 +24,9 @@
24
24
  "types": "./dist/index.d.ts"
25
25
  }
26
26
  },
27
+ "peerDependencies": {
28
+ "@awsless/lambda": "^0.0.5"
29
+ },
27
30
  "dependencies": {
28
31
  "@aws-sdk/client-cloudformation": "^3.369.0",
29
32
  "@aws-sdk/client-s3": "^3.369.0",