@awsless/awsless 0.0.489 → 0.0.490
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 +391 -75
- package/dist/build-json-schema.js +104 -31
- package/dist/layers/sharp-arm.zip +0 -0
- package/dist/prebuild/images/HASH +1 -0
- package/dist/prebuild/images/bundle.zip +0 -0
- package/dist/prebuild/rpc/bundle.zip +0 -0
- package/dist/prebuild.js +5 -4
- package/dist/stack.json +1 -1
- package/package.json +14 -12
package/dist/bin.js
CHANGED
|
@@ -861,7 +861,7 @@ var LogRetentionSchema = DurationSchema.refine(
|
|
|
861
861
|
(duration) => {
|
|
862
862
|
return validLogRetentionDays.includes(toDays(duration));
|
|
863
863
|
},
|
|
864
|
-
`Invalid log retention. Valid days are: ${validLogRetentionDays.map((
|
|
864
|
+
`Invalid log retention. Valid days are: ${validLogRetentionDays.map((days7) => `${days7}`).join(", ")}`
|
|
865
865
|
).describe("The log retention duration.");
|
|
866
866
|
var LogSchema = z14.union([
|
|
867
867
|
z14.boolean().transform((enabled) => ({ retention: enabled ? days(7) : days(0) })),
|
|
@@ -1241,7 +1241,7 @@ var AppSchema = z24.object({
|
|
|
1241
1241
|
});
|
|
1242
1242
|
|
|
1243
1243
|
// src/config/stack.ts
|
|
1244
|
-
import { z as
|
|
1244
|
+
import { z as z39 } from "zod";
|
|
1245
1245
|
|
|
1246
1246
|
// src/feature/cache/schema.ts
|
|
1247
1247
|
import { gibibytes as gibibytes2 } from "@awsless/size";
|
|
@@ -1676,24 +1676,96 @@ var StoresSchema = z33.union([
|
|
|
1676
1676
|
)
|
|
1677
1677
|
]).optional().describe("Define the stores in your stack.");
|
|
1678
1678
|
|
|
1679
|
-
// src/feature/
|
|
1680
|
-
import { minutes as minutes4, seconds as seconds4 } from "@awsless/duration";
|
|
1679
|
+
// src/feature/images/schema.ts
|
|
1681
1680
|
import { z as z34 } from "zod";
|
|
1682
|
-
var
|
|
1683
|
-
|
|
1681
|
+
var transformationOptionsSchema = z34.object({
|
|
1682
|
+
// Resize options
|
|
1683
|
+
width: z34.number().int().positive().optional(),
|
|
1684
|
+
height: z34.number().int().positive().optional(),
|
|
1685
|
+
fit: z34.enum(["cover", "contain", "fill", "inside", "outside"]).optional(),
|
|
1686
|
+
position: z34.enum(["top", "right top", "right", "right bottom", "bottom", "left bottom", "left", "left top", "center"]).optional(),
|
|
1687
|
+
// Format options
|
|
1688
|
+
quality: z34.number().int().min(1).max(100).optional(),
|
|
1689
|
+
progressive: z34.boolean().optional(),
|
|
1690
|
+
// Processing options
|
|
1691
|
+
rotate: z34.number().optional(),
|
|
1692
|
+
flip: z34.boolean().optional(),
|
|
1693
|
+
flop: z34.boolean().optional(),
|
|
1694
|
+
blur: z34.number().min(0.3).max(1e3).optional(),
|
|
1695
|
+
sharpen: z34.boolean().optional(),
|
|
1696
|
+
grayscale: z34.boolean().optional(),
|
|
1697
|
+
normalize: z34.boolean().optional()
|
|
1698
|
+
});
|
|
1699
|
+
var extensionOptionsSchema = z34.object({
|
|
1700
|
+
// WebP specific
|
|
1701
|
+
effort: z34.number().int().min(0).max(6).optional(),
|
|
1702
|
+
lossless: z34.boolean().optional(),
|
|
1703
|
+
nearLossless: z34.boolean().optional(),
|
|
1704
|
+
// smartSubsample: z.boolean().optional(),
|
|
1705
|
+
// JPEG specific
|
|
1706
|
+
mozjpeg: z34.boolean().optional(),
|
|
1707
|
+
// trellisQuantisation: z.boolean().optional(),
|
|
1708
|
+
// overshootDeringing: z.boolean().optional(),
|
|
1709
|
+
// optimiseScans: z.boolean().optional(),
|
|
1710
|
+
// PNG specific
|
|
1711
|
+
compressionLevel: z34.number().int().min(0).max(9).optional(),
|
|
1712
|
+
adaptiveFiltering: z34.boolean().optional(),
|
|
1713
|
+
// palette: z.boolean().optional(),
|
|
1714
|
+
// AVIF specific
|
|
1715
|
+
speed: z34.number().int().min(0).max(9).optional()
|
|
1716
|
+
// chromaSubsampling: z.string().optional(),
|
|
1717
|
+
});
|
|
1718
|
+
var staticOriginSchema = LocalDirectorySchema.describe(
|
|
1719
|
+
"Specifies the path to a image directory that will be uploaded in S3."
|
|
1720
|
+
);
|
|
1721
|
+
var functionOriginSchema = FunctionSchema.describe(
|
|
1722
|
+
"Specifies the file that will be called when an image isn't found in the S3 bucket."
|
|
1723
|
+
);
|
|
1724
|
+
var ImagesSchema = z34.record(
|
|
1684
1725
|
ResourceIdSchema,
|
|
1685
1726
|
z34.object({
|
|
1727
|
+
domain: ResourceIdSchema.describe("The domain id to link your site with.").optional(),
|
|
1728
|
+
subDomain: z34.string().optional(),
|
|
1729
|
+
presets: z34.record(z34.string(), transformationOptionsSchema).describe("Named presets for image transformations"),
|
|
1730
|
+
extensions: z34.record(z34.enum(["jpeg", "jpg", "png", "webp"]), extensionOptionsSchema).describe("Format-specific optimization options"),
|
|
1731
|
+
origin: z34.union([
|
|
1732
|
+
z34.object({
|
|
1733
|
+
static: staticOriginSchema,
|
|
1734
|
+
function: functionOriginSchema.optional()
|
|
1735
|
+
}),
|
|
1736
|
+
z34.object({
|
|
1737
|
+
static: staticOriginSchema.optional(),
|
|
1738
|
+
function: functionOriginSchema
|
|
1739
|
+
}),
|
|
1740
|
+
z34.object({
|
|
1741
|
+
static: staticOriginSchema,
|
|
1742
|
+
function: functionOriginSchema
|
|
1743
|
+
})
|
|
1744
|
+
]).describe(
|
|
1745
|
+
"Image transformation will be applied from a base image. Base images orginates from a local directory that will be uploaded to S3 or from a lambda function."
|
|
1746
|
+
)
|
|
1747
|
+
// postprocess: FunctionSchema.optional()
|
|
1748
|
+
})
|
|
1749
|
+
).optional().describe("Define image CDN & transformations in your stack.");
|
|
1750
|
+
|
|
1751
|
+
// src/feature/table/schema.ts
|
|
1752
|
+
import { minutes as minutes4, seconds as seconds4 } from "@awsless/duration";
|
|
1753
|
+
import { z as z35 } from "zod";
|
|
1754
|
+
var KeySchema = z35.string().min(1).max(255);
|
|
1755
|
+
var TablesSchema = z35.record(
|
|
1756
|
+
ResourceIdSchema,
|
|
1757
|
+
z35.object({
|
|
1686
1758
|
hash: KeySchema.describe(
|
|
1687
1759
|
"Specifies the name of the partition / hash key that makes up the primary key for the table."
|
|
1688
1760
|
),
|
|
1689
1761
|
sort: KeySchema.optional().describe(
|
|
1690
1762
|
"Specifies the name of the range / sort key that makes up the primary key for the table."
|
|
1691
1763
|
),
|
|
1692
|
-
fields:
|
|
1764
|
+
fields: z35.record(z35.string(), z35.enum(["string", "number", "binary"])).optional().describe(
|
|
1693
1765
|
'A list of attributes that describe the key schema for the table and indexes. If no attribute field is defined we default to "string".'
|
|
1694
1766
|
),
|
|
1695
|
-
class:
|
|
1696
|
-
pointInTimeRecovery:
|
|
1767
|
+
class: z35.enum(["standard", "standard-infrequent-access"]).default("standard").describe("The table class of the table."),
|
|
1768
|
+
pointInTimeRecovery: z35.boolean().default(false).describe("Indicates whether point in time recovery is enabled on the table."),
|
|
1697
1769
|
ttl: KeySchema.optional().describe(
|
|
1698
1770
|
[
|
|
1699
1771
|
"The name of the TTL attribute used to store the expiration time for items in the table.",
|
|
@@ -1701,8 +1773,8 @@ var TablesSchema = z34.record(
|
|
|
1701
1773
|
].join("\n")
|
|
1702
1774
|
),
|
|
1703
1775
|
// deletionProtection: DeletionProtectionSchema.optional(),
|
|
1704
|
-
stream:
|
|
1705
|
-
type:
|
|
1776
|
+
stream: z35.object({
|
|
1777
|
+
type: z35.enum(["keys-only", "new-image", "old-image", "new-and-old-images"]).describe(
|
|
1706
1778
|
[
|
|
1707
1779
|
"When an item in the table is modified, you can determines what information is written to the stream for this table.",
|
|
1708
1780
|
"Valid values are:",
|
|
@@ -1712,7 +1784,7 @@ var TablesSchema = z34.record(
|
|
|
1712
1784
|
"- new-and-old-images - Both the new and the old item images of the item are written to the stream."
|
|
1713
1785
|
].join("\n")
|
|
1714
1786
|
),
|
|
1715
|
-
batchSize:
|
|
1787
|
+
batchSize: z35.number().min(1).max(1e4).default(1).describe(
|
|
1716
1788
|
[
|
|
1717
1789
|
"The maximum number of records in each batch that Lambda pulls from your stream and sends to your function.",
|
|
1718
1790
|
"Lambda passes all of the records in the batch to the function in a single call, up to the payload limit for synchronous invocation (6 MB).",
|
|
@@ -1742,7 +1814,7 @@ var TablesSchema = z34.record(
|
|
|
1742
1814
|
// 'You can specify a number from -1 to 10000.',
|
|
1743
1815
|
// ].join('\n')
|
|
1744
1816
|
// ),
|
|
1745
|
-
retryAttempts:
|
|
1817
|
+
retryAttempts: z35.number().min(-1).max(1e4).default(-1).describe(
|
|
1746
1818
|
[
|
|
1747
1819
|
"Discard records after the specified number of retries.",
|
|
1748
1820
|
"The default value is -1, which sets the maximum number of retries to infinite.",
|
|
@@ -1750,7 +1822,7 @@ var TablesSchema = z34.record(
|
|
|
1750
1822
|
"You can specify a number from -1 to 10000."
|
|
1751
1823
|
].join("\n")
|
|
1752
1824
|
),
|
|
1753
|
-
concurrencyPerShard:
|
|
1825
|
+
concurrencyPerShard: z35.number().min(1).max(10).default(1).describe(
|
|
1754
1826
|
[
|
|
1755
1827
|
"The number of batches to process concurrently from each shard.",
|
|
1756
1828
|
"You can specify a number from 1 to 10."
|
|
@@ -1760,16 +1832,16 @@ var TablesSchema = z34.record(
|
|
|
1760
1832
|
}).optional().describe(
|
|
1761
1833
|
"The settings for the DynamoDB table stream, which capture changes to items stored in the table."
|
|
1762
1834
|
),
|
|
1763
|
-
indexes:
|
|
1764
|
-
|
|
1765
|
-
|
|
1835
|
+
indexes: z35.record(
|
|
1836
|
+
z35.string(),
|
|
1837
|
+
z35.object({
|
|
1766
1838
|
hash: KeySchema.describe(
|
|
1767
1839
|
"Specifies the name of the partition / hash key that makes up the primary key for the global secondary index."
|
|
1768
1840
|
),
|
|
1769
1841
|
sort: KeySchema.optional().describe(
|
|
1770
1842
|
"Specifies the name of the range / sort key that makes up the primary key for the global secondary index."
|
|
1771
1843
|
),
|
|
1772
|
-
projection:
|
|
1844
|
+
projection: z35.enum(["all", "keys-only"]).default("all").describe(
|
|
1773
1845
|
[
|
|
1774
1846
|
"The set of attributes that are projected into the index:",
|
|
1775
1847
|
"- all - All of the table attributes are projected into the index.",
|
|
@@ -1783,11 +1855,11 @@ var TablesSchema = z34.record(
|
|
|
1783
1855
|
).optional().describe("Define the tables in your stack.");
|
|
1784
1856
|
|
|
1785
1857
|
// src/feature/task/schema.ts
|
|
1786
|
-
import { z as
|
|
1787
|
-
var RetryAttemptsSchema2 =
|
|
1858
|
+
import { z as z36 } from "zod";
|
|
1859
|
+
var RetryAttemptsSchema2 = z36.number().int().min(0).max(2).describe(
|
|
1788
1860
|
"The maximum number of times to retry when the function returns an error. You can specify a number from 0 to 2."
|
|
1789
1861
|
);
|
|
1790
|
-
var TaskSchema =
|
|
1862
|
+
var TaskSchema = z36.union([
|
|
1791
1863
|
LocalFileSchema.transform((file) => ({
|
|
1792
1864
|
consumer: {
|
|
1793
1865
|
code: {
|
|
@@ -1798,33 +1870,33 @@ var TaskSchema = z35.union([
|
|
|
1798
1870
|
},
|
|
1799
1871
|
retryAttempts: void 0
|
|
1800
1872
|
})),
|
|
1801
|
-
|
|
1873
|
+
z36.object({
|
|
1802
1874
|
consumer: FunctionSchema,
|
|
1803
1875
|
retryAttempts: RetryAttemptsSchema2.optional()
|
|
1804
1876
|
})
|
|
1805
1877
|
]);
|
|
1806
|
-
var TasksSchema =
|
|
1878
|
+
var TasksSchema = z36.record(ResourceIdSchema, TaskSchema).optional().describe("Define the tasks in your stack.");
|
|
1807
1879
|
|
|
1808
1880
|
// src/feature/test/schema.ts
|
|
1809
|
-
import { z as
|
|
1810
|
-
var TestsSchema =
|
|
1881
|
+
import { z as z37 } from "zod";
|
|
1882
|
+
var TestsSchema = z37.union([LocalDirectorySchema.transform((v) => [v]), LocalDirectorySchema.array()]).describe("Define the location of your tests for your stack.").optional();
|
|
1811
1883
|
|
|
1812
1884
|
// src/feature/topic/schema.ts
|
|
1813
1885
|
import { kebabCase as kebabCase3 } from "change-case";
|
|
1814
|
-
import { z as
|
|
1815
|
-
var TopicNameSchema =
|
|
1816
|
-
var TopicsSchema =
|
|
1886
|
+
import { z as z38 } from "zod";
|
|
1887
|
+
var TopicNameSchema = z38.string().min(3).max(256).regex(/^[a-z0-9\-]+$/i, "Invalid topic name").transform((value) => kebabCase3(value)).describe("Define event topic name.");
|
|
1888
|
+
var TopicsSchema = z38.array(TopicNameSchema).refine((topics) => {
|
|
1817
1889
|
return topics.length === new Set(topics).size;
|
|
1818
1890
|
}, "Must be a list of unique topic names").optional().describe("Define the event topics to publish too in your stack.");
|
|
1819
|
-
var SubscribersSchema =
|
|
1891
|
+
var SubscribersSchema = z38.record(TopicNameSchema, FunctionSchema).optional().describe("Define the event topics to subscribe too in your stack.");
|
|
1820
1892
|
|
|
1821
1893
|
// src/config/stack.ts
|
|
1822
1894
|
var DependsSchema = ResourceIdSchema.array().optional().describe("Define the stacks that this stack is depended on.");
|
|
1823
1895
|
var NameSchema = ResourceIdSchema.refine((name) => !["base", "hostedzones"].includes(name), {
|
|
1824
1896
|
message: `Stack name can't be a reserved name.`
|
|
1825
1897
|
}).describe("Stack name.");
|
|
1826
|
-
var StackSchema =
|
|
1827
|
-
$schema:
|
|
1898
|
+
var StackSchema = z39.object({
|
|
1899
|
+
$schema: z39.string().optional(),
|
|
1828
1900
|
name: NameSchema,
|
|
1829
1901
|
depends: DependsSchema,
|
|
1830
1902
|
commands: CommandsSchema,
|
|
@@ -1849,7 +1921,8 @@ var StackSchema = z38.object({
|
|
|
1849
1921
|
pubsub: PubSubSchema,
|
|
1850
1922
|
searchs: SearchsSchema,
|
|
1851
1923
|
sites: SitesSchema,
|
|
1852
|
-
tests: TestsSchema
|
|
1924
|
+
tests: TestsSchema,
|
|
1925
|
+
images: ImagesSchema
|
|
1853
1926
|
});
|
|
1854
1927
|
|
|
1855
1928
|
// src/config/load/read.ts
|
|
@@ -1891,13 +1964,13 @@ var readConfigWithStage = async (file, stage) => {
|
|
|
1891
1964
|
};
|
|
1892
1965
|
|
|
1893
1966
|
// src/config/load/validate.ts
|
|
1894
|
-
import { z as
|
|
1967
|
+
import { z as z40 } from "zod";
|
|
1895
1968
|
var validateConfig = async (schema, file, data) => {
|
|
1896
1969
|
try {
|
|
1897
1970
|
const result = await schema.parseAsync(data);
|
|
1898
1971
|
return result;
|
|
1899
1972
|
} catch (error) {
|
|
1900
|
-
if (error instanceof
|
|
1973
|
+
if (error instanceof z40.ZodError) {
|
|
1901
1974
|
throw new ConfigError(file, error, data);
|
|
1902
1975
|
}
|
|
1903
1976
|
throw error;
|
|
@@ -4076,19 +4149,23 @@ var createPrebuildLambdaFunction = (group, ctx, ns, id, props) => {
|
|
|
4076
4149
|
}
|
|
4077
4150
|
if (props.log?.retention && props.log?.retention?.value > 0n) {
|
|
4078
4151
|
const logGroup = new $12.aws.cloudwatch.LogGroup(group, "log", {
|
|
4079
|
-
name:
|
|
4152
|
+
name: `/aws/lambda/${name}`,
|
|
4080
4153
|
retentionInDays: toDays4(props.log.retention ?? days3(7))
|
|
4081
4154
|
});
|
|
4082
|
-
addPermission(
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4155
|
+
addPermission({
|
|
4156
|
+
actions: ["logs:PutLogEvents", "logs:CreateLogStream"],
|
|
4157
|
+
resources: [logGroup.arn.pipe((arn) => `${arn}:*`)]
|
|
4158
|
+
});
|
|
4159
|
+
const onLogArn = getGlobalOnLog(ctx);
|
|
4160
|
+
if (onLogArn && ctx.appConfig.defaults.onLog) {
|
|
4161
|
+
const logFilter = ctx.appConfig.defaults.onLog.filter;
|
|
4162
|
+
new $12.aws.cloudwatch.LogSubscriptionFilter(group, `on-log`, {
|
|
4163
|
+
name: "log-subscription",
|
|
4164
|
+
destinationArn: onLogArn,
|
|
4165
|
+
logGroupName: logGroup.name,
|
|
4166
|
+
filterPattern: formatFilterPattern(logFilter)
|
|
4167
|
+
});
|
|
4168
|
+
}
|
|
4092
4169
|
}
|
|
4093
4170
|
if (props.warm) {
|
|
4094
4171
|
const rule = new $12.aws.cloudwatch.EventRule(group, "warm", {
|
|
@@ -5696,10 +5773,6 @@ import { $ as $21, Group as Group22 } from "@awsless/formation";
|
|
|
5696
5773
|
var layerFeature = defineFeature({
|
|
5697
5774
|
name: "layer",
|
|
5698
5775
|
onBefore(ctx) {
|
|
5699
|
-
const layers = Object.entries(ctx.appConfig.defaults.layers ?? {});
|
|
5700
|
-
if (layers.length === 0) {
|
|
5701
|
-
return;
|
|
5702
|
-
}
|
|
5703
5776
|
const group = new Group22(ctx.base, "layer", "asset");
|
|
5704
5777
|
const bucket = new $21.aws.s3.Bucket(group, "bucket", {
|
|
5705
5778
|
bucket: formatGlobalResourceName({
|
|
@@ -5731,7 +5804,7 @@ var layerFeature = defineFeature({
|
|
|
5731
5804
|
for (const [id, _props] of layers) {
|
|
5732
5805
|
const props = _props;
|
|
5733
5806
|
const group = new Group22(ctx.base, "layer", id);
|
|
5734
|
-
const
|
|
5807
|
+
const zip = new $21.aws.s3.BucketObject(group, "zip", {
|
|
5735
5808
|
bucket: ctx.shared.get("layer", "bucket-name"),
|
|
5736
5809
|
key: `/layer/${id}.zip`,
|
|
5737
5810
|
contentType: "application/zip",
|
|
@@ -5750,9 +5823,9 @@ var layerFeature = defineFeature({
|
|
|
5750
5823
|
description: id,
|
|
5751
5824
|
compatibleArchitectures: props.architecture ? [props.architecture] : void 0,
|
|
5752
5825
|
compatibleRuntimes: props.runtimes,
|
|
5753
|
-
s3Bucket:
|
|
5754
|
-
s3ObjectVersion:
|
|
5755
|
-
s3Key:
|
|
5826
|
+
s3Bucket: zip.bucket,
|
|
5827
|
+
s3ObjectVersion: zip.versionId,
|
|
5828
|
+
s3Key: zip.key.pipe((name) => {
|
|
5756
5829
|
if (name.startsWith("/")) {
|
|
5757
5830
|
return name.substring(1);
|
|
5758
5831
|
}
|
|
@@ -5761,7 +5834,7 @@ var layerFeature = defineFeature({
|
|
|
5761
5834
|
sourceCodeHash: $hash(props.file)
|
|
5762
5835
|
},
|
|
5763
5836
|
{
|
|
5764
|
-
dependsOn: [
|
|
5837
|
+
dependsOn: [zip]
|
|
5765
5838
|
}
|
|
5766
5839
|
);
|
|
5767
5840
|
ctx.shared.add("layer", "arn", id, layer.arn);
|
|
@@ -5770,6 +5843,248 @@ var layerFeature = defineFeature({
|
|
|
5770
5843
|
}
|
|
5771
5844
|
});
|
|
5772
5845
|
|
|
5846
|
+
// src/feature/images/index.ts
|
|
5847
|
+
import { $ as $22, Group as Group23 } from "@awsless/formation";
|
|
5848
|
+
import { glob as glob3 } from "glob";
|
|
5849
|
+
import { join as join12, extname as extname3, dirname as dirname8 } from "path";
|
|
5850
|
+
import { contentType as contentType2 } from "mime-types";
|
|
5851
|
+
import { Future as Future4 } from "@awsless/formation";
|
|
5852
|
+
import { createHash as createHash5 } from "crypto";
|
|
5853
|
+
import { mebibytes as mebibytes4 } from "@awsless/size";
|
|
5854
|
+
import { days as days6, seconds as seconds9, toSeconds as toSeconds8, weeks } from "@awsless/duration";
|
|
5855
|
+
import { constantCase as constantCase11 } from "change-case";
|
|
5856
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
5857
|
+
var __dirname2 = dirname8(fileURLToPath2(import.meta.url));
|
|
5858
|
+
var imagesFeature = defineFeature({
|
|
5859
|
+
name: "images",
|
|
5860
|
+
onStack(ctx) {
|
|
5861
|
+
for (const [id, props] of Object.entries(ctx.stackConfig.images ?? {})) {
|
|
5862
|
+
const group = new Group23(ctx.stack, "images", id);
|
|
5863
|
+
const name = formatLocalResourceName({
|
|
5864
|
+
appName: ctx.app.name,
|
|
5865
|
+
stackName: ctx.stack.name,
|
|
5866
|
+
resourceType: "images",
|
|
5867
|
+
resourceName: id
|
|
5868
|
+
});
|
|
5869
|
+
const originGroup = new Group23(ctx.stack, "images-origins", id);
|
|
5870
|
+
let lambdaOrigin = void 0;
|
|
5871
|
+
if (props.origin.function) {
|
|
5872
|
+
lambdaOrigin = createLambdaFunction(originGroup, ctx, `images-lambda-origin`, id, props.origin.function);
|
|
5873
|
+
}
|
|
5874
|
+
let s3Origin;
|
|
5875
|
+
if (props.origin.static) {
|
|
5876
|
+
s3Origin = new $22.aws.s3.Bucket(originGroup, "bucket", {
|
|
5877
|
+
bucket: formatLocalResourceName({
|
|
5878
|
+
appName: ctx.app.name,
|
|
5879
|
+
stackName: ctx.stack.name,
|
|
5880
|
+
resourceType: "images",
|
|
5881
|
+
resourceName: id,
|
|
5882
|
+
postfix: ctx.appId
|
|
5883
|
+
}),
|
|
5884
|
+
forceDestroy: true
|
|
5885
|
+
});
|
|
5886
|
+
}
|
|
5887
|
+
const path = join12(__dirname2, "/layers/sharp-arm.zip");
|
|
5888
|
+
const layerId = formatLocalResourceName({
|
|
5889
|
+
appName: ctx.appConfig.name,
|
|
5890
|
+
stackName: ctx.stack.name,
|
|
5891
|
+
resourceType: "layer",
|
|
5892
|
+
resourceName: shortId(id)
|
|
5893
|
+
});
|
|
5894
|
+
const zipFile = new $22.aws.s3.BucketObject(group, "layer-zip", {
|
|
5895
|
+
bucket: ctx.shared.get("layer", "bucket-name"),
|
|
5896
|
+
key: `/layer/${layerId}.zip`,
|
|
5897
|
+
contentType: "application/zip",
|
|
5898
|
+
source: path,
|
|
5899
|
+
sourceHash: $hash(path)
|
|
5900
|
+
});
|
|
5901
|
+
const layer = new $22.aws.lambda.LayerVersion(
|
|
5902
|
+
group,
|
|
5903
|
+
"layer",
|
|
5904
|
+
{
|
|
5905
|
+
layerName: layerId,
|
|
5906
|
+
description: "sharp-arm.zip for the awsless images feature.",
|
|
5907
|
+
compatibleArchitectures: ["arm64"],
|
|
5908
|
+
compatibleRuntimes: ["nodejs22.x"],
|
|
5909
|
+
s3Bucket: zipFile.bucket,
|
|
5910
|
+
s3ObjectVersion: zipFile.versionId,
|
|
5911
|
+
s3Key: zipFile.key.pipe((name2) => {
|
|
5912
|
+
if (name2.startsWith("/")) {
|
|
5913
|
+
return name2.substring(1);
|
|
5914
|
+
}
|
|
5915
|
+
return name2;
|
|
5916
|
+
}),
|
|
5917
|
+
sourceCodeHash: $hash(path)
|
|
5918
|
+
},
|
|
5919
|
+
{
|
|
5920
|
+
dependsOn: [zipFile]
|
|
5921
|
+
}
|
|
5922
|
+
);
|
|
5923
|
+
ctx.shared.add("layer", "arn", layerId, layer.arn);
|
|
5924
|
+
const transformFn = createPrebuildLambdaFunction(group, ctx, "images", id, {
|
|
5925
|
+
bundleFile: join12(__dirname2, "/prebuild/images/bundle.zip"),
|
|
5926
|
+
bundleHash: join12(__dirname2, "/prebuild/images/HASH"),
|
|
5927
|
+
memorySize: mebibytes4(512),
|
|
5928
|
+
timeout: seconds9(10),
|
|
5929
|
+
handler: "index.default",
|
|
5930
|
+
runtime: "nodejs22.x",
|
|
5931
|
+
log: { retention: weeks(2) },
|
|
5932
|
+
layers: [layerId]
|
|
5933
|
+
});
|
|
5934
|
+
new UpdateFunctionCode(group, "update", {
|
|
5935
|
+
version: transformFn.code.sourceHash,
|
|
5936
|
+
functionName: transformFn.lambda.functionName,
|
|
5937
|
+
architectures: transformFn.lambda.architectures,
|
|
5938
|
+
s3Bucket: transformFn.lambda.s3Bucket,
|
|
5939
|
+
s3Key: transformFn.lambda.s3Key,
|
|
5940
|
+
s3ObjectVersion: transformFn.lambda.s3ObjectVersion,
|
|
5941
|
+
imageUri: transformFn.lambda.imageUri
|
|
5942
|
+
});
|
|
5943
|
+
const permission = new $22.aws.lambda.Permission(group, "permission", {
|
|
5944
|
+
principal: "cloudfront.amazonaws.com",
|
|
5945
|
+
action: "lambda:InvokeFunctionUrl",
|
|
5946
|
+
functionName: transformFn.lambda.functionName,
|
|
5947
|
+
functionUrlAuthType: "AWS_IAM",
|
|
5948
|
+
sourceArn: `arn:aws:cloudfront::${ctx.accountId}:distribution/*`
|
|
5949
|
+
});
|
|
5950
|
+
const transformFnUrl = new $22.aws.lambda.FunctionUrl(
|
|
5951
|
+
group,
|
|
5952
|
+
"url",
|
|
5953
|
+
{
|
|
5954
|
+
functionName: transformFn.lambda.functionName,
|
|
5955
|
+
authorizationType: "AWS_IAM"
|
|
5956
|
+
},
|
|
5957
|
+
{ dependsOn: [permission] }
|
|
5958
|
+
);
|
|
5959
|
+
transformFn.setEnvironment(
|
|
5960
|
+
"IMAGES_CONFIG",
|
|
5961
|
+
JSON.stringify({
|
|
5962
|
+
presets: props.presets,
|
|
5963
|
+
extensions: props.extensions
|
|
5964
|
+
})
|
|
5965
|
+
);
|
|
5966
|
+
if (lambdaOrigin) {
|
|
5967
|
+
transformFn.setEnvironment("IMAGES_ORIGIN_LAMBDA", lambdaOrigin.name);
|
|
5968
|
+
}
|
|
5969
|
+
if (s3Origin) {
|
|
5970
|
+
transformFn.setEnvironment("IMAGES_ORIGIN_S3", s3Origin.bucket);
|
|
5971
|
+
transformFn.addPermission({
|
|
5972
|
+
actions: [
|
|
5973
|
+
"s3:ListBucket",
|
|
5974
|
+
"s3:ListBucketV2",
|
|
5975
|
+
"s3:HeadObject",
|
|
5976
|
+
"s3:GetObject",
|
|
5977
|
+
"s3:PutObject",
|
|
5978
|
+
"s3:DeleteObject",
|
|
5979
|
+
// 's3:CopyObject',
|
|
5980
|
+
"s3:GetObjectAttributes"
|
|
5981
|
+
],
|
|
5982
|
+
resources: [
|
|
5983
|
+
//
|
|
5984
|
+
s3Origin.arn,
|
|
5985
|
+
s3Origin.arn.pipe((arn) => `${arn}/*`)
|
|
5986
|
+
]
|
|
5987
|
+
});
|
|
5988
|
+
}
|
|
5989
|
+
const versions = [];
|
|
5990
|
+
ctx.onReady(() => {
|
|
5991
|
+
if (props.origin.static && s3Origin) {
|
|
5992
|
+
const files = glob3.sync("**", {
|
|
5993
|
+
cwd: props.origin.static,
|
|
5994
|
+
nodir: true
|
|
5995
|
+
});
|
|
5996
|
+
for (const file of files) {
|
|
5997
|
+
const object = new $22.aws.s3.BucketObject(group, `static-${file}`, {
|
|
5998
|
+
bucket: s3Origin.bucket,
|
|
5999
|
+
key: file,
|
|
6000
|
+
cacheControl: "public, max-age=31536000, immutable",
|
|
6001
|
+
contentType: contentType2(extname3(file)) || `image/${extname3(file).slice(1)}`,
|
|
6002
|
+
source: join12(props.origin.static, file),
|
|
6003
|
+
sourceHash: $hash(join12(props.origin.static, file))
|
|
6004
|
+
});
|
|
6005
|
+
versions.push(object.key);
|
|
6006
|
+
versions.push(object.sourceHash);
|
|
6007
|
+
}
|
|
6008
|
+
}
|
|
6009
|
+
});
|
|
6010
|
+
const domainName = props.domain ? formatFullDomainName(ctx.appConfig, props.domain, props.subDomain) : void 0;
|
|
6011
|
+
const certificateArn = props.domain ? ctx.shared.entry("domain", `global-certificate-arn`, props.domain) : void 0;
|
|
6012
|
+
const accessControl = new $22.aws.cloudfront.OriginAccessControl(group, "access", {
|
|
6013
|
+
name,
|
|
6014
|
+
description: "Policy for Images Lambda Transformation Function URL",
|
|
6015
|
+
originAccessControlOriginType: "lambda",
|
|
6016
|
+
signingBehavior: "always",
|
|
6017
|
+
signingProtocol: "sigv4"
|
|
6018
|
+
});
|
|
6019
|
+
const cache = new $22.aws.cloudfront.CachePolicy(group, "cache", {
|
|
6020
|
+
name,
|
|
6021
|
+
defaultTtl: toSeconds8(days6(365))
|
|
6022
|
+
});
|
|
6023
|
+
const distribution = new $22.aws.cloudfront.Distribution(group, "distribution", {
|
|
6024
|
+
comment: name,
|
|
6025
|
+
enabled: true,
|
|
6026
|
+
aliases: domainName ? [domainName] : void 0,
|
|
6027
|
+
priceClass: "PriceClass_All",
|
|
6028
|
+
httpVersion: "http2and3",
|
|
6029
|
+
viewerCertificate: certificateArn ? {
|
|
6030
|
+
sslSupportMethod: "sni-only",
|
|
6031
|
+
minimumProtocolVersion: "TLSv1.2_2021",
|
|
6032
|
+
acmCertificateArn: certificateArn
|
|
6033
|
+
} : {
|
|
6034
|
+
cloudfrontDefaultCertificate: true
|
|
6035
|
+
},
|
|
6036
|
+
origin: [
|
|
6037
|
+
{
|
|
6038
|
+
originId: "default",
|
|
6039
|
+
domainName: transformFnUrl.functionUrl.pipe((url) => url.split("/")[2]),
|
|
6040
|
+
originAccessControlId: accessControl.id,
|
|
6041
|
+
customOriginConfig: {
|
|
6042
|
+
originProtocolPolicy: "https-only",
|
|
6043
|
+
httpPort: 80,
|
|
6044
|
+
httpsPort: 443,
|
|
6045
|
+
originSslProtocols: ["TLSv1.2"]
|
|
6046
|
+
}
|
|
6047
|
+
}
|
|
6048
|
+
],
|
|
6049
|
+
defaultCacheBehavior: {
|
|
6050
|
+
compress: true,
|
|
6051
|
+
targetOriginId: "default",
|
|
6052
|
+
cachePolicyId: cache.id,
|
|
6053
|
+
viewerProtocolPolicy: "redirect-to-https",
|
|
6054
|
+
allowedMethods: ["GET", "HEAD"],
|
|
6055
|
+
cachedMethods: ["GET", "HEAD"]
|
|
6056
|
+
}
|
|
6057
|
+
});
|
|
6058
|
+
new Invalidation(group, "invalidate", {
|
|
6059
|
+
distributionId: distribution.id,
|
|
6060
|
+
paths: ["/*"],
|
|
6061
|
+
version: new Future4((resolve) => {
|
|
6062
|
+
$combine(...versions).then((versions2) => {
|
|
6063
|
+
const combined = versions2.filter((v) => !!v).sort().join(",");
|
|
6064
|
+
const version = createHash5("sha1").update(combined).digest("hex");
|
|
6065
|
+
resolve(version);
|
|
6066
|
+
});
|
|
6067
|
+
})
|
|
6068
|
+
});
|
|
6069
|
+
if (domainName) {
|
|
6070
|
+
new $22.aws.route53.Record(group, `record`, {
|
|
6071
|
+
zoneId: ctx.shared.entry("domain", "zone-id", props.domain),
|
|
6072
|
+
type: "A",
|
|
6073
|
+
name: domainName,
|
|
6074
|
+
alias: {
|
|
6075
|
+
name: distribution.domainName,
|
|
6076
|
+
zoneId: distribution.hostedZoneId,
|
|
6077
|
+
evaluateTargetHealth: false
|
|
6078
|
+
}
|
|
6079
|
+
});
|
|
6080
|
+
ctx.bind(`IMAGES_${ctx.stack.name}_${constantCase11(id)}_ENDPOINT`, domainName);
|
|
6081
|
+
} else {
|
|
6082
|
+
ctx.bind(`IMAGES_${ctx.stack.name}_${constantCase11(id)}_ENDPOINT`, distribution.domainName);
|
|
6083
|
+
}
|
|
6084
|
+
}
|
|
6085
|
+
}
|
|
6086
|
+
});
|
|
6087
|
+
|
|
5773
6088
|
// src/feature/index.ts
|
|
5774
6089
|
var features = [
|
|
5775
6090
|
// 1
|
|
@@ -5802,6 +6117,7 @@ var features = [
|
|
|
5802
6117
|
// httpFeature,
|
|
5803
6118
|
restFeature,
|
|
5804
6119
|
siteFeature,
|
|
6120
|
+
imagesFeature,
|
|
5805
6121
|
// 4
|
|
5806
6122
|
rpcFeature
|
|
5807
6123
|
];
|
|
@@ -6663,13 +6979,13 @@ import wildstring4 from "wildstring";
|
|
|
6663
6979
|
import { log as log9 } from "@clack/prompts";
|
|
6664
6980
|
import chalk5 from "chalk";
|
|
6665
6981
|
import { mkdir as mkdir4, readFile as readFile5, writeFile as writeFile3 } from "fs/promises";
|
|
6666
|
-
import { join as
|
|
6982
|
+
import { join as join15 } from "path";
|
|
6667
6983
|
import wildstring3 from "wildstring";
|
|
6668
6984
|
|
|
6669
6985
|
// src/build/__fingerprint.ts
|
|
6670
|
-
import { createHash as
|
|
6986
|
+
import { createHash as createHash6 } from "crypto";
|
|
6671
6987
|
import { readdir as readdir4, readFile as readFile4, stat as stat4 } from "fs/promises";
|
|
6672
|
-
import { basename as basename4, dirname as
|
|
6988
|
+
import { basename as basename4, dirname as dirname9, extname as extname4, join as join13 } from "path";
|
|
6673
6989
|
import parseStaticImports from "parse-static-imports";
|
|
6674
6990
|
var extensions = ["js", "mjs", "jsx", "ts", "mts", "tsx"];
|
|
6675
6991
|
var generateFileHashes = async (file, hashes) => {
|
|
@@ -6678,7 +6994,7 @@ var generateFileHashes = async (file, hashes) => {
|
|
|
6678
6994
|
}
|
|
6679
6995
|
const code = await readModuleFile(file);
|
|
6680
6996
|
const deps = await findDependencies(file, code);
|
|
6681
|
-
const hash =
|
|
6997
|
+
const hash = createHash6("sha1").update(code).digest();
|
|
6682
6998
|
hashes.set(file, hash);
|
|
6683
6999
|
for (const dep of deps) {
|
|
6684
7000
|
if (dep.startsWith("/")) {
|
|
@@ -6690,12 +7006,12 @@ var fingerprintFromDirectory = async (dir) => {
|
|
|
6690
7006
|
const hashes = /* @__PURE__ */ new Map();
|
|
6691
7007
|
const files = await readdir4(dir, { recursive: true });
|
|
6692
7008
|
for (const file of files) {
|
|
6693
|
-
if (extensions.includes(
|
|
6694
|
-
await generateFileHashes(
|
|
7009
|
+
if (extensions.includes(extname4(file).substring(1)) && file.at(0) !== "_") {
|
|
7010
|
+
await generateFileHashes(join13(dir, file), hashes);
|
|
6695
7011
|
}
|
|
6696
7012
|
}
|
|
6697
7013
|
const merge2 = Buffer.concat(Array.from(hashes.values()).sort());
|
|
6698
|
-
return
|
|
7014
|
+
return createHash6("sha1").update(merge2).digest("hex");
|
|
6699
7015
|
};
|
|
6700
7016
|
var readModuleFile = (file) => {
|
|
6701
7017
|
if (file.endsWith(".js")) {
|
|
@@ -6705,7 +7021,7 @@ var readModuleFile = (file) => {
|
|
|
6705
7021
|
return readFiles([
|
|
6706
7022
|
file,
|
|
6707
7023
|
...extensions.map((exp) => `${file}.${exp}`),
|
|
6708
|
-
...extensions.map((exp) =>
|
|
7024
|
+
...extensions.map((exp) => join13(file, `/index.${exp}`))
|
|
6709
7025
|
]);
|
|
6710
7026
|
}
|
|
6711
7027
|
return readFile4(file, "utf8");
|
|
@@ -6725,7 +7041,7 @@ var readFiles = async (files) => {
|
|
|
6725
7041
|
};
|
|
6726
7042
|
var findDependencies = async (file, code) => {
|
|
6727
7043
|
const imports = await parseStaticImports(code);
|
|
6728
|
-
return imports.map((entry) => entry.moduleName).filter(Boolean).map((value) => value?.startsWith(".") ?
|
|
7044
|
+
return imports.map((entry) => entry.moduleName).filter(Boolean).map((value) => value?.startsWith(".") ? join13(dirname9(file), value) : value);
|
|
6729
7045
|
};
|
|
6730
7046
|
|
|
6731
7047
|
// src/test/reporter.ts
|
|
@@ -6805,13 +7121,13 @@ var CustomReporter = class {
|
|
|
6805
7121
|
import commonjs2 from "@rollup/plugin-commonjs";
|
|
6806
7122
|
import json2 from "@rollup/plugin-json";
|
|
6807
7123
|
import nodeResolve2 from "@rollup/plugin-node-resolve";
|
|
6808
|
-
import { dirname as
|
|
7124
|
+
import { dirname as dirname10, join as join14 } from "path";
|
|
6809
7125
|
import { swc as swc2 } from "rollup-plugin-swc3";
|
|
6810
|
-
import { fileURLToPath as
|
|
7126
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
6811
7127
|
import { configDefaults } from "vitest/config";
|
|
6812
7128
|
import { startVitest } from "vitest/node";
|
|
6813
7129
|
var startTest = async (props) => {
|
|
6814
|
-
const
|
|
7130
|
+
const __dirname3 = dirname10(fileURLToPath3(import.meta.url));
|
|
6815
7131
|
const result = await startVitest(
|
|
6816
7132
|
"test",
|
|
6817
7133
|
props.filters,
|
|
@@ -6827,7 +7143,7 @@ var startTest = async (props) => {
|
|
|
6827
7143
|
reporters: props.reporter,
|
|
6828
7144
|
setupFiles: [
|
|
6829
7145
|
//
|
|
6830
|
-
|
|
7146
|
+
join14(__dirname3, "test-global-setup.js")
|
|
6831
7147
|
]
|
|
6832
7148
|
// globalSetup: [
|
|
6833
7149
|
// //
|
|
@@ -6926,7 +7242,7 @@ var logTestErrors = (event) => {
|
|
|
6926
7242
|
var runTest = async (stack, dir, filters) => {
|
|
6927
7243
|
await mkdir4(directories.test, { recursive: true });
|
|
6928
7244
|
const fingerprint = await fingerprintFromDirectory(dir);
|
|
6929
|
-
const file =
|
|
7245
|
+
const file = join15(directories.test, `${stack}.json`);
|
|
6930
7246
|
const exists = await fileExist(file);
|
|
6931
7247
|
if (exists && !process.env.NO_CACHE) {
|
|
6932
7248
|
const raw = await readFile5(file, { encoding: "utf8" });
|
|
@@ -7165,7 +7481,7 @@ var auth = (program2) => {
|
|
|
7165
7481
|
|
|
7166
7482
|
// src/cli/command/bind.ts
|
|
7167
7483
|
import { log as log10, note as note3 } from "@clack/prompts";
|
|
7168
|
-
import { constantCase as
|
|
7484
|
+
import { constantCase as constantCase12 } from "change-case";
|
|
7169
7485
|
import { spawn } from "child_process";
|
|
7170
7486
|
var bind = (program2) => {
|
|
7171
7487
|
program2.command("bind").argument("[command...]", "The command to execute").option("--config <string...>", "List of config values that will be accessable", (v) => v.split(",")).description(`Bind your site environment variables to a command`).action(async (commands7 = [], opts) => {
|
|
@@ -7194,10 +7510,10 @@ var bind = (program2) => {
|
|
|
7194
7510
|
const configList = opts.config ?? [];
|
|
7195
7511
|
const configs = {};
|
|
7196
7512
|
for (const name of configList) {
|
|
7197
|
-
configs[`CONFIG_${
|
|
7513
|
+
configs[`CONFIG_${constantCase12(name)}`] = name;
|
|
7198
7514
|
}
|
|
7199
7515
|
if (configList.length ?? 0 > 0) {
|
|
7200
|
-
note3(wrap(configList.map((v) => color.label(
|
|
7516
|
+
note3(wrap(configList.map((v) => color.label(constantCase12(v)))), "Bind Config");
|
|
7201
7517
|
}
|
|
7202
7518
|
if (commands7.length === 0) {
|
|
7203
7519
|
return "No command to execute.";
|
|
@@ -7260,7 +7576,7 @@ import { log as log11 } from "@clack/prompts";
|
|
|
7260
7576
|
|
|
7261
7577
|
// src/type-gen/generate.ts
|
|
7262
7578
|
import { mkdir as mkdir5, writeFile as writeFile4 } from "fs/promises";
|
|
7263
|
-
import { dirname as
|
|
7579
|
+
import { dirname as dirname11, join as join16, relative as relative7 } from "path";
|
|
7264
7580
|
var generateTypes = async (props) => {
|
|
7265
7581
|
const files = [];
|
|
7266
7582
|
await Promise.all(
|
|
@@ -7269,12 +7585,12 @@ var generateTypes = async (props) => {
|
|
|
7269
7585
|
...props,
|
|
7270
7586
|
async write(file, data, include = false) {
|
|
7271
7587
|
const code = data?.toString("utf8");
|
|
7272
|
-
const path =
|
|
7588
|
+
const path = join16(directories.types, file);
|
|
7273
7589
|
if (code) {
|
|
7274
7590
|
if (include) {
|
|
7275
7591
|
files.push(relative7(directories.root, path));
|
|
7276
7592
|
}
|
|
7277
|
-
await mkdir5(
|
|
7593
|
+
await mkdir5(dirname11(path), { recursive: true });
|
|
7278
7594
|
await writeFile4(path, code);
|
|
7279
7595
|
}
|
|
7280
7596
|
}
|
|
@@ -7283,7 +7599,7 @@ var generateTypes = async (props) => {
|
|
|
7283
7599
|
);
|
|
7284
7600
|
if (files.length) {
|
|
7285
7601
|
const code = files.map((file) => `/// <reference path='${file}' />`).join("\n");
|
|
7286
|
-
await writeFile4(
|
|
7602
|
+
await writeFile4(join16(directories.root, `awsless.d.ts`), code);
|
|
7287
7603
|
}
|
|
7288
7604
|
};
|
|
7289
7605
|
|