@awsless/awsless 0.0.665 → 0.0.667
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/app.json +1 -1
- package/dist/app.stage.json +1 -1
- package/dist/bin.js +987 -417
- package/dist/build-json-schema.js +302 -177
- package/dist/prebuild/icon/bundle.zip +0 -0
- package/dist/prebuild/image/bundle.zip +0 -0
- package/dist/prebuild/on-error-log/bundle.zip +0 -0
- package/dist/prebuild/on-failure/bundle.zip +0 -0
- package/dist/prebuild/rpc/bundle.zip +0 -0
- package/dist/server.d.ts +12 -1
- package/dist/server.js +88 -9
- package/dist/stack.json +1 -1
- package/dist/stack.stage.json +1 -1
- package/package.json +17 -16
package/dist/bin.js
CHANGED
|
@@ -943,7 +943,7 @@ var debug = (...parts) => {
|
|
|
943
943
|
};
|
|
944
944
|
|
|
945
945
|
// src/config/app.ts
|
|
946
|
-
import { z as
|
|
946
|
+
import { z as z30 } from "zod";
|
|
947
947
|
|
|
948
948
|
// src/feature/alert/schema.ts
|
|
949
949
|
import { kebabCase } from "change-case";
|
|
@@ -1175,7 +1175,7 @@ var LogRetentionSchema = DurationSchema.refine(
|
|
|
1175
1175
|
(duration) => {
|
|
1176
1176
|
return validLogRetentionDays.includes(toDays(duration));
|
|
1177
1177
|
},
|
|
1178
|
-
`Invalid log retention. Valid days are: ${validLogRetentionDays.map((
|
|
1178
|
+
`Invalid log retention. Valid days are: ${validLogRetentionDays.map((days10) => `${days10}`).join(", ")}`
|
|
1179
1179
|
).describe("The log retention duration.");
|
|
1180
1180
|
var LogSchema = z15.union([
|
|
1181
1181
|
z15.boolean().transform((enabled) => ({ retention: enabled ? days(7) : days(0) })),
|
|
@@ -1715,13 +1715,11 @@ var RpcSchema = z25.record(
|
|
|
1715
1715
|
).describe("The queries for your global RPC API.")
|
|
1716
1716
|
).describe("Define the schema in your stack for your global RPC API.").optional();
|
|
1717
1717
|
|
|
1718
|
-
// src/feature/
|
|
1719
|
-
import { days as days4, toDays as toDays2 } from "@awsless/duration";
|
|
1718
|
+
// src/feature/job/schema.ts
|
|
1719
|
+
import { days as days4, hours as hours2, minutes as minutes5, toDays as toDays2 } from "@awsless/duration";
|
|
1720
1720
|
import { toMebibytes } from "@awsless/size";
|
|
1721
1721
|
import { z as z26 } from "zod";
|
|
1722
|
-
var CpuSchema = z26.union([z26.literal(0.25), z26.literal(0.5), z26.literal(1), z26.literal(2), z26.literal(4), z26.literal(8), z26.literal(16)]).transform((v) => `${v} vCPU`).describe(
|
|
1723
|
-
"The number of virtual CPU units (vCPU) used by the instance. Valid values: 0.25, 0.5, 1, 2, 4, 8, 16 vCPU."
|
|
1724
|
-
);
|
|
1722
|
+
var CpuSchema = z26.union([z26.literal(0.25), z26.literal(0.5), z26.literal(1), z26.literal(2), z26.literal(4), z26.literal(8), z26.literal(16)]).transform((v) => `${v} vCPU`).describe("The number of virtual CPU units (vCPU) used by the job. Valid values: 0.25, 0.5, 1, 2, 4, 8, 16 vCPU.");
|
|
1725
1723
|
var validMemorySize = [
|
|
1726
1724
|
// 0.25 vCPU
|
|
1727
1725
|
512,
|
|
@@ -1758,22 +1756,9 @@ var validMemorySize = [
|
|
|
1758
1756
|
var MemorySizeSchema2 = SizeSchema.refine(
|
|
1759
1757
|
(s) => validMemorySize.includes(toMebibytes(s)),
|
|
1760
1758
|
`Invalid memory size. Allowed sizes: ${validMemorySize.join(", ")} MiB`
|
|
1761
|
-
).describe("The amount of memory (in MiB) used by the
|
|
1762
|
-
var HealthCheckSchema = z26.object({
|
|
1763
|
-
path: z26.string().describe("The path that the container runs to determine if it is healthy."),
|
|
1764
|
-
interval: DurationSchema.describe("The time period in seconds between each health check execution."),
|
|
1765
|
-
retries: z26.number().int().min(1).max(10).describe(
|
|
1766
|
-
"The number of times to retry a failed health check before the container is considered unhealthy."
|
|
1767
|
-
),
|
|
1768
|
-
startPeriod: DurationSchema.describe(
|
|
1769
|
-
"The optional grace period to provide containers time to bootstrap before failed health checks count towards the maximum number of retries."
|
|
1770
|
-
),
|
|
1771
|
-
timeout: DurationSchema.describe(
|
|
1772
|
-
"The time period in seconds to wait for a health check to succeed before it is considered a failure."
|
|
1773
|
-
)
|
|
1774
|
-
}).describe("The health check command and associated configuration parameters for the container.");
|
|
1759
|
+
).describe("The amount of memory (in MiB) used by the job. Valid memory values depend on the CPU configuration.");
|
|
1775
1760
|
var EnvironmentSchema2 = z26.record(z26.string(), z26.string()).optional().describe("Environment variable key-value pairs.");
|
|
1776
|
-
var ArchitectureSchema3 = z26.enum(["x86_64", "arm64"]).describe("The instruction set architecture that the
|
|
1761
|
+
var ArchitectureSchema3 = z26.enum(["x86_64", "arm64"]).describe("The instruction set architecture that the job supports.");
|
|
1777
1762
|
var ActionSchema2 = z26.string();
|
|
1778
1763
|
var ActionsSchema2 = z26.union([ActionSchema2.transform((v) => [v]), ActionSchema2.array()]);
|
|
1779
1764
|
var ArnSchema2 = z26.string().startsWith("arn:");
|
|
@@ -1785,9 +1770,7 @@ var PermissionSchema2 = z26.object({
|
|
|
1785
1770
|
actions: ActionsSchema2,
|
|
1786
1771
|
resources: ResourcesSchema2
|
|
1787
1772
|
});
|
|
1788
|
-
var PermissionsSchema2 = z26.union([PermissionSchema2.transform((v) => [v]), PermissionSchema2.array()]).describe("Add IAM permissions to your
|
|
1789
|
-
var DescriptionSchema2 = z26.string().describe("A description of the instance.");
|
|
1790
|
-
var ImageSchema = z26.string().optional().describe("The URL of the container image to use.");
|
|
1773
|
+
var PermissionsSchema2 = z26.union([PermissionSchema2.transform((v) => [v]), PermissionSchema2.array()]).describe("Add IAM permissions to your job.");
|
|
1791
1774
|
var validLogRetentionDays2 = [
|
|
1792
1775
|
...[1, 3, 5, 7, 14, 30, 60, 90, 120, 150],
|
|
1793
1776
|
...[180, 365, 400, 545, 731, 1096, 1827, 2192],
|
|
@@ -1800,7 +1783,7 @@ var LogRetentionSchema2 = DurationSchema.refine(
|
|
|
1800
1783
|
(duration) => {
|
|
1801
1784
|
return validLogRetentionDays2.includes(toDays2(duration));
|
|
1802
1785
|
},
|
|
1803
|
-
`Invalid log retention. Valid days are: ${validLogRetentionDays2.map((
|
|
1786
|
+
`Invalid log retention. Valid days are: ${validLogRetentionDays2.map((days10) => `${days10}`).join(", ")}`
|
|
1804
1787
|
).describe("The log retention duration.");
|
|
1805
1788
|
var LogSchema2 = z26.union([
|
|
1806
1789
|
z26.boolean().transform((enabled) => ({ retention: enabled ? days4(7) : days4(0) })),
|
|
@@ -1810,59 +1793,199 @@ var LogSchema2 = z26.union([
|
|
|
1810
1793
|
})
|
|
1811
1794
|
]).describe("Enable logging to a CloudWatch log group. Providing a duration value will set the log retention time.");
|
|
1812
1795
|
var FileCodeSchema2 = z26.object({
|
|
1813
|
-
file: LocalFileSchema.describe("The file path of the
|
|
1796
|
+
file: LocalFileSchema.describe("The file path of the job code.")
|
|
1814
1797
|
});
|
|
1815
1798
|
var CodeSchema2 = z26.union([
|
|
1816
1799
|
LocalFileSchema.transform((file) => ({
|
|
1817
1800
|
file
|
|
1818
1801
|
})).pipe(FileCodeSchema2),
|
|
1819
1802
|
FileCodeSchema2
|
|
1820
|
-
]).describe("Specify the code of your
|
|
1821
|
-
var
|
|
1803
|
+
]).describe("Specify the code of your job.");
|
|
1804
|
+
var TimeoutSchema3 = DurationSchema.refine(durationMin(minutes5(1)), "Minimum timeout is 1 minute.").refine(durationMax(hours2(4)), "Maximum timeout is 4 hours.").describe("The maximum time the job is allowed to run before being stopped.");
|
|
1805
|
+
var ImageSchema = z26.string().describe("The URL of the container image to use.");
|
|
1806
|
+
var StartupCommandSchema = z26.union([z26.string().transform((v) => [v]), z26.string().array()]).describe("Optional shell commands to run before the job program starts.");
|
|
1807
|
+
var ASchema = z26.object({
|
|
1822
1808
|
code: CodeSchema2,
|
|
1823
|
-
description: DescriptionSchema2.optional(),
|
|
1824
1809
|
image: ImageSchema.optional(),
|
|
1810
|
+
startupCommand: StartupCommandSchema.optional(),
|
|
1825
1811
|
log: LogSchema2.optional(),
|
|
1826
1812
|
cpu: CpuSchema.optional(),
|
|
1827
1813
|
memorySize: MemorySizeSchema2.optional(),
|
|
1828
1814
|
architecture: ArchitectureSchema3.optional(),
|
|
1829
1815
|
environment: EnvironmentSchema2.optional(),
|
|
1830
1816
|
permissions: PermissionsSchema2.optional(),
|
|
1831
|
-
|
|
1832
|
-
// restartPolicy: RestartPolicySchema.optional(),
|
|
1817
|
+
timeout: TimeoutSchema3.default("30 minutes").describe("The maximum time the job is allowed to run before being stopped. Default: 30 minutes.")
|
|
1833
1818
|
});
|
|
1834
|
-
var
|
|
1819
|
+
var JobSchema = z26.union([
|
|
1835
1820
|
LocalFileSchema.transform((code) => ({
|
|
1836
1821
|
code
|
|
1837
|
-
})).pipe(
|
|
1838
|
-
|
|
1822
|
+
})).pipe(ASchema),
|
|
1823
|
+
ASchema
|
|
1839
1824
|
]);
|
|
1840
|
-
var
|
|
1841
|
-
var
|
|
1825
|
+
var JobsSchema = z26.record(ResourceIdSchema, JobSchema).optional().describe("Define the jobs in your stack.");
|
|
1826
|
+
var JobDefaultSchema = z26.object({
|
|
1842
1827
|
image: ImageSchema.optional(),
|
|
1843
1828
|
cpu: CpuSchema.default(0.25),
|
|
1844
1829
|
memorySize: MemorySizeSchema2.default("512 MB"),
|
|
1845
1830
|
architecture: ArchitectureSchema3.default("arm64"),
|
|
1846
1831
|
environment: EnvironmentSchema2.optional(),
|
|
1847
1832
|
permissions: PermissionsSchema2.optional(),
|
|
1848
|
-
|
|
1849
|
-
// restartPolicy: RestartPolicySchema.default({ enabled: true }),
|
|
1833
|
+
timeout: TimeoutSchema3.optional(),
|
|
1850
1834
|
log: LogSchema2.default(true).transform((log35) => ({
|
|
1851
1835
|
retention: log35.retention ?? days4(7)
|
|
1852
1836
|
}))
|
|
1853
1837
|
}).default({});
|
|
1854
1838
|
|
|
1839
|
+
// src/feature/instance/schema.ts
|
|
1840
|
+
import { days as days5, toDays as toDays3 } from "@awsless/duration";
|
|
1841
|
+
import { toMebibytes as toMebibytes2 } from "@awsless/size";
|
|
1842
|
+
import { z as z27 } from "zod";
|
|
1843
|
+
var CpuSchema2 = z27.union([z27.literal(0.25), z27.literal(0.5), z27.literal(1), z27.literal(2), z27.literal(4), z27.literal(8), z27.literal(16)]).transform((v) => `${v} vCPU`).describe(
|
|
1844
|
+
"The number of virtual CPU units (vCPU) used by the instance. Valid values: 0.25, 0.5, 1, 2, 4, 8, 16 vCPU."
|
|
1845
|
+
);
|
|
1846
|
+
var validMemorySize2 = [
|
|
1847
|
+
// 0.25 vCPU
|
|
1848
|
+
512,
|
|
1849
|
+
1024,
|
|
1850
|
+
2048,
|
|
1851
|
+
// 0.5 vCPU
|
|
1852
|
+
1024,
|
|
1853
|
+
2048,
|
|
1854
|
+
3072,
|
|
1855
|
+
4096,
|
|
1856
|
+
// 1 vCPU
|
|
1857
|
+
2048,
|
|
1858
|
+
3072,
|
|
1859
|
+
4096,
|
|
1860
|
+
5120,
|
|
1861
|
+
6144,
|
|
1862
|
+
7168,
|
|
1863
|
+
8192,
|
|
1864
|
+
// 2 vCPU
|
|
1865
|
+
4096,
|
|
1866
|
+
5120,
|
|
1867
|
+
6144,
|
|
1868
|
+
7168,
|
|
1869
|
+
8192,
|
|
1870
|
+
9216,
|
|
1871
|
+
10240,
|
|
1872
|
+
11264,
|
|
1873
|
+
12288,
|
|
1874
|
+
13312,
|
|
1875
|
+
14336,
|
|
1876
|
+
15360,
|
|
1877
|
+
16384
|
|
1878
|
+
];
|
|
1879
|
+
var MemorySizeSchema3 = SizeSchema.refine(
|
|
1880
|
+
(s) => validMemorySize2.includes(toMebibytes2(s)),
|
|
1881
|
+
`Invalid memory size. Allowed sizes: ${validMemorySize2.join(", ")} MiB`
|
|
1882
|
+
).describe("The amount of memory (in MiB) used by the instance. Valid memory values depend on the CPU configuration.");
|
|
1883
|
+
var HealthCheckSchema = z27.object({
|
|
1884
|
+
path: z27.string().describe("The path that the container runs to determine if it is healthy."),
|
|
1885
|
+
interval: DurationSchema.describe("The time period in seconds between each health check execution."),
|
|
1886
|
+
retries: z27.number().int().min(1).max(10).describe(
|
|
1887
|
+
"The number of times to retry a failed health check before the container is considered unhealthy."
|
|
1888
|
+
),
|
|
1889
|
+
startPeriod: DurationSchema.describe(
|
|
1890
|
+
"The optional grace period to provide containers time to bootstrap before failed health checks count towards the maximum number of retries."
|
|
1891
|
+
),
|
|
1892
|
+
timeout: DurationSchema.describe(
|
|
1893
|
+
"The time period in seconds to wait for a health check to succeed before it is considered a failure."
|
|
1894
|
+
)
|
|
1895
|
+
}).describe("The health check command and associated configuration parameters for the container.");
|
|
1896
|
+
var EnvironmentSchema3 = z27.record(z27.string(), z27.string()).optional().describe("Environment variable key-value pairs.");
|
|
1897
|
+
var ArchitectureSchema4 = z27.enum(["x86_64", "arm64"]).describe("The instruction set architecture that the instance supports.");
|
|
1898
|
+
var ActionSchema3 = z27.string();
|
|
1899
|
+
var ActionsSchema3 = z27.union([ActionSchema3.transform((v) => [v]), ActionSchema3.array()]);
|
|
1900
|
+
var ArnSchema3 = z27.string().startsWith("arn:");
|
|
1901
|
+
var WildcardSchema3 = z27.literal("*");
|
|
1902
|
+
var ResourceSchema3 = z27.union([ArnSchema3, WildcardSchema3]);
|
|
1903
|
+
var ResourcesSchema3 = z27.union([ResourceSchema3.transform((v) => [v]), ResourceSchema3.array()]);
|
|
1904
|
+
var PermissionSchema3 = z27.object({
|
|
1905
|
+
effect: z27.enum(["allow", "deny"]).default("allow"),
|
|
1906
|
+
actions: ActionsSchema3,
|
|
1907
|
+
resources: ResourcesSchema3
|
|
1908
|
+
});
|
|
1909
|
+
var PermissionsSchema3 = z27.union([PermissionSchema3.transform((v) => [v]), PermissionSchema3.array()]).describe("Add IAM permissions to your instance.");
|
|
1910
|
+
var DescriptionSchema2 = z27.string().describe("A description of the instance.");
|
|
1911
|
+
var ImageSchema2 = z27.string().optional().describe("The URL of the container image to use.");
|
|
1912
|
+
var validLogRetentionDays3 = [
|
|
1913
|
+
...[1, 3, 5, 7, 14, 30, 60, 90, 120, 150],
|
|
1914
|
+
...[180, 365, 400, 545, 731, 1096, 1827, 2192],
|
|
1915
|
+
...[2557, 2922, 3288, 3653]
|
|
1916
|
+
];
|
|
1917
|
+
var LogRetentionSchema3 = DurationSchema.refine(
|
|
1918
|
+
durationMin(days5(0)),
|
|
1919
|
+
"Minimum log retention is 0 day, which will disable logging."
|
|
1920
|
+
).refine(
|
|
1921
|
+
(duration) => {
|
|
1922
|
+
return validLogRetentionDays3.includes(toDays3(duration));
|
|
1923
|
+
},
|
|
1924
|
+
`Invalid log retention. Valid days are: ${validLogRetentionDays3.map((days10) => `${days10}`).join(", ")}`
|
|
1925
|
+
).describe("The log retention duration.");
|
|
1926
|
+
var LogSchema3 = z27.union([
|
|
1927
|
+
z27.boolean().transform((enabled) => ({ retention: enabled ? days5(7) : days5(0) })),
|
|
1928
|
+
LogRetentionSchema3.transform((retention) => ({ retention })),
|
|
1929
|
+
z27.object({
|
|
1930
|
+
retention: LogRetentionSchema3.optional()
|
|
1931
|
+
})
|
|
1932
|
+
]).describe("Enable logging to a CloudWatch log group. Providing a duration value will set the log retention time.");
|
|
1933
|
+
var FileCodeSchema3 = z27.object({
|
|
1934
|
+
file: LocalFileSchema.describe("The file path of the instance code.")
|
|
1935
|
+
});
|
|
1936
|
+
var CodeSchema3 = z27.union([
|
|
1937
|
+
LocalFileSchema.transform((file) => ({
|
|
1938
|
+
file
|
|
1939
|
+
})).pipe(FileCodeSchema3),
|
|
1940
|
+
FileCodeSchema3
|
|
1941
|
+
]).describe("Specify the code of your instance.");
|
|
1942
|
+
var StartupCommandSchema2 = z27.union([z27.string().transform((v) => [v]), z27.string().array()]).describe("Optional shell commands to run before the instance program starts.");
|
|
1943
|
+
var ISchema = z27.object({
|
|
1944
|
+
code: CodeSchema3,
|
|
1945
|
+
description: DescriptionSchema2.optional(),
|
|
1946
|
+
image: ImageSchema2.optional(),
|
|
1947
|
+
startupCommand: StartupCommandSchema2.optional(),
|
|
1948
|
+
log: LogSchema3.optional(),
|
|
1949
|
+
cpu: CpuSchema2.optional(),
|
|
1950
|
+
memorySize: MemorySizeSchema3.optional(),
|
|
1951
|
+
architecture: ArchitectureSchema4.optional(),
|
|
1952
|
+
environment: EnvironmentSchema3.optional(),
|
|
1953
|
+
permissions: PermissionsSchema3.optional(),
|
|
1954
|
+
healthCheck: HealthCheckSchema.optional()
|
|
1955
|
+
// restartPolicy: RestartPolicySchema.optional(),
|
|
1956
|
+
});
|
|
1957
|
+
var InstanceSchema = z27.union([
|
|
1958
|
+
LocalFileSchema.transform((code) => ({
|
|
1959
|
+
code
|
|
1960
|
+
})).pipe(ISchema),
|
|
1961
|
+
ISchema
|
|
1962
|
+
]);
|
|
1963
|
+
var InstancesSchema = z27.record(ResourceIdSchema, InstanceSchema).optional().describe("Define the instances in your stack.");
|
|
1964
|
+
var InstanceDefaultSchema = z27.object({
|
|
1965
|
+
image: ImageSchema2.optional(),
|
|
1966
|
+
cpu: CpuSchema2.default(0.25),
|
|
1967
|
+
memorySize: MemorySizeSchema3.default("512 MB"),
|
|
1968
|
+
architecture: ArchitectureSchema4.default("arm64"),
|
|
1969
|
+
environment: EnvironmentSchema3.optional(),
|
|
1970
|
+
permissions: PermissionsSchema3.optional(),
|
|
1971
|
+
healthCheck: HealthCheckSchema.optional(),
|
|
1972
|
+
// restartPolicy: RestartPolicySchema.default({ enabled: true }),
|
|
1973
|
+
log: LogSchema3.default(true).transform((log35) => ({
|
|
1974
|
+
retention: log35.retention ?? days5(7)
|
|
1975
|
+
}))
|
|
1976
|
+
}).default({});
|
|
1977
|
+
|
|
1855
1978
|
// src/feature/topic/schema.ts
|
|
1856
1979
|
import { kebabCase as kebabCase3 } from "change-case";
|
|
1857
|
-
import { z as
|
|
1858
|
-
var TopicNameSchema =
|
|
1859
|
-
var TopicsDefaultSchema =
|
|
1980
|
+
import { z as z28 } from "zod";
|
|
1981
|
+
var TopicNameSchema = z28.string().min(3).max(256).regex(/^[a-z0-9\-]+$/i, "Invalid topic name").transform((value) => kebabCase3(value)).describe("Define event topic name.");
|
|
1982
|
+
var TopicsDefaultSchema = z28.array(TopicNameSchema).refine((topics) => {
|
|
1860
1983
|
return topics.length === new Set(topics).size;
|
|
1861
1984
|
}, "Must be a list of unique topic names").optional().describe("Define the event topics for your app.");
|
|
1862
|
-
var SubscribersSchema =
|
|
1985
|
+
var SubscribersSchema = z28.record(TopicNameSchema, TaskSchema).optional().describe("Define the event topics to subscribe too in your stack.");
|
|
1863
1986
|
|
|
1864
1987
|
// src/config/schema/region.ts
|
|
1865
|
-
import { z as
|
|
1988
|
+
import { z as z29 } from "zod";
|
|
1866
1989
|
var US = ["us-east-2", "us-east-1", "us-west-1", "us-west-2"];
|
|
1867
1990
|
var AF = ["af-south-1"];
|
|
1868
1991
|
var AP = [
|
|
@@ -1891,16 +2014,16 @@ var EU = [
|
|
|
1891
2014
|
var ME = ["me-south-1", "me-central-1"];
|
|
1892
2015
|
var SA = ["sa-east-1"];
|
|
1893
2016
|
var regions = [...US, ...AF, ...AP, ...CA, ...EU, ...ME, ...SA];
|
|
1894
|
-
var RegionSchema =
|
|
2017
|
+
var RegionSchema = z29.enum(regions);
|
|
1895
2018
|
|
|
1896
2019
|
// src/config/app.ts
|
|
1897
|
-
var AppSchema =
|
|
1898
|
-
$schema:
|
|
2020
|
+
var AppSchema = z30.object({
|
|
2021
|
+
$schema: z30.string().optional(),
|
|
1899
2022
|
name: ResourceIdSchema.describe("App name."),
|
|
1900
2023
|
region: RegionSchema.describe("The AWS region to deploy to."),
|
|
1901
|
-
profile:
|
|
1902
|
-
protect:
|
|
1903
|
-
removal:
|
|
2024
|
+
profile: z30.string().describe("The AWS profile to deploy to."),
|
|
2025
|
+
protect: z30.boolean().default(false).describe("Protect your app & stacks from being deleted."),
|
|
2026
|
+
removal: z30.enum(["remove", "retain"]).default("remove").describe(
|
|
1904
2027
|
[
|
|
1905
2028
|
"Configure how your resources are handled when they have to be removed.",
|
|
1906
2029
|
"",
|
|
@@ -1914,13 +2037,14 @@ var AppSchema = z29.object({
|
|
|
1914
2037
|
// .default('prod')
|
|
1915
2038
|
// .describe('The deployment stage.'),
|
|
1916
2039
|
// onFailure: OnFailureSchema,
|
|
1917
|
-
defaults:
|
|
2040
|
+
defaults: z30.object({
|
|
1918
2041
|
onFailure: OnFailureDefaultSchema,
|
|
1919
2042
|
onErrorLog: OnErrorLogDefaultSchema,
|
|
1920
2043
|
auth: AuthDefaultSchema,
|
|
1921
2044
|
domains: DomainsDefaultSchema,
|
|
1922
2045
|
function: FunctionDefaultSchema,
|
|
1923
2046
|
instance: InstanceDefaultSchema,
|
|
2047
|
+
job: JobDefaultSchema,
|
|
1924
2048
|
queue: QueueDefaultSchema,
|
|
1925
2049
|
// graphql: GraphQLDefaultSchema,
|
|
1926
2050
|
// http: HttpDefaultSchema,
|
|
@@ -1938,11 +2062,11 @@ var AppSchema = z29.object({
|
|
|
1938
2062
|
});
|
|
1939
2063
|
|
|
1940
2064
|
// src/config/stack.ts
|
|
1941
|
-
import { z as
|
|
2065
|
+
import { z as z45 } from "zod";
|
|
1942
2066
|
|
|
1943
2067
|
// src/feature/cache/schema.ts
|
|
1944
2068
|
import { gibibytes as gibibytes2 } from "@awsless/size";
|
|
1945
|
-
import { z as
|
|
2069
|
+
import { z as z31 } from "zod";
|
|
1946
2070
|
var StorageSchema = SizeSchema.refine(sizeMin(gibibytes2(1)), "Minimum storage size is 1 GB").refine(
|
|
1947
2071
|
sizeMax(gibibytes2(5e3)),
|
|
1948
2072
|
"Maximum storage size is 5000 GB"
|
|
@@ -1953,31 +2077,31 @@ var MinimumStorageSchema = StorageSchema.describe(
|
|
|
1953
2077
|
var MaximumStorageSchema = StorageSchema.describe(
|
|
1954
2078
|
"The upper limit for data storage the cache is set to use. You can specify a size value from 1 GB to 5000 GB."
|
|
1955
2079
|
);
|
|
1956
|
-
var EcpuSchema =
|
|
2080
|
+
var EcpuSchema = z31.number().int().min(1e3).max(15e6);
|
|
1957
2081
|
var MinimumEcpuSchema = EcpuSchema.describe(
|
|
1958
2082
|
"The minimum number of ECPUs the cache can consume per second. You can specify a integer from 1,000 to 15,000,000."
|
|
1959
2083
|
);
|
|
1960
2084
|
var MaximumEcpuSchema = EcpuSchema.describe(
|
|
1961
2085
|
"The maximum number of ECPUs the cache can consume per second. You can specify a integer from 1,000 to 15,000,000."
|
|
1962
2086
|
);
|
|
1963
|
-
var CachesSchema =
|
|
2087
|
+
var CachesSchema = z31.record(
|
|
1964
2088
|
ResourceIdSchema,
|
|
1965
|
-
|
|
2089
|
+
z31.object({
|
|
1966
2090
|
minStorage: MinimumStorageSchema.optional(),
|
|
1967
2091
|
maxStorage: MaximumStorageSchema.optional(),
|
|
1968
2092
|
minECPU: MinimumEcpuSchema.optional(),
|
|
1969
2093
|
maxECPU: MaximumEcpuSchema.optional(),
|
|
1970
|
-
snapshotRetentionLimit:
|
|
2094
|
+
snapshotRetentionLimit: z31.number().int().positive().default(1)
|
|
1971
2095
|
})
|
|
1972
2096
|
).optional().describe("Define the caches in your stack. For access to the cache put your functions inside the global VPC.");
|
|
1973
2097
|
|
|
1974
2098
|
// src/feature/command/schema.ts
|
|
1975
|
-
import { z as
|
|
1976
|
-
var CommandSchema =
|
|
1977
|
-
|
|
2099
|
+
import { z as z32 } from "zod";
|
|
2100
|
+
var CommandSchema = z32.union([
|
|
2101
|
+
z32.object({
|
|
1978
2102
|
file: LocalFileSchema,
|
|
1979
|
-
handler:
|
|
1980
|
-
description:
|
|
2103
|
+
handler: z32.string().default("default").describe("The name of the handler that needs to run"),
|
|
2104
|
+
description: z32.string().optional().describe("A description of the command")
|
|
1981
2105
|
// options: z.record(ResourceIdSchema, OptionSchema).optional(),
|
|
1982
2106
|
// arguments: z.record(ResourceIdSchema, ArgumentSchema).optional(),
|
|
1983
2107
|
}),
|
|
@@ -1987,22 +2111,22 @@ var CommandSchema = z31.union([
|
|
|
1987
2111
|
description: void 0
|
|
1988
2112
|
}))
|
|
1989
2113
|
]);
|
|
1990
|
-
var CommandsSchema =
|
|
2114
|
+
var CommandsSchema = z32.record(ResourceIdSchema, CommandSchema).optional().describe("Define the custom commands for your stack.");
|
|
1991
2115
|
|
|
1992
2116
|
// src/feature/config/schema.ts
|
|
1993
|
-
import { z as
|
|
1994
|
-
var ConfigNameSchema =
|
|
1995
|
-
var ConfigsSchema =
|
|
2117
|
+
import { z as z33 } from "zod";
|
|
2118
|
+
var ConfigNameSchema = z33.string().regex(/[a-z0-9\-]/g, "Invalid config name");
|
|
2119
|
+
var ConfigsSchema = z33.array(ConfigNameSchema).optional().describe("Define the config values for your stack.");
|
|
1996
2120
|
|
|
1997
2121
|
// src/feature/cron/schema/index.ts
|
|
1998
|
-
import { z as
|
|
2122
|
+
import { z as z35 } from "zod";
|
|
1999
2123
|
|
|
2000
2124
|
// src/feature/cron/schema/schedule.ts
|
|
2001
|
-
import { z as
|
|
2125
|
+
import { z as z34 } from "zod";
|
|
2002
2126
|
import { awsCronExpressionValidator } from "aws-cron-expression-validator";
|
|
2003
|
-
var RateExpressionSchema =
|
|
2127
|
+
var RateExpressionSchema = z34.custom(
|
|
2004
2128
|
(value) => {
|
|
2005
|
-
return
|
|
2129
|
+
return z34.string().regex(/^[0-9]+ (seconds?|minutes?|hours?|days?)$/).refine((rate) => {
|
|
2006
2130
|
const [str] = rate.split(" ");
|
|
2007
2131
|
const number = parseInt(str);
|
|
2008
2132
|
return number > 0;
|
|
@@ -2018,9 +2142,9 @@ var RateExpressionSchema = z33.custom(
|
|
|
2018
2142
|
}
|
|
2019
2143
|
return `rate(${rate})`;
|
|
2020
2144
|
});
|
|
2021
|
-
var CronExpressionSchema =
|
|
2145
|
+
var CronExpressionSchema = z34.custom(
|
|
2022
2146
|
(value) => {
|
|
2023
|
-
return
|
|
2147
|
+
return z34.string().safeParse(value).success;
|
|
2024
2148
|
},
|
|
2025
2149
|
{ message: "Invalid cron expression" }
|
|
2026
2150
|
).superRefine((value, ctx) => {
|
|
@@ -2029,12 +2153,12 @@ var CronExpressionSchema = z33.custom(
|
|
|
2029
2153
|
} catch (error) {
|
|
2030
2154
|
if (error instanceof Error) {
|
|
2031
2155
|
ctx.addIssue({
|
|
2032
|
-
code:
|
|
2156
|
+
code: z34.ZodIssueCode.custom,
|
|
2033
2157
|
message: `Invalid cron expression: ${error.message}`
|
|
2034
2158
|
});
|
|
2035
2159
|
} else {
|
|
2036
2160
|
ctx.addIssue({
|
|
2037
|
-
code:
|
|
2161
|
+
code: z34.ZodIssueCode.custom,
|
|
2038
2162
|
message: "Invalid cron expression"
|
|
2039
2163
|
});
|
|
2040
2164
|
}
|
|
@@ -2045,32 +2169,32 @@ var CronExpressionSchema = z33.custom(
|
|
|
2045
2169
|
var ScheduleExpressionSchema = RateExpressionSchema.or(CronExpressionSchema);
|
|
2046
2170
|
|
|
2047
2171
|
// src/feature/cron/schema/index.ts
|
|
2048
|
-
var RetryAttemptsSchema4 =
|
|
2172
|
+
var RetryAttemptsSchema4 = z35.number().int().min(0).max(2).describe(
|
|
2049
2173
|
"The maximum number of times to retry when the function returns an error. You can specify a number from 0 to 2."
|
|
2050
2174
|
);
|
|
2051
|
-
var CronsSchema =
|
|
2175
|
+
var CronsSchema = z35.record(
|
|
2052
2176
|
ResourceIdSchema,
|
|
2053
|
-
|
|
2054
|
-
enabled:
|
|
2177
|
+
z35.object({
|
|
2178
|
+
enabled: z35.boolean().default(true).describe("If the cron is enabled."),
|
|
2055
2179
|
consumer: FunctionSchema.describe("The consuming lambda function properties."),
|
|
2056
2180
|
schedule: ScheduleExpressionSchema.describe(
|
|
2057
2181
|
'The scheduling expression.\n\nexample: "0 20 * * ? *"\nexample: "5 minutes"'
|
|
2058
2182
|
),
|
|
2059
|
-
payload:
|
|
2183
|
+
payload: z35.unknown().optional().describe("The JSON payload that will be passed to the consumer."),
|
|
2060
2184
|
retryAttempts: RetryAttemptsSchema4.default(2)
|
|
2061
2185
|
})
|
|
2062
2186
|
).optional().describe(`Define the cron jobs in your stack.`);
|
|
2063
2187
|
|
|
2064
2188
|
// src/feature/search/schema.ts
|
|
2065
2189
|
import { gibibytes as gibibytes3 } from "@awsless/size";
|
|
2066
|
-
import { z as
|
|
2067
|
-
var VersionSchema =
|
|
2190
|
+
import { z as z36 } from "zod";
|
|
2191
|
+
var VersionSchema = z36.union([
|
|
2068
2192
|
//
|
|
2069
|
-
|
|
2070
|
-
|
|
2193
|
+
z36.enum(["2.13", "2.11", "2.9", "2.7", "2.5", "2.3", "1.3"]),
|
|
2194
|
+
z36.string()
|
|
2071
2195
|
]).describe("Specify the OpenSearch engine version.");
|
|
2072
|
-
var TypeSchema =
|
|
2073
|
-
|
|
2196
|
+
var TypeSchema = z36.union([
|
|
2197
|
+
z36.enum([
|
|
2074
2198
|
"t3.small",
|
|
2075
2199
|
"t3.medium",
|
|
2076
2200
|
"m3.medium",
|
|
@@ -2144,13 +2268,13 @@ var TypeSchema = z35.union([
|
|
|
2144
2268
|
"r6gd.12xlarge",
|
|
2145
2269
|
"r6gd.16xlarge"
|
|
2146
2270
|
]),
|
|
2147
|
-
|
|
2271
|
+
z36.string()
|
|
2148
2272
|
]).describe("Instance type of data nodes in the cluster.");
|
|
2149
|
-
var CountSchema =
|
|
2273
|
+
var CountSchema = z36.number().int().min(1).describe("Number of instances in the cluster.");
|
|
2150
2274
|
var StorageSizeSchema = SizeSchema.refine(sizeMin(gibibytes3(10)), "Minimum storage size is 10 GB").refine(sizeMax(gibibytes3(100)), "Maximum storage size is 100 GB").describe("The size of the function's /tmp directory. You can specify a size value from 512 MB to 10 GiB.");
|
|
2151
|
-
var SearchsSchema =
|
|
2275
|
+
var SearchsSchema = z36.record(
|
|
2152
2276
|
ResourceIdSchema,
|
|
2153
|
-
|
|
2277
|
+
z36.object({
|
|
2154
2278
|
type: TypeSchema.default("t3.small"),
|
|
2155
2279
|
count: CountSchema.default(1),
|
|
2156
2280
|
version: VersionSchema.default("2.13"),
|
|
@@ -2161,12 +2285,12 @@ var SearchsSchema = z35.record(
|
|
|
2161
2285
|
).optional().describe("Define the search instances in your stack. Backed by OpenSearch.");
|
|
2162
2286
|
|
|
2163
2287
|
// src/feature/site/schema.ts
|
|
2164
|
-
import { z as
|
|
2288
|
+
import { z as z38 } from "zod";
|
|
2165
2289
|
|
|
2166
2290
|
// src/config/schema/local-entry.ts
|
|
2167
2291
|
import { stat as stat3 } from "fs/promises";
|
|
2168
|
-
import { z as
|
|
2169
|
-
var LocalEntrySchema =
|
|
2292
|
+
import { z as z37 } from "zod";
|
|
2293
|
+
var LocalEntrySchema = z37.union([
|
|
2170
2294
|
RelativePathSchema.refine(async (path) => {
|
|
2171
2295
|
try {
|
|
2172
2296
|
const s = await stat3(path);
|
|
@@ -2175,7 +2299,7 @@ var LocalEntrySchema = z36.union([
|
|
|
2175
2299
|
return false;
|
|
2176
2300
|
}
|
|
2177
2301
|
}, `File or directory doesn't exist`),
|
|
2178
|
-
|
|
2302
|
+
z37.object({
|
|
2179
2303
|
nocheck: RelativePathSchema.describe(
|
|
2180
2304
|
"Specifies a local file or directory without checking if the file or directory exists."
|
|
2181
2305
|
)
|
|
@@ -2183,21 +2307,21 @@ var LocalEntrySchema = z36.union([
|
|
|
2183
2307
|
]);
|
|
2184
2308
|
|
|
2185
2309
|
// src/feature/site/schema.ts
|
|
2186
|
-
var SitesSchema =
|
|
2310
|
+
var SitesSchema = z38.record(
|
|
2187
2311
|
ResourceIdSchema,
|
|
2188
|
-
|
|
2312
|
+
z38.object({
|
|
2189
2313
|
router: ResourceIdSchema.describe("The router id to link your site with."),
|
|
2190
2314
|
path: RouteSchema2.describe("The path inside the router to link your site to."),
|
|
2191
|
-
build:
|
|
2192
|
-
command:
|
|
2315
|
+
build: z38.object({
|
|
2316
|
+
command: z38.string().describe(
|
|
2193
2317
|
`Specifies the files and directories to generate the cache key for your custom build command.`
|
|
2194
2318
|
),
|
|
2195
|
-
cacheKey:
|
|
2319
|
+
cacheKey: z38.union([LocalEntrySchema.transform((v) => [v]), LocalEntrySchema.array()]).describe(
|
|
2196
2320
|
`Specifies the files and directories to generate the cache key for your custom build command.`
|
|
2197
2321
|
),
|
|
2198
|
-
configs:
|
|
2322
|
+
configs: z38.string().array().optional().describe("Define the config values for your build command.")
|
|
2199
2323
|
}).optional().describe(`Specifies the build process for sites that need a build step.`),
|
|
2200
|
-
static:
|
|
2324
|
+
static: z38.union([LocalDirectorySchema, z38.boolean()]).optional().describe(
|
|
2201
2325
|
"Specifies the path to the static files directory. Additionally you can also pass `true` when you don't have local static files, but still want to make an S3 bucket."
|
|
2202
2326
|
),
|
|
2203
2327
|
ssr: FunctionSchema.optional().describe("Specifies the file that will render the site on the server.")
|
|
@@ -2205,21 +2329,21 @@ var SitesSchema = z37.record(
|
|
|
2205
2329
|
).optional().describe("Define the sites in your stack.");
|
|
2206
2330
|
|
|
2207
2331
|
// src/feature/store/schema.ts
|
|
2208
|
-
import { z as
|
|
2209
|
-
var StoresSchema =
|
|
2210
|
-
|
|
2332
|
+
import { z as z39 } from "zod";
|
|
2333
|
+
var StoresSchema = z39.union([
|
|
2334
|
+
z39.array(ResourceIdSchema).transform((list3) => {
|
|
2211
2335
|
const stores = {};
|
|
2212
2336
|
for (const key of list3) {
|
|
2213
2337
|
stores[key] = {};
|
|
2214
2338
|
}
|
|
2215
2339
|
return stores;
|
|
2216
2340
|
}),
|
|
2217
|
-
|
|
2341
|
+
z39.record(
|
|
2218
2342
|
ResourceIdSchema,
|
|
2219
|
-
|
|
2343
|
+
z39.object({
|
|
2220
2344
|
static: LocalDirectorySchema.optional().describe("Specifies the path to the static files directory."),
|
|
2221
|
-
versioning:
|
|
2222
|
-
events:
|
|
2345
|
+
versioning: z39.boolean().default(false).describe("Enable versioning of your store."),
|
|
2346
|
+
events: z39.object({
|
|
2223
2347
|
// create
|
|
2224
2348
|
"created:*": TaskSchema.optional().describe(
|
|
2225
2349
|
"Subscribe to notifications regardless of the API that was used to create an object."
|
|
@@ -2252,30 +2376,30 @@ var StoresSchema = z38.union([
|
|
|
2252
2376
|
]).optional().describe("Define the stores in your stack.");
|
|
2253
2377
|
|
|
2254
2378
|
// src/feature/icon/schema.ts
|
|
2255
|
-
import { z as
|
|
2379
|
+
import { z as z40 } from "zod";
|
|
2256
2380
|
var staticOriginSchema = LocalDirectorySchema.describe(
|
|
2257
2381
|
"Specifies the path to a local image directory that will be uploaded in S3."
|
|
2258
2382
|
);
|
|
2259
2383
|
var functionOriginSchema = FunctionSchema.describe(
|
|
2260
2384
|
"Specifies the file that will be called when an image isn't found in the (cache) bucket."
|
|
2261
2385
|
);
|
|
2262
|
-
var IconsSchema =
|
|
2386
|
+
var IconsSchema = z40.record(
|
|
2263
2387
|
ResourceIdSchema,
|
|
2264
|
-
|
|
2388
|
+
z40.object({
|
|
2265
2389
|
// domain: ResourceIdSchema.describe('The domain id to link your site with.').optional(),
|
|
2266
2390
|
// subDomain: z.string().optional(),
|
|
2267
2391
|
router: ResourceIdSchema.describe("The router id to link your icon proxy."),
|
|
2268
2392
|
path: RouteSchema2.describe("The path inside the router to link your icon proxy to."),
|
|
2269
2393
|
log: LogSchema.optional(),
|
|
2270
2394
|
cacheDuration: DurationSchema.optional().describe("The cache duration of the cached icons."),
|
|
2271
|
-
preserveIds:
|
|
2272
|
-
symbols:
|
|
2273
|
-
origin:
|
|
2274
|
-
|
|
2395
|
+
preserveIds: z40.boolean().optional().default(false).describe("Preserve the IDs of the icons."),
|
|
2396
|
+
symbols: z40.boolean().optional().default(false).describe(`Convert the SVG's to SVG symbols.`),
|
|
2397
|
+
origin: z40.union([
|
|
2398
|
+
z40.object({
|
|
2275
2399
|
static: staticOriginSchema,
|
|
2276
2400
|
function: functionOriginSchema.optional()
|
|
2277
2401
|
}),
|
|
2278
|
-
|
|
2402
|
+
z40.object({
|
|
2279
2403
|
static: staticOriginSchema.optional(),
|
|
2280
2404
|
function: functionOriginSchema
|
|
2281
2405
|
})
|
|
@@ -2302,13 +2426,13 @@ var IconsSchema = z39.record(
|
|
|
2302
2426
|
).optional().describe("Define an svg icon proxy in your stack. Store, optimize, and deliver svg icons at scale.");
|
|
2303
2427
|
|
|
2304
2428
|
// src/feature/image/schema.ts
|
|
2305
|
-
import { z as
|
|
2306
|
-
var transformationOptionsSchema =
|
|
2307
|
-
width:
|
|
2308
|
-
height:
|
|
2309
|
-
fit:
|
|
2310
|
-
position:
|
|
2311
|
-
quality:
|
|
2429
|
+
import { z as z41 } from "zod";
|
|
2430
|
+
var transformationOptionsSchema = z41.object({
|
|
2431
|
+
width: z41.number().int().positive().optional(),
|
|
2432
|
+
height: z41.number().int().positive().optional(),
|
|
2433
|
+
fit: z41.enum(["cover", "contain", "fill", "inside", "outside"]).optional(),
|
|
2434
|
+
position: z41.enum(["top", "right top", "right", "right bottom", "bottom", "left bottom", "left", "left top", "center"]).optional(),
|
|
2435
|
+
quality: z41.number().int().min(1).max(100).optional()
|
|
2312
2436
|
});
|
|
2313
2437
|
var staticOriginSchema2 = LocalDirectorySchema.describe(
|
|
2314
2438
|
"Specifies the path to a local image directory that will be uploaded in S3."
|
|
@@ -2316,38 +2440,38 @@ var staticOriginSchema2 = LocalDirectorySchema.describe(
|
|
|
2316
2440
|
var functionOriginSchema2 = FunctionSchema.describe(
|
|
2317
2441
|
"Specifies the file that will be called when an image isn't found in the (cache) bucket."
|
|
2318
2442
|
);
|
|
2319
|
-
var ImagesSchema =
|
|
2443
|
+
var ImagesSchema = z41.record(
|
|
2320
2444
|
ResourceIdSchema,
|
|
2321
|
-
|
|
2445
|
+
z41.object({
|
|
2322
2446
|
// domain: ResourceIdSchema.describe('The domain id to link your site with.').optional(),
|
|
2323
2447
|
// subDomain: z.string().optional(),
|
|
2324
2448
|
router: ResourceIdSchema.describe("The router id to link your image proxy."),
|
|
2325
2449
|
path: RouteSchema2.describe("The path inside the router to link your image proxy to."),
|
|
2326
2450
|
log: LogSchema.optional(),
|
|
2327
2451
|
cacheDuration: DurationSchema.optional().describe("Cache duration of the cached images."),
|
|
2328
|
-
presets:
|
|
2329
|
-
extensions:
|
|
2330
|
-
jpg:
|
|
2331
|
-
mozjpeg:
|
|
2332
|
-
progressive:
|
|
2452
|
+
presets: z41.record(z41.string(), transformationOptionsSchema).describe("Named presets for image transformations"),
|
|
2453
|
+
extensions: z41.object({
|
|
2454
|
+
jpg: z41.object({
|
|
2455
|
+
mozjpeg: z41.boolean().optional(),
|
|
2456
|
+
progressive: z41.boolean().optional()
|
|
2333
2457
|
}).optional(),
|
|
2334
|
-
webp:
|
|
2335
|
-
effort:
|
|
2336
|
-
lossless:
|
|
2337
|
-
nearLossless:
|
|
2458
|
+
webp: z41.object({
|
|
2459
|
+
effort: z41.number().int().min(1).max(10).default(7).optional(),
|
|
2460
|
+
lossless: z41.boolean().optional(),
|
|
2461
|
+
nearLossless: z41.boolean().optional()
|
|
2338
2462
|
}).optional(),
|
|
2339
|
-
png:
|
|
2340
|
-
compressionLevel:
|
|
2463
|
+
png: z41.object({
|
|
2464
|
+
compressionLevel: z41.number().int().min(0).max(9).default(6).optional()
|
|
2341
2465
|
}).optional()
|
|
2342
2466
|
}).refine((data) => {
|
|
2343
2467
|
return Object.keys(data).length > 0;
|
|
2344
2468
|
}, "At least one extension must be defined.").describe("Specify the allowed extensions."),
|
|
2345
|
-
origin:
|
|
2346
|
-
|
|
2469
|
+
origin: z41.union([
|
|
2470
|
+
z41.object({
|
|
2347
2471
|
static: staticOriginSchema2,
|
|
2348
2472
|
function: functionOriginSchema2.optional()
|
|
2349
2473
|
}),
|
|
2350
|
-
|
|
2474
|
+
z41.object({
|
|
2351
2475
|
static: staticOriginSchema2.optional(),
|
|
2352
2476
|
function: functionOriginSchema2
|
|
2353
2477
|
})
|
|
@@ -2362,7 +2486,7 @@ var ImagesSchema = z40.record(
|
|
|
2362
2486
|
).optional().describe("Define an image proxy in your stack. Store, transform, optimize, and deliver images at scale.");
|
|
2363
2487
|
|
|
2364
2488
|
// src/feature/metric/schema.ts
|
|
2365
|
-
import { z as
|
|
2489
|
+
import { z as z42 } from "zod";
|
|
2366
2490
|
var ops = {
|
|
2367
2491
|
">": "GreaterThanThreshold",
|
|
2368
2492
|
">=": "GreaterThanOrEqualToThreshold",
|
|
@@ -2376,15 +2500,15 @@ var stats = {
|
|
|
2376
2500
|
min: "Minimum",
|
|
2377
2501
|
max: "Maximum"
|
|
2378
2502
|
};
|
|
2379
|
-
var WhereSchema =
|
|
2380
|
-
|
|
2503
|
+
var WhereSchema = z42.union([
|
|
2504
|
+
z42.string().regex(/(count|avg|sum|min|max) (>|>=|<|<=) (\d)/, "Invalid where query").transform((where) => {
|
|
2381
2505
|
const [stat4, op, value] = where.split(" ");
|
|
2382
2506
|
return { stat: stat4, op, value: parseFloat(value) };
|
|
2383
2507
|
}),
|
|
2384
|
-
|
|
2385
|
-
stat:
|
|
2386
|
-
op:
|
|
2387
|
-
value:
|
|
2508
|
+
z42.object({
|
|
2509
|
+
stat: z42.enum(["count", "avg", "sum", "min", "max"]),
|
|
2510
|
+
op: z42.enum([">", ">=", "<", "<="]),
|
|
2511
|
+
value: z42.number()
|
|
2388
2512
|
})
|
|
2389
2513
|
]).transform((where) => {
|
|
2390
2514
|
return {
|
|
@@ -2393,39 +2517,39 @@ var WhereSchema = z41.union([
|
|
|
2393
2517
|
value: where.value
|
|
2394
2518
|
};
|
|
2395
2519
|
});
|
|
2396
|
-
var AlarmSchema =
|
|
2397
|
-
description:
|
|
2520
|
+
var AlarmSchema = z42.object({
|
|
2521
|
+
description: z42.string().optional(),
|
|
2398
2522
|
where: WhereSchema,
|
|
2399
2523
|
period: DurationSchema,
|
|
2400
|
-
minDataPoints:
|
|
2401
|
-
trigger:
|
|
2524
|
+
minDataPoints: z42.number().int().default(1),
|
|
2525
|
+
trigger: z42.union([EmailSchema.transform((v) => [v]), EmailSchema.array(), FunctionSchema])
|
|
2402
2526
|
});
|
|
2403
|
-
var MetricsSchema =
|
|
2527
|
+
var MetricsSchema = z42.record(
|
|
2404
2528
|
ResourceIdSchema,
|
|
2405
|
-
|
|
2406
|
-
type:
|
|
2529
|
+
z42.object({
|
|
2530
|
+
type: z42.enum(["number", "size", "duration"]),
|
|
2407
2531
|
alarms: AlarmSchema.array().optional()
|
|
2408
2532
|
})
|
|
2409
2533
|
).optional().describe("Define the metrics in your stack.");
|
|
2410
2534
|
|
|
2411
2535
|
// src/feature/table/schema.ts
|
|
2412
|
-
import { minutes as
|
|
2413
|
-
import { z as
|
|
2414
|
-
var KeySchema =
|
|
2415
|
-
var TablesSchema =
|
|
2536
|
+
import { minutes as minutes6, seconds as seconds4 } from "@awsless/duration";
|
|
2537
|
+
import { z as z43 } from "zod";
|
|
2538
|
+
var KeySchema = z43.string().min(1).max(255);
|
|
2539
|
+
var TablesSchema = z43.record(
|
|
2416
2540
|
ResourceIdSchema,
|
|
2417
|
-
|
|
2541
|
+
z43.object({
|
|
2418
2542
|
hash: KeySchema.describe(
|
|
2419
2543
|
"Specifies the name of the partition / hash key that makes up the primary key for the table."
|
|
2420
2544
|
),
|
|
2421
2545
|
sort: KeySchema.optional().describe(
|
|
2422
2546
|
"Specifies the name of the range / sort key that makes up the primary key for the table."
|
|
2423
2547
|
),
|
|
2424
|
-
fields:
|
|
2548
|
+
fields: z43.record(z43.string(), z43.enum(["string", "number", "binary"])).optional().describe(
|
|
2425
2549
|
'A list of attributes that describe the key schema for the table and indexes. If no attribute field is defined we default to "string".'
|
|
2426
2550
|
),
|
|
2427
|
-
class:
|
|
2428
|
-
pointInTimeRecovery:
|
|
2551
|
+
class: z43.enum(["standard", "standard-infrequent-access"]).default("standard").describe("The table class of the table."),
|
|
2552
|
+
pointInTimeRecovery: z43.boolean().default(false).describe("Indicates whether point in time recovery is enabled on the table."),
|
|
2429
2553
|
ttl: KeySchema.optional().describe(
|
|
2430
2554
|
[
|
|
2431
2555
|
"The name of the TTL attribute used to store the expiration time for items in the table.",
|
|
@@ -2433,8 +2557,8 @@ var TablesSchema = z42.record(
|
|
|
2433
2557
|
].join("\n")
|
|
2434
2558
|
),
|
|
2435
2559
|
// deletionProtection: DeletionProtectionSchema.optional(),
|
|
2436
|
-
stream:
|
|
2437
|
-
type:
|
|
2560
|
+
stream: z43.object({
|
|
2561
|
+
type: z43.enum(["keys-only", "new-image", "old-image", "new-and-old-images"]).describe(
|
|
2438
2562
|
[
|
|
2439
2563
|
"When an item in the table is modified, you can determines what information is written to the stream for this table.",
|
|
2440
2564
|
"Valid values are:",
|
|
@@ -2444,7 +2568,7 @@ var TablesSchema = z42.record(
|
|
|
2444
2568
|
"- new-and-old-images - Both the new and the old item images of the item are written to the stream."
|
|
2445
2569
|
].join("\n")
|
|
2446
2570
|
),
|
|
2447
|
-
batchSize:
|
|
2571
|
+
batchSize: z43.number().min(1).max(1e4).default(1).describe(
|
|
2448
2572
|
[
|
|
2449
2573
|
"The maximum number of records in each batch that Lambda pulls from your stream and sends to your function.",
|
|
2450
2574
|
"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).",
|
|
@@ -2454,7 +2578,7 @@ var TablesSchema = z42.record(
|
|
|
2454
2578
|
batchWindow: DurationSchema.refine(
|
|
2455
2579
|
durationMin(seconds4(1)),
|
|
2456
2580
|
"Minimum batch window duration is 1 second"
|
|
2457
|
-
).refine(durationMax(
|
|
2581
|
+
).refine(durationMax(minutes6(5)), "Maximum batch window duration is 5 minutes").optional().describe(
|
|
2458
2582
|
[
|
|
2459
2583
|
"The maximum amount of time that is spend gathering records before invoking the function.",
|
|
2460
2584
|
"You can specify a duration from 1 seconds to 5 minutes."
|
|
@@ -2473,7 +2597,7 @@ var TablesSchema = z42.record(
|
|
|
2473
2597
|
// 'The default value is 60s',
|
|
2474
2598
|
// ].join('\n')
|
|
2475
2599
|
// ),
|
|
2476
|
-
retryAttempts:
|
|
2600
|
+
retryAttempts: z43.number().min(-1).max(1e4).default(2).describe(
|
|
2477
2601
|
[
|
|
2478
2602
|
"Discard records after the specified number of retries.",
|
|
2479
2603
|
"-1 will sets the maximum number of retries to infinite.",
|
|
@@ -2482,7 +2606,7 @@ var TablesSchema = z42.record(
|
|
|
2482
2606
|
"The default value is 2"
|
|
2483
2607
|
].join("\n")
|
|
2484
2608
|
),
|
|
2485
|
-
concurrencyPerShard:
|
|
2609
|
+
concurrencyPerShard: z43.number().min(1).max(10).default(1).describe(
|
|
2486
2610
|
[
|
|
2487
2611
|
"The number of batches to process concurrently from each shard.",
|
|
2488
2612
|
"You can specify a number from 1 to 10."
|
|
@@ -2492,16 +2616,16 @@ var TablesSchema = z42.record(
|
|
|
2492
2616
|
}).optional().describe(
|
|
2493
2617
|
"The settings for the DynamoDB table stream, which capture changes to items stored in the table."
|
|
2494
2618
|
),
|
|
2495
|
-
indexes:
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
hash:
|
|
2619
|
+
indexes: z43.record(
|
|
2620
|
+
z43.string(),
|
|
2621
|
+
z43.object({
|
|
2622
|
+
hash: z43.union([KeySchema.transform((v) => [v]), KeySchema.array()]).describe(
|
|
2499
2623
|
"Specifies the name of the partition / hash key that makes up the primary key for the global secondary index."
|
|
2500
2624
|
),
|
|
2501
|
-
sort:
|
|
2625
|
+
sort: z43.union([KeySchema.transform((v) => [v]), KeySchema.array()]).optional().describe(
|
|
2502
2626
|
"Specifies the name of the range / sort key that makes up the primary key for the global secondary index."
|
|
2503
2627
|
),
|
|
2504
|
-
projection:
|
|
2628
|
+
projection: z43.enum(["all", "keys-only"]).default("all").describe(
|
|
2505
2629
|
[
|
|
2506
2630
|
"The set of attributes that are projected into the index:",
|
|
2507
2631
|
"- all - All of the table attributes are projected into the index.",
|
|
@@ -2515,12 +2639,12 @@ var TablesSchema = z42.record(
|
|
|
2515
2639
|
).optional().describe("Define the tables in your stack.");
|
|
2516
2640
|
|
|
2517
2641
|
// src/feature/test/schema.ts
|
|
2518
|
-
import { z as
|
|
2519
|
-
var TestsSchema =
|
|
2642
|
+
import { z as z44 } from "zod";
|
|
2643
|
+
var TestsSchema = z44.union([
|
|
2520
2644
|
//
|
|
2521
2645
|
LocalDirectorySchema.transform((v) => [v]),
|
|
2522
2646
|
LocalDirectorySchema.array(),
|
|
2523
|
-
|
|
2647
|
+
z44.literal(false)
|
|
2524
2648
|
]).describe("Define the location of your tests for your stack.").optional();
|
|
2525
2649
|
|
|
2526
2650
|
// src/config/stack.ts
|
|
@@ -2528,8 +2652,8 @@ var DependsSchema = ResourceIdSchema.array().optional().describe("Define the sta
|
|
|
2528
2652
|
var NameSchema = ResourceIdSchema.refine((name) => !["base", "hostedzones"].includes(name), {
|
|
2529
2653
|
message: `Stack name can't be a reserved name.`
|
|
2530
2654
|
}).describe("Stack name.");
|
|
2531
|
-
var StackSchema =
|
|
2532
|
-
$schema:
|
|
2655
|
+
var StackSchema = z45.object({
|
|
2656
|
+
$schema: z45.string().optional(),
|
|
2533
2657
|
name: NameSchema,
|
|
2534
2658
|
depends: DependsSchema,
|
|
2535
2659
|
commands: CommandsSchema,
|
|
@@ -2546,6 +2670,7 @@ var StackSchema = z44.object({
|
|
|
2546
2670
|
subscribers: SubscribersSchema,
|
|
2547
2671
|
functions: FunctionsSchema,
|
|
2548
2672
|
instances: InstancesSchema,
|
|
2673
|
+
jobs: JobsSchema,
|
|
2549
2674
|
tasks: TasksSchema,
|
|
2550
2675
|
tables: TablesSchema,
|
|
2551
2676
|
stores: StoresSchema,
|
|
@@ -2566,37 +2691,37 @@ import { basename, dirname as dirname2, extname, join as join4 } from "path";
|
|
|
2566
2691
|
|
|
2567
2692
|
// src/config/stage-patch.ts
|
|
2568
2693
|
import jsonPatch from "fast-json-patch";
|
|
2569
|
-
import { z as
|
|
2570
|
-
var AddOperationSchema =
|
|
2571
|
-
op:
|
|
2572
|
-
path:
|
|
2573
|
-
value:
|
|
2694
|
+
import { z as z46 } from "zod";
|
|
2695
|
+
var AddOperationSchema = z46.object({
|
|
2696
|
+
op: z46.literal("add"),
|
|
2697
|
+
path: z46.string(),
|
|
2698
|
+
value: z46.unknown()
|
|
2574
2699
|
}).strict();
|
|
2575
|
-
var RemoveOperationSchema =
|
|
2576
|
-
op:
|
|
2577
|
-
path:
|
|
2700
|
+
var RemoveOperationSchema = z46.object({
|
|
2701
|
+
op: z46.literal("remove"),
|
|
2702
|
+
path: z46.string()
|
|
2578
2703
|
}).strict();
|
|
2579
|
-
var ReplaceOperationSchema =
|
|
2580
|
-
op:
|
|
2581
|
-
path:
|
|
2582
|
-
value:
|
|
2704
|
+
var ReplaceOperationSchema = z46.object({
|
|
2705
|
+
op: z46.literal("replace"),
|
|
2706
|
+
path: z46.string(),
|
|
2707
|
+
value: z46.unknown()
|
|
2583
2708
|
}).strict();
|
|
2584
|
-
var MoveOperationSchema =
|
|
2585
|
-
op:
|
|
2586
|
-
from:
|
|
2587
|
-
path:
|
|
2709
|
+
var MoveOperationSchema = z46.object({
|
|
2710
|
+
op: z46.literal("move"),
|
|
2711
|
+
from: z46.string(),
|
|
2712
|
+
path: z46.string()
|
|
2588
2713
|
}).strict();
|
|
2589
|
-
var CopyOperationSchema =
|
|
2590
|
-
op:
|
|
2591
|
-
from:
|
|
2592
|
-
path:
|
|
2714
|
+
var CopyOperationSchema = z46.object({
|
|
2715
|
+
op: z46.literal("copy"),
|
|
2716
|
+
from: z46.string(),
|
|
2717
|
+
path: z46.string()
|
|
2593
2718
|
}).strict();
|
|
2594
|
-
var TestOperationSchema =
|
|
2595
|
-
op:
|
|
2596
|
-
path:
|
|
2597
|
-
value:
|
|
2719
|
+
var TestOperationSchema = z46.object({
|
|
2720
|
+
op: z46.literal("test"),
|
|
2721
|
+
path: z46.string(),
|
|
2722
|
+
value: z46.unknown()
|
|
2598
2723
|
}).strict();
|
|
2599
|
-
var JsonPatchOperationSchema =
|
|
2724
|
+
var JsonPatchOperationSchema = z46.discriminatedUnion("op", [
|
|
2600
2725
|
AddOperationSchema,
|
|
2601
2726
|
RemoveOperationSchema,
|
|
2602
2727
|
ReplaceOperationSchema,
|
|
@@ -2604,8 +2729,8 @@ var JsonPatchOperationSchema = z45.discriminatedUnion("op", [
|
|
|
2604
2729
|
CopyOperationSchema,
|
|
2605
2730
|
TestOperationSchema
|
|
2606
2731
|
]);
|
|
2607
|
-
var StagePatchSchema =
|
|
2608
|
-
$schema:
|
|
2732
|
+
var StagePatchSchema = z46.object({
|
|
2733
|
+
$schema: z46.string().optional(),
|
|
2609
2734
|
operations: JsonPatchOperationSchema.array()
|
|
2610
2735
|
}).strict();
|
|
2611
2736
|
var applyStagePatch = (source, patch, file) => {
|
|
@@ -2621,13 +2746,13 @@ var applyStagePatch = (source, patch, file) => {
|
|
|
2621
2746
|
};
|
|
2622
2747
|
|
|
2623
2748
|
// src/config/load/validate.ts
|
|
2624
|
-
import { z as
|
|
2749
|
+
import { z as z47 } from "zod";
|
|
2625
2750
|
var validateConfig = async (schema, file, data) => {
|
|
2626
2751
|
try {
|
|
2627
2752
|
const result = await schema.parseAsync(data);
|
|
2628
2753
|
return result;
|
|
2629
2754
|
} catch (error) {
|
|
2630
|
-
if (error instanceof
|
|
2755
|
+
if (error instanceof z47.ZodError) {
|
|
2631
2756
|
throw new ConfigError(file, error, data);
|
|
2632
2757
|
}
|
|
2633
2758
|
throw error;
|
|
@@ -2862,7 +2987,7 @@ var generateGlobalAppId = (opt) => {
|
|
|
2862
2987
|
};
|
|
2863
2988
|
|
|
2864
2989
|
// src/feature/auth/index.ts
|
|
2865
|
-
import { toDays as
|
|
2990
|
+
import { toDays as toDays4, toHours } from "@awsless/duration";
|
|
2866
2991
|
var authFeature = defineFeature({
|
|
2867
2992
|
name: "auth",
|
|
2868
2993
|
async onTypeGen(ctx) {
|
|
@@ -2995,7 +3120,7 @@ var authFeature = defineFeature({
|
|
|
2995
3120
|
requireUppercase: props.password.uppercase,
|
|
2996
3121
|
requireNumbers: props.password.numbers,
|
|
2997
3122
|
requireSymbols: props.password.symbols,
|
|
2998
|
-
temporaryPasswordValidityDays:
|
|
3123
|
+
temporaryPasswordValidityDays: toDays4(props.password.temporaryPasswordValidity)
|
|
2999
3124
|
},
|
|
3000
3125
|
deletionProtection: ctx.appConfig.removal === "retain" ? "ACTIVE" : "INACTIVE"
|
|
3001
3126
|
},
|
|
@@ -3009,7 +3134,7 @@ var authFeature = defineFeature({
|
|
|
3009
3134
|
name,
|
|
3010
3135
|
idTokenValidity: toHours(props.validity.idToken),
|
|
3011
3136
|
accessTokenValidity: toHours(props.validity.accessToken),
|
|
3012
|
-
refreshTokenValidity:
|
|
3137
|
+
refreshTokenValidity: toDays4(props.validity.refreshToken),
|
|
3013
3138
|
tokenValidityUnits: [
|
|
3014
3139
|
{
|
|
3015
3140
|
idToken: "hours",
|
|
@@ -3467,8 +3592,8 @@ var zipFiles = (files) => {
|
|
|
3467
3592
|
};
|
|
3468
3593
|
|
|
3469
3594
|
// src/feature/function/util.ts
|
|
3470
|
-
import { toDays as
|
|
3471
|
-
import { toMebibytes as
|
|
3595
|
+
import { toDays as toDays5, toSeconds } from "@awsless/duration";
|
|
3596
|
+
import { toMebibytes as toMebibytes3 } from "@awsless/size";
|
|
3472
3597
|
import { pascalCase } from "change-case";
|
|
3473
3598
|
|
|
3474
3599
|
// src/util/cache.ts
|
|
@@ -3763,9 +3888,9 @@ var createLambdaFunction = (parentGroup, ctx, ns, id, local) => {
|
|
|
3763
3888
|
const policy = new aws4.iam.RolePolicy(group, "policy", {
|
|
3764
3889
|
role: role.name,
|
|
3765
3890
|
name: "lambda-policy",
|
|
3766
|
-
policy: new Output3(statementDeps, async (
|
|
3891
|
+
policy: new Output3(statementDeps, async (resolve2) => {
|
|
3767
3892
|
const list3 = await resolveInputs(statements);
|
|
3768
|
-
|
|
3893
|
+
resolve2(
|
|
3769
3894
|
JSON.stringify({
|
|
3770
3895
|
Version: "2012-10-17",
|
|
3771
3896
|
Statement: list3.map((statement) => ({
|
|
@@ -3827,7 +3952,7 @@ var createLambdaFunction = (parentGroup, ctx, ns, id, local) => {
|
|
|
3827
3952
|
runtime: props.runtime,
|
|
3828
3953
|
handler: props.handler,
|
|
3829
3954
|
timeout: toSeconds(props.timeout),
|
|
3830
|
-
memorySize:
|
|
3955
|
+
memorySize: toMebibytes3(props.memorySize),
|
|
3831
3956
|
architectures: [props.architecture],
|
|
3832
3957
|
timeouts: {
|
|
3833
3958
|
create: "30s",
|
|
@@ -3882,7 +4007,7 @@ var createLambdaFunction = (parentGroup, ctx, ns, id, local) => {
|
|
|
3882
4007
|
const logGroup = new aws4.cloudwatch.LogGroup(group, "log", {
|
|
3883
4008
|
// name: lambda.functionName.pipe(name => `/aws/lambda/${name}`),
|
|
3884
4009
|
name: `/aws/lambda/${name}`,
|
|
3885
|
-
retentionInDays:
|
|
4010
|
+
retentionInDays: toDays5(props.log.retention)
|
|
3886
4011
|
});
|
|
3887
4012
|
addPermission({
|
|
3888
4013
|
actions: ["logs:PutLogEvents", "logs:CreateLogStream"],
|
|
@@ -4129,7 +4254,7 @@ var cronFeature = defineFeature({
|
|
|
4129
4254
|
});
|
|
4130
4255
|
|
|
4131
4256
|
// src/feature/domain/index.ts
|
|
4132
|
-
import { minutes as
|
|
4257
|
+
import { minutes as minutes7, toSeconds as toSeconds2 } from "@awsless/duration";
|
|
4133
4258
|
import { Group as Group5 } from "@terraforge/core";
|
|
4134
4259
|
import { aws as aws6 } from "@terraforge/aws";
|
|
4135
4260
|
var domainFeature = defineFeature({
|
|
@@ -4171,7 +4296,7 @@ var domainFeature = defineFeature({
|
|
|
4171
4296
|
zoneId: zone.id,
|
|
4172
4297
|
name: option(certificate, 0).pipe((r) => r.resourceRecordName),
|
|
4173
4298
|
type: option(certificate, 0).pipe((r) => r.resourceRecordType),
|
|
4174
|
-
ttl: toSeconds2(
|
|
4299
|
+
ttl: toSeconds2(minutes7(5)),
|
|
4175
4300
|
records: [option(certificate, 0).pipe((r) => r.resourceRecordValue)],
|
|
4176
4301
|
allowOverwrite: true
|
|
4177
4302
|
});
|
|
@@ -4179,7 +4304,7 @@ var domainFeature = defineFeature({
|
|
|
4179
4304
|
zoneId: zone.id,
|
|
4180
4305
|
name: option(certificate, 1).pipe((r) => r.resourceRecordName),
|
|
4181
4306
|
type: option(certificate, 1).pipe((r) => r.resourceRecordType),
|
|
4182
|
-
ttl: toSeconds2(
|
|
4307
|
+
ttl: toSeconds2(minutes7(5)),
|
|
4183
4308
|
records: [option(certificate, 1).pipe((r) => r.resourceRecordValue)],
|
|
4184
4309
|
allowOverwrite: true
|
|
4185
4310
|
});
|
|
@@ -4214,7 +4339,7 @@ var domainFeature = defineFeature({
|
|
|
4214
4339
|
zoneId: zone.id,
|
|
4215
4340
|
name: option(globalCertificate, 0).pipe((r) => r.resourceRecordName),
|
|
4216
4341
|
type: option(globalCertificate, 0).pipe((r) => r.resourceRecordType),
|
|
4217
|
-
ttl: toSeconds2(
|
|
4342
|
+
ttl: toSeconds2(minutes7(5)),
|
|
4218
4343
|
records: [option(globalCertificate, 0).pipe((r) => r.resourceRecordValue)],
|
|
4219
4344
|
allowOverwrite: true
|
|
4220
4345
|
});
|
|
@@ -4222,7 +4347,7 @@ var domainFeature = defineFeature({
|
|
|
4222
4347
|
zoneId: zone.id,
|
|
4223
4348
|
name: option(globalCertificate, 1).pipe((r) => r.resourceRecordName),
|
|
4224
4349
|
type: option(globalCertificate, 1).pipe((r) => r.resourceRecordType),
|
|
4225
|
-
ttl: toSeconds2(
|
|
4350
|
+
ttl: toSeconds2(minutes7(5)),
|
|
4226
4351
|
records: [option(globalCertificate, 1).pipe((r) => r.resourceRecordValue)],
|
|
4227
4352
|
allowOverwrite: true
|
|
4228
4353
|
});
|
|
@@ -4248,7 +4373,7 @@ var domainFeature = defineFeature({
|
|
|
4248
4373
|
zoneId: zone.id,
|
|
4249
4374
|
name: `_amazonses.${props.domain}`,
|
|
4250
4375
|
type: "TXT",
|
|
4251
|
-
ttl: toSeconds2(
|
|
4376
|
+
ttl: toSeconds2(minutes7(5)),
|
|
4252
4377
|
records: [identity.verificationToken]
|
|
4253
4378
|
});
|
|
4254
4379
|
const dkim = new aws6.ses.DomainDkim(group2, "dkim", {
|
|
@@ -4259,7 +4384,7 @@ var domainFeature = defineFeature({
|
|
|
4259
4384
|
zoneId: zone.id,
|
|
4260
4385
|
type: "CNAME",
|
|
4261
4386
|
name: dkim.dkimTokens.pipe((t) => `${t.at(i)}._domainkey`),
|
|
4262
|
-
ttl: toSeconds2(
|
|
4387
|
+
ttl: toSeconds2(minutes7(5)),
|
|
4263
4388
|
records: [dkim.dkimTokens.pipe((t) => `${t.at(i)}.dkim.amazonses.com`)]
|
|
4264
4389
|
});
|
|
4265
4390
|
}
|
|
@@ -4272,21 +4397,21 @@ var domainFeature = defineFeature({
|
|
|
4272
4397
|
zoneId: zone.id,
|
|
4273
4398
|
name: mailFrom.mailFromDomain,
|
|
4274
4399
|
type: "MX",
|
|
4275
|
-
ttl: toSeconds2(
|
|
4400
|
+
ttl: toSeconds2(minutes7(5)),
|
|
4276
4401
|
records: [`10 feedback-smtp.${ctx.appConfig.region}.amazonses.com`]
|
|
4277
4402
|
});
|
|
4278
4403
|
new aws6.route53.Record(group2, `SPF`, {
|
|
4279
4404
|
zoneId: zone.id,
|
|
4280
4405
|
name: mailFrom.mailFromDomain,
|
|
4281
4406
|
type: "TXT",
|
|
4282
|
-
ttl: toSeconds2(
|
|
4407
|
+
ttl: toSeconds2(minutes7(5)),
|
|
4283
4408
|
records: ["v=spf1 include:amazonses.com -all"]
|
|
4284
4409
|
});
|
|
4285
4410
|
new aws6.route53.Record(group2, `DMARC`, {
|
|
4286
4411
|
zoneId: zone.id,
|
|
4287
4412
|
name: `_dmarc.${props.domain}`,
|
|
4288
4413
|
type: "TXT",
|
|
4289
|
-
ttl: toSeconds2(
|
|
4414
|
+
ttl: toSeconds2(minutes7(5)),
|
|
4290
4415
|
records: ["v=DMARC1; p=none;"]
|
|
4291
4416
|
});
|
|
4292
4417
|
const verification = new aws6.ses.DomainIdentityVerification(
|
|
@@ -4443,8 +4568,8 @@ var functionFeature = defineFeature({
|
|
|
4443
4568
|
});
|
|
4444
4569
|
|
|
4445
4570
|
// src/feature/function/prebuild.ts
|
|
4446
|
-
import { days as
|
|
4447
|
-
import { mebibytes as mebibytes2, toMebibytes as
|
|
4571
|
+
import { days as days6, seconds as seconds5, toDays as toDays6, toSeconds as toSeconds3 } from "@awsless/duration";
|
|
4572
|
+
import { mebibytes as mebibytes2, toMebibytes as toMebibytes4 } from "@awsless/size";
|
|
4448
4573
|
import { aws as aws8 } from "@terraforge/aws";
|
|
4449
4574
|
import { Output as Output4, findInputDeps as findInputDeps2, resolveInputs as resolveInputs2 } from "@terraforge/core";
|
|
4450
4575
|
import { pascalCase as pascalCase2 } from "change-case";
|
|
@@ -4514,9 +4639,9 @@ var createPrebuildLambdaFunction = (group, ctx, ns, id, props) => {
|
|
|
4514
4639
|
const policy = new aws8.iam.RolePolicy(group, "policy", {
|
|
4515
4640
|
role: role.name,
|
|
4516
4641
|
name: "lambda-policy",
|
|
4517
|
-
policy: new Output4(statementDeps, async (
|
|
4642
|
+
policy: new Output4(statementDeps, async (resolve2) => {
|
|
4518
4643
|
const list3 = await resolveInputs2(statements);
|
|
4519
|
-
|
|
4644
|
+
resolve2(
|
|
4520
4645
|
JSON.stringify({
|
|
4521
4646
|
Version: "2012-10-17",
|
|
4522
4647
|
Statement: list3.map((statement) => ({
|
|
@@ -4541,7 +4666,7 @@ var createPrebuildLambdaFunction = (group, ctx, ns, id, props) => {
|
|
|
4541
4666
|
runtime: props.runtime,
|
|
4542
4667
|
handler: props.handler,
|
|
4543
4668
|
timeout: toSeconds3(props.timeout ?? seconds5(10)),
|
|
4544
|
-
memorySize:
|
|
4669
|
+
memorySize: toMebibytes4(props.memorySize ?? mebibytes2(128)),
|
|
4545
4670
|
architectures: [props.architecture ?? "arm64"],
|
|
4546
4671
|
layers: props.layers?.map((id2) => ctx.shared.entry("layer", "arn", id2)),
|
|
4547
4672
|
s3Bucket: code.bucket,
|
|
@@ -4575,7 +4700,7 @@ var createPrebuildLambdaFunction = (group, ctx, ns, id, props) => {
|
|
|
4575
4700
|
if (props.log?.retention && props.log?.retention?.value > 0n) {
|
|
4576
4701
|
const logGroup = new aws8.cloudwatch.LogGroup(group, "log", {
|
|
4577
4702
|
name: `/aws/lambda/${name}`,
|
|
4578
|
-
retentionInDays:
|
|
4703
|
+
retentionInDays: toDays6(props.log.retention ?? days6(7))
|
|
4579
4704
|
});
|
|
4580
4705
|
addPermission({
|
|
4581
4706
|
actions: ["logs:PutLogEvents", "logs:CreateLogStream"],
|
|
@@ -4632,7 +4757,7 @@ import { Group as Group8 } from "@terraforge/core";
|
|
|
4632
4757
|
import { aws as aws9 } from "@terraforge/aws";
|
|
4633
4758
|
import { join as join10 } from "path";
|
|
4634
4759
|
import { mebibytes as mebibytes3 } from "@awsless/size";
|
|
4635
|
-
import { days as
|
|
4760
|
+
import { days as days7, seconds as seconds6 } from "@awsless/duration";
|
|
4636
4761
|
var onErrorLogFeature = defineFeature({
|
|
4637
4762
|
name: "on-error-log",
|
|
4638
4763
|
onApp(ctx) {
|
|
@@ -4647,7 +4772,7 @@ var onErrorLogFeature = defineFeature({
|
|
|
4647
4772
|
log: {
|
|
4648
4773
|
format: "json",
|
|
4649
4774
|
level: "warn",
|
|
4650
|
-
retention:
|
|
4775
|
+
retention: days7(3),
|
|
4651
4776
|
system: "warn"
|
|
4652
4777
|
}
|
|
4653
4778
|
});
|
|
@@ -4704,7 +4829,7 @@ import { Group as Group9 } from "@terraforge/core";
|
|
|
4704
4829
|
import { aws as aws10 } from "@terraforge/aws";
|
|
4705
4830
|
import { join as join11 } from "path";
|
|
4706
4831
|
import { mebibytes as mebibytes4 } from "@awsless/size";
|
|
4707
|
-
import { days as
|
|
4832
|
+
import { days as days8, toSeconds as toSeconds4 } from "@awsless/duration";
|
|
4708
4833
|
var onFailureFeature = defineFeature({
|
|
4709
4834
|
name: "on-failure",
|
|
4710
4835
|
onApp(ctx) {
|
|
@@ -4715,7 +4840,7 @@ var onFailureFeature = defineFeature({
|
|
|
4715
4840
|
resourceType: "on-failure",
|
|
4716
4841
|
resourceName: "deadletter"
|
|
4717
4842
|
}),
|
|
4718
|
-
messageRetentionSeconds: toSeconds4(
|
|
4843
|
+
messageRetentionSeconds: toSeconds4(days8(14))
|
|
4719
4844
|
});
|
|
4720
4845
|
const queue2 = new aws10.sqs.Queue(group, "on-failure", {
|
|
4721
4846
|
name: formatGlobalResourceName({
|
|
@@ -4863,7 +4988,7 @@ var onFailureFeature = defineFeature({
|
|
|
4863
4988
|
log: {
|
|
4864
4989
|
format: "json",
|
|
4865
4990
|
level: "warn",
|
|
4866
|
-
retention:
|
|
4991
|
+
retention: days8(3),
|
|
4867
4992
|
system: "warn"
|
|
4868
4993
|
}
|
|
4869
4994
|
});
|
|
@@ -4961,7 +5086,7 @@ var formatFullDomainName = (config2, id, subDomain) => {
|
|
|
4961
5086
|
};
|
|
4962
5087
|
|
|
4963
5088
|
// src/feature/pubsub/index.ts
|
|
4964
|
-
import { minutes as
|
|
5089
|
+
import { minutes as minutes8, toSeconds as toSeconds5 } from "@awsless/duration";
|
|
4965
5090
|
var pubsubFeature = defineFeature({
|
|
4966
5091
|
name: "pubsub",
|
|
4967
5092
|
onApp(ctx) {
|
|
@@ -5012,7 +5137,7 @@ var pubsubFeature = defineFeature({
|
|
|
5012
5137
|
zoneId: ctx.shared.entry("domain", `zone-id`, props.domain),
|
|
5013
5138
|
name: domainName,
|
|
5014
5139
|
type: "CNAME",
|
|
5015
|
-
ttl: toSeconds5(
|
|
5140
|
+
ttl: toSeconds5(minutes8(5)),
|
|
5016
5141
|
records: [endpoint.endpointAddress]
|
|
5017
5142
|
});
|
|
5018
5143
|
ctx.bind(`PUBSUB_${constantCase5(id)}_ENDPOINT`, domainName);
|
|
@@ -6762,7 +6887,7 @@ import { Group as Group23 } from "@terraforge/core";
|
|
|
6762
6887
|
import { aws as aws24 } from "@terraforge/aws";
|
|
6763
6888
|
import { join as join15, dirname as dirname7 } from "path";
|
|
6764
6889
|
import { mebibytes as mebibytes6 } from "@awsless/size";
|
|
6765
|
-
import { seconds as seconds8, toDays as
|
|
6890
|
+
import { seconds as seconds8, toDays as toDays7 } from "@awsless/duration";
|
|
6766
6891
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
6767
6892
|
import { glob as glob4 } from "glob";
|
|
6768
6893
|
var __dirname3 = dirname7(fileURLToPath2(import.meta.url));
|
|
@@ -6853,7 +6978,7 @@ var imageFeature = defineFeature({
|
|
|
6853
6978
|
enabled: true,
|
|
6854
6979
|
id: "image-cache-duration",
|
|
6855
6980
|
expiration: {
|
|
6856
|
-
days:
|
|
6981
|
+
days: toDays7(props.cacheDuration)
|
|
6857
6982
|
}
|
|
6858
6983
|
}
|
|
6859
6984
|
]
|
|
@@ -6959,7 +7084,7 @@ import { Group as Group24 } from "@terraforge/core";
|
|
|
6959
7084
|
import { aws as aws25 } from "@terraforge/aws";
|
|
6960
7085
|
import { join as join16, dirname as dirname8 } from "path";
|
|
6961
7086
|
import { mebibytes as mebibytes7 } from "@awsless/size";
|
|
6962
|
-
import { seconds as seconds9, toDays as
|
|
7087
|
+
import { seconds as seconds9, toDays as toDays8 } from "@awsless/duration";
|
|
6963
7088
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
6964
7089
|
import { glob as glob5 } from "glob";
|
|
6965
7090
|
var __dirname4 = dirname8(fileURLToPath3(import.meta.url));
|
|
@@ -7004,7 +7129,7 @@ var iconFeature = defineFeature({
|
|
|
7004
7129
|
enabled: true,
|
|
7005
7130
|
id: "icon-cache-duration",
|
|
7006
7131
|
expiration: {
|
|
7007
|
-
days:
|
|
7132
|
+
days: toDays8(props.cacheDuration)
|
|
7008
7133
|
}
|
|
7009
7134
|
}
|
|
7010
7135
|
]
|
|
@@ -7102,31 +7227,42 @@ var iconFeature = defineFeature({
|
|
|
7102
7227
|
}
|
|
7103
7228
|
});
|
|
7104
7229
|
|
|
7105
|
-
// src/feature/
|
|
7106
|
-
import { Group as Group26 } from "@terraforge/core";
|
|
7230
|
+
// src/feature/job/index.ts
|
|
7231
|
+
import { Group as Group26, Output as Output7, resolveInputs as resolveInputs4, findInputDeps as findInputDeps4 } from "@terraforge/core";
|
|
7107
7232
|
import { aws as aws27 } from "@terraforge/aws";
|
|
7233
|
+
import { camelCase as camelCase8 } from "change-case";
|
|
7234
|
+
import { relative as relative8 } from "path";
|
|
7108
7235
|
|
|
7109
|
-
// src/feature/
|
|
7110
|
-
import { toDays as
|
|
7111
|
-
import { toMebibytes as
|
|
7236
|
+
// src/feature/job/util.ts
|
|
7237
|
+
import { toDays as toDays9, toSeconds as toSeconds9 } from "@awsless/duration";
|
|
7238
|
+
import { toMebibytes as toMebibytes5 } from "@awsless/size";
|
|
7112
7239
|
import { generateFileHash as generateFileHash2 } from "@awsless/ts-file-cache";
|
|
7113
7240
|
import { aws as aws26 } from "@terraforge/aws";
|
|
7114
7241
|
import { Group as Group25, Output as Output6, findInputDeps as findInputDeps3, resolveInputs as resolveInputs3 } from "@terraforge/core";
|
|
7115
7242
|
import { constantCase as constantCase12, pascalCase as pascalCase3 } from "change-case";
|
|
7116
7243
|
import deepmerge4 from "deepmerge";
|
|
7117
|
-
import { join as join18 } from "path";
|
|
7118
7244
|
|
|
7119
|
-
// src/feature/
|
|
7245
|
+
// src/feature/job/build/executable.ts
|
|
7120
7246
|
import { createHash as createHash3 } from "crypto";
|
|
7121
|
-
import { readFile as readFile4 } from "fs/promises";
|
|
7122
|
-
import { join as join17 } from "path";
|
|
7123
|
-
var
|
|
7247
|
+
import { readFile as readFile4, writeFile as writeFile3 } from "fs/promises";
|
|
7248
|
+
import { join as join17, resolve } from "path";
|
|
7249
|
+
var buildJobExecutable = async (input, outputPath, architecture) => {
|
|
7124
7250
|
const filePath = join17(outputPath, "program");
|
|
7251
|
+
const wrapperPath = join17(outputPath, "wrapper.ts");
|
|
7252
|
+
const handlerPath = resolve(input);
|
|
7253
|
+
await writeFile3(
|
|
7254
|
+
wrapperPath,
|
|
7255
|
+
[
|
|
7256
|
+
`import handler from '${handlerPath}'`,
|
|
7257
|
+
`const payload = JSON.parse(process.env.PAYLOAD || '{}')`,
|
|
7258
|
+
`await handler(payload)`
|
|
7259
|
+
].join("\n")
|
|
7260
|
+
);
|
|
7125
7261
|
const target = architecture === "x86_64" ? "bun-linux-x64" : "bun-linux-arm64";
|
|
7126
7262
|
let result;
|
|
7127
7263
|
try {
|
|
7128
7264
|
result = await Bun.build({
|
|
7129
|
-
entrypoints: [
|
|
7265
|
+
entrypoints: [wrapperPath],
|
|
7130
7266
|
compile: {
|
|
7131
7267
|
target,
|
|
7132
7268
|
outfile: filePath
|
|
@@ -7135,23 +7271,23 @@ var buildExecutable = async (input, outputPath, architecture) => {
|
|
|
7135
7271
|
});
|
|
7136
7272
|
} catch (error) {
|
|
7137
7273
|
throw new ExpectedError(
|
|
7138
|
-
`
|
|
7274
|
+
`Job executable build failed: ${error instanceof Error ? error.message : JSON.stringify(error)}`
|
|
7139
7275
|
);
|
|
7140
7276
|
}
|
|
7141
7277
|
if (!result.success) {
|
|
7142
|
-
throw new ExpectedError(`
|
|
7278
|
+
throw new ExpectedError(`Job executable build failed:
|
|
7143
7279
|
${result.logs?.map((log35) => log35.message).join("\n")}`);
|
|
7144
7280
|
}
|
|
7145
7281
|
const file = await readFile4(filePath);
|
|
7146
7282
|
return {
|
|
7147
|
-
hash: createHash3("sha1").update(file).update(
|
|
7283
|
+
hash: createHash3("sha1").update(file).update(architecture).digest("hex"),
|
|
7148
7284
|
file
|
|
7149
7285
|
};
|
|
7150
7286
|
};
|
|
7151
7287
|
|
|
7152
|
-
// src/feature/
|
|
7153
|
-
var
|
|
7154
|
-
const group = new Group25(parentGroup, "
|
|
7288
|
+
// src/feature/job/util.ts
|
|
7289
|
+
var createFargateJob = (parentGroup, ctx, ns, id, local) => {
|
|
7290
|
+
const group = new Group25(parentGroup, "job", ns);
|
|
7155
7291
|
const name = formatLocalResourceName({
|
|
7156
7292
|
appName: ctx.app.name,
|
|
7157
7293
|
stackName: ctx.stack.name,
|
|
@@ -7159,13 +7295,13 @@ var createFargateTask = (parentGroup, ctx, ns, id, local) => {
|
|
|
7159
7295
|
resourceName: id
|
|
7160
7296
|
});
|
|
7161
7297
|
const shortName = shortId(`${ctx.app.name}:${ctx.stack.name}:${ns}:${id}:${ctx.appId}`);
|
|
7162
|
-
const props = deepmerge4(ctx.appConfig.defaults.
|
|
7298
|
+
const props = deepmerge4(ctx.appConfig.defaults.job, local);
|
|
7163
7299
|
const image2 = props.image || (props.architecture === "arm64" ? "public.ecr.aws/aws-cli/aws-cli:arm64" : "public.ecr.aws/aws-cli/aws-cli:amd64");
|
|
7164
|
-
ctx.registerBuild("
|
|
7300
|
+
ctx.registerBuild("job", name, async (build3, { workspace }) => {
|
|
7165
7301
|
const fingerprint = await generateFileHash2(workspace, local.code.file);
|
|
7166
7302
|
return build3(fingerprint, async (write) => {
|
|
7167
|
-
const temp = await createTempFolder(`
|
|
7168
|
-
const executable = await
|
|
7303
|
+
const temp = await createTempFolder(`job--${name}`);
|
|
7304
|
+
const executable = await buildJobExecutable(local.code.file, temp.path, props.architecture);
|
|
7169
7305
|
await Promise.all([
|
|
7170
7306
|
//
|
|
7171
7307
|
write("HASH", executable.hash),
|
|
@@ -7178,10 +7314,10 @@ var createFargateTask = (parentGroup, ctx, ns, id, local) => {
|
|
|
7178
7314
|
});
|
|
7179
7315
|
});
|
|
7180
7316
|
const code = new aws26.s3.BucketObject(group, "code", {
|
|
7181
|
-
bucket: ctx.shared.get("
|
|
7317
|
+
bucket: ctx.shared.get("job", "bucket-name"),
|
|
7182
7318
|
key: name,
|
|
7183
|
-
source: relativePath(getBuildPath("
|
|
7184
|
-
sourceHash: $file(getBuildPath("
|
|
7319
|
+
source: relativePath(getBuildPath("job", name, "program")),
|
|
7320
|
+
sourceHash: $file(getBuildPath("job", name, "HASH"))
|
|
7185
7321
|
});
|
|
7186
7322
|
const executionRole = new aws26.iam.Role(group, "execution-role", {
|
|
7187
7323
|
name: shortId(`${shortName}:execution-role`),
|
|
@@ -7245,9 +7381,9 @@ var createFargateTask = (parentGroup, ctx, ns, id, local) => {
|
|
|
7245
7381
|
const policy = new aws26.iam.RolePolicy(group, "policy", {
|
|
7246
7382
|
role: role.name,
|
|
7247
7383
|
name: "task-policy",
|
|
7248
|
-
policy: new Output6(statementDeps, async (
|
|
7384
|
+
policy: new Output6(statementDeps, async (resolve2) => {
|
|
7249
7385
|
const list3 = await resolveInputs3(statements);
|
|
7250
|
-
|
|
7386
|
+
resolve2(
|
|
7251
7387
|
JSON.stringify({
|
|
7252
7388
|
Version: "2012-10-17",
|
|
7253
7389
|
Statement: list3.map((statement) => ({
|
|
@@ -7272,8 +7408,7 @@ var createFargateTask = (parentGroup, ctx, ns, id, local) => {
|
|
|
7272
7408
|
if (props.log.retention && props.log.retention.value > 0n) {
|
|
7273
7409
|
logGroup = new aws26.cloudwatch.LogGroup(group, "log", {
|
|
7274
7410
|
name: `/aws/ecs/${name}`,
|
|
7275
|
-
|
|
7276
|
-
retentionInDays: toDays8(props.log.retention)
|
|
7411
|
+
retentionInDays: toDays9(props.log.retention)
|
|
7277
7412
|
});
|
|
7278
7413
|
if (ctx.shared.has("on-error-log", "subscriber-arn")) {
|
|
7279
7414
|
new aws26.cloudwatch.LogSubscriptionFilter(group, "on-error-log", {
|
|
@@ -7298,7 +7433,7 @@ var createFargateTask = (parentGroup, ctx, ns, id, local) => {
|
|
|
7298
7433
|
family: name,
|
|
7299
7434
|
networkMode: "awsvpc",
|
|
7300
7435
|
cpu: props.cpu,
|
|
7301
|
-
memory:
|
|
7436
|
+
memory: toMebibytes5(props.memorySize).toString(),
|
|
7302
7437
|
requiresCompatibilities: ["FARGATE"],
|
|
7303
7438
|
executionRoleArn: executionRole.arn,
|
|
7304
7439
|
taskRoleArn: role.arn,
|
|
@@ -7307,13 +7442,13 @@ var createFargateTask = (parentGroup, ctx, ns, id, local) => {
|
|
|
7307
7442
|
operatingSystemFamily: "LINUX"
|
|
7308
7443
|
},
|
|
7309
7444
|
trackLatest: true,
|
|
7310
|
-
containerDefinitions: new Output6(variableDeps, async (
|
|
7445
|
+
containerDefinitions: new Output6(variableDeps, async (resolve2) => {
|
|
7311
7446
|
const data = await resolveInputs3(variables);
|
|
7312
7447
|
const { s3Bucket, s3Key } = await resolveInputs3({
|
|
7313
7448
|
s3Bucket: code.bucket,
|
|
7314
7449
|
s3Key: code.key
|
|
7315
7450
|
});
|
|
7316
|
-
|
|
7451
|
+
resolve2(
|
|
7317
7452
|
JSON.stringify([
|
|
7318
7453
|
{
|
|
7319
7454
|
name: `container-${id}`,
|
|
@@ -7326,50 +7461,25 @@ var createFargateTask = (parentGroup, ctx, ns, id, local) => {
|
|
|
7326
7461
|
[
|
|
7327
7462
|
`aws s3 cp s3://${s3Bucket}/${s3Key} /usr/app/program`,
|
|
7328
7463
|
`chmod +x /usr/app/program`,
|
|
7329
|
-
|
|
7464
|
+
...props.startupCommand ?? [],
|
|
7465
|
+
`exec timeout ${toSeconds9(props.timeout)} /usr/app/program`
|
|
7330
7466
|
].join(" && ")
|
|
7331
7467
|
],
|
|
7332
7468
|
environment: Object.entries(data).map(([name2, value]) => ({
|
|
7333
7469
|
name: name2,
|
|
7334
7470
|
value
|
|
7335
7471
|
})),
|
|
7336
|
-
portMappings: [
|
|
7337
|
-
{
|
|
7338
|
-
name: "http",
|
|
7339
|
-
protocol: "tcp",
|
|
7340
|
-
appProtocol: "http",
|
|
7341
|
-
containerPort: 80,
|
|
7342
|
-
hostPort: 80
|
|
7343
|
-
}
|
|
7344
|
-
],
|
|
7345
|
-
restartPolicy: {
|
|
7346
|
-
enabled: true,
|
|
7347
|
-
restartAttemptPeriod: 60
|
|
7348
|
-
},
|
|
7349
7472
|
...logGroup && {
|
|
7350
7473
|
logConfiguration: {
|
|
7351
7474
|
logDriver: "awslogs",
|
|
7352
7475
|
options: {
|
|
7353
|
-
|
|
7354
|
-
"awslogs-group": `/aws/lambda/${name}`,
|
|
7476
|
+
"awslogs-group": `/aws/ecs/${name}`,
|
|
7355
7477
|
"awslogs-region": ctx.appConfig.region,
|
|
7356
7478
|
"awslogs-stream-prefix": "ecs",
|
|
7357
7479
|
mode: "non-blocking"
|
|
7358
|
-
// 'awslogs-multiline-pattern': '',
|
|
7359
|
-
// 'max-buffer-size': '100m',
|
|
7360
7480
|
}
|
|
7361
7481
|
}
|
|
7362
|
-
}
|
|
7363
|
-
healthCheck: props.healthCheck ? {
|
|
7364
|
-
command: [
|
|
7365
|
-
"CMD-SHELL",
|
|
7366
|
-
`curl -f http://${join18("localhost", props.healthCheck.path)} || exit 1`
|
|
7367
|
-
],
|
|
7368
|
-
interval: toSeconds9(props.healthCheck.interval),
|
|
7369
|
-
retries: props.healthCheck.retries,
|
|
7370
|
-
startPeriod: toSeconds9(props.healthCheck.startPeriod),
|
|
7371
|
-
timeout: toSeconds9(props.healthCheck.timeout)
|
|
7372
|
-
} : void 0
|
|
7482
|
+
}
|
|
7373
7483
|
}
|
|
7374
7484
|
])
|
|
7375
7485
|
);
|
|
@@ -7388,52 +7498,506 @@ var createFargateTask = (parentGroup, ctx, ns, id, local) => {
|
|
|
7388
7498
|
dependsOn: [code]
|
|
7389
7499
|
}
|
|
7390
7500
|
);
|
|
7391
|
-
|
|
7392
|
-
|
|
7393
|
-
|
|
7394
|
-
|
|
7395
|
-
|
|
7396
|
-
tags
|
|
7397
|
-
});
|
|
7398
|
-
new aws26.vpc.SecurityGroupEgressRule(group, "egress-rule", {
|
|
7399
|
-
securityGroupId: securityGroup.id,
|
|
7400
|
-
description: `Allow all outbound traffic from the ${name} instance`,
|
|
7401
|
-
ipProtocol: "-1",
|
|
7402
|
-
cidrIpv4: "0.0.0.0/0",
|
|
7403
|
-
tags
|
|
7501
|
+
ctx.onEnv((name2, value) => {
|
|
7502
|
+
variables[name2] = value;
|
|
7503
|
+
for (const dep of findInputDeps3([value])) {
|
|
7504
|
+
variableDeps.add(dep);
|
|
7505
|
+
}
|
|
7404
7506
|
});
|
|
7405
|
-
|
|
7406
|
-
|
|
7407
|
-
|
|
7408
|
-
|
|
7409
|
-
|
|
7410
|
-
|
|
7411
|
-
|
|
7412
|
-
|
|
7413
|
-
|
|
7414
|
-
|
|
7415
|
-
|
|
7416
|
-
|
|
7417
|
-
|
|
7418
|
-
|
|
7419
|
-
|
|
7420
|
-
|
|
7421
|
-
|
|
7422
|
-
|
|
7423
|
-
|
|
7424
|
-
|
|
7425
|
-
|
|
7426
|
-
|
|
7427
|
-
|
|
7428
|
-
|
|
7429
|
-
|
|
7430
|
-
|
|
7431
|
-
|
|
7432
|
-
|
|
7507
|
+
variables.APP = ctx.appConfig.name;
|
|
7508
|
+
variables.APP_ID = ctx.appId;
|
|
7509
|
+
variables.AWS_ACCOUNT_ID = ctx.accountId;
|
|
7510
|
+
variables.STACK = ctx.stackConfig.name;
|
|
7511
|
+
variables.CODE_HASH = code.sourceHash;
|
|
7512
|
+
variables.TIMEOUT = toSeconds9(props.timeout).toString();
|
|
7513
|
+
if (props.environment) {
|
|
7514
|
+
for (const [key, value] of Object.entries(props.environment)) {
|
|
7515
|
+
variables[key] = value;
|
|
7516
|
+
}
|
|
7517
|
+
}
|
|
7518
|
+
if (ctx.appConfig.defaults.job.permissions) {
|
|
7519
|
+
statements.push(...ctx.appConfig.defaults.job.permissions);
|
|
7520
|
+
}
|
|
7521
|
+
if ("permissions" in local && local.permissions) {
|
|
7522
|
+
statements.push(...local.permissions);
|
|
7523
|
+
}
|
|
7524
|
+
return { name, task: task2, policy, code, group };
|
|
7525
|
+
};
|
|
7526
|
+
|
|
7527
|
+
// src/feature/job/index.ts
|
|
7528
|
+
var typeGenCode10 = `
|
|
7529
|
+
import type { Mock } from 'vitest'
|
|
7530
|
+
|
|
7531
|
+
type Func = (...args: any[]) => any
|
|
7532
|
+
|
|
7533
|
+
type Invoke<N extends string, F extends Func> = unknown extends Parameters<F>[0] ? InvokeWithoutPayload<N, F> : InvokeWithPayload<N, F>
|
|
7534
|
+
|
|
7535
|
+
type InvokeWithPayload<Name extends string, F extends Func> = {
|
|
7536
|
+
readonly name: Name
|
|
7537
|
+
(payload: Parameters<F>[0]): Promise<{ taskArn: string | undefined }>
|
|
7538
|
+
}
|
|
7539
|
+
|
|
7540
|
+
type InvokeWithoutPayload<Name extends string, F extends Func> = {
|
|
7541
|
+
readonly name: Name
|
|
7542
|
+
(payload?: Parameters<F>[0]): Promise<{ taskArn: string | undefined }>
|
|
7543
|
+
}
|
|
7544
|
+
|
|
7545
|
+
type MockHandle<F extends Func> = (payload: Parameters<F>[0]) => void | Promise<void>
|
|
7546
|
+
type MockBuilder<F extends Func> = (handle?: MockHandle<F>) => void
|
|
7547
|
+
type MockObject<F extends Func> = Mock<Parameters<F>, ReturnType<F>>
|
|
7548
|
+
`;
|
|
7549
|
+
var jobFeature = defineFeature({
|
|
7550
|
+
name: "job",
|
|
7551
|
+
onBefore(ctx) {
|
|
7552
|
+
const group = new Group26(ctx.base, "job", "asset");
|
|
7553
|
+
const bucket = new aws27.s3.Bucket(group, "bucket", {
|
|
7554
|
+
bucket: formatGlobalResourceName({
|
|
7555
|
+
appName: ctx.app.name,
|
|
7556
|
+
resourceType: "job",
|
|
7557
|
+
resourceName: "assets",
|
|
7558
|
+
postfix: ctx.appId
|
|
7559
|
+
}),
|
|
7560
|
+
forceDestroy: true
|
|
7561
|
+
});
|
|
7562
|
+
ctx.shared.set("job", "bucket-name", bucket.bucket);
|
|
7563
|
+
},
|
|
7564
|
+
onApp(ctx) {
|
|
7565
|
+
const found = ctx.stackConfigs.filter((stack) => {
|
|
7566
|
+
return Object.keys(stack.jobs ?? {}).length > 0;
|
|
7567
|
+
});
|
|
7568
|
+
if (found.length === 0) {
|
|
7569
|
+
return;
|
|
7570
|
+
}
|
|
7571
|
+
const group = new Group26(ctx.base, "job", "cluster");
|
|
7572
|
+
const cluster = new aws27.ecs.Cluster(group, "cluster", {
|
|
7573
|
+
name: `${ctx.app.name}-job`
|
|
7574
|
+
});
|
|
7575
|
+
new aws27.ecs.ClusterCapacityProviders(group, "capacity-providers", {
|
|
7576
|
+
clusterName: cluster.name,
|
|
7577
|
+
capacityProviders: ["FARGATE", "FARGATE_SPOT"],
|
|
7578
|
+
defaultCapacityProviderStrategy: [
|
|
7579
|
+
{
|
|
7580
|
+
capacityProvider: "FARGATE_SPOT",
|
|
7581
|
+
weight: 1
|
|
7582
|
+
}
|
|
7583
|
+
]
|
|
7584
|
+
});
|
|
7585
|
+
ctx.shared.set("job", "cluster-name", cluster.name);
|
|
7586
|
+
ctx.shared.set("job", "cluster-arn", cluster.arn);
|
|
7587
|
+
const securityGroup = new aws27.security.Group(group, "security-group", {
|
|
7588
|
+
name: `${ctx.app.name}-job`,
|
|
7589
|
+
description: "Shared security group for jobs",
|
|
7590
|
+
vpcId: ctx.shared.get("vpc", "id"),
|
|
7591
|
+
revokeRulesOnDelete: true,
|
|
7592
|
+
tags: {
|
|
7593
|
+
APP: ctx.appConfig.name
|
|
7594
|
+
}
|
|
7595
|
+
});
|
|
7596
|
+
new aws27.vpc.SecurityGroupEgressRule(group, "egress-rule", {
|
|
7597
|
+
securityGroupId: securityGroup.id,
|
|
7598
|
+
description: "Allow all outbound traffic from jobs",
|
|
7599
|
+
ipProtocol: "-1",
|
|
7600
|
+
cidrIpv4: "0.0.0.0/0",
|
|
7601
|
+
tags: {
|
|
7602
|
+
APP: ctx.appConfig.name
|
|
7603
|
+
}
|
|
7604
|
+
});
|
|
7605
|
+
ctx.shared.set("job", "security-group-id", securityGroup.id);
|
|
7606
|
+
ctx.addGlobalPermission({
|
|
7607
|
+
actions: ["ecs:RunTask", "ecs:DescribeTasks", "ecs:StopTask"],
|
|
7608
|
+
resources: ["*"]
|
|
7609
|
+
});
|
|
7610
|
+
ctx.addGlobalPermission({
|
|
7611
|
+
actions: ["iam:PassRole"],
|
|
7612
|
+
resources: ["*"]
|
|
7613
|
+
});
|
|
7614
|
+
},
|
|
7615
|
+
onStack(ctx) {
|
|
7616
|
+
if (!ctx.shared.has("job", "security-group-id")) return;
|
|
7617
|
+
const subnets = ctx.shared.get("vpc", "public-subnets");
|
|
7618
|
+
ctx.addEnv(
|
|
7619
|
+
"JOB_SUBNETS",
|
|
7620
|
+
new Output7(new Set(findInputDeps4(subnets)), async (resolve2) => {
|
|
7621
|
+
const resolved = await resolveInputs4(subnets);
|
|
7622
|
+
resolve2(JSON.stringify(resolved));
|
|
7623
|
+
})
|
|
7624
|
+
);
|
|
7625
|
+
ctx.addEnv("JOB_SECURITY_GROUP", ctx.shared.get("job", "security-group-id"));
|
|
7626
|
+
for (const [id, props] of Object.entries(ctx.stackConfig.jobs ?? {})) {
|
|
7627
|
+
const group = new Group26(ctx.stack, "job", id);
|
|
7628
|
+
createFargateJob(group, ctx, "job", id, props);
|
|
7629
|
+
}
|
|
7630
|
+
},
|
|
7631
|
+
async onTypeGen(ctx) {
|
|
7632
|
+
const types2 = new TypeFile("@awsless/awsless");
|
|
7633
|
+
const resources2 = new TypeObject(1);
|
|
7634
|
+
const mocks = new TypeObject(1);
|
|
7635
|
+
const mockResponses = new TypeObject(1);
|
|
7636
|
+
for (const stack of ctx.stackConfigs) {
|
|
7637
|
+
const resource = new TypeObject(2);
|
|
7638
|
+
const mock = new TypeObject(2);
|
|
7639
|
+
const mockResponse = new TypeObject(2);
|
|
7640
|
+
for (const [name, props] of Object.entries(stack.jobs || {})) {
|
|
7641
|
+
const varName = camelCase8(`${stack.name}-${name}`);
|
|
7642
|
+
const funcName = formatLocalResourceName({
|
|
7643
|
+
appName: ctx.appConfig.name,
|
|
7644
|
+
stackName: stack.name,
|
|
7645
|
+
resourceType: "job",
|
|
7646
|
+
resourceName: name
|
|
7647
|
+
});
|
|
7648
|
+
if ("file" in props.code) {
|
|
7649
|
+
const relFile = relative8(directories.types, props.code.file);
|
|
7650
|
+
types2.addImport(varName, relFile);
|
|
7651
|
+
resource.addType(name, `Invoke<'${funcName}', typeof ${varName}>`);
|
|
7652
|
+
mock.addType(name, `MockBuilder<typeof ${varName}>`);
|
|
7653
|
+
mockResponse.addType(name, `MockObject<typeof ${varName}>`);
|
|
7654
|
+
}
|
|
7655
|
+
}
|
|
7656
|
+
mocks.addType(stack.name, mock);
|
|
7657
|
+
resources2.addType(stack.name, resource);
|
|
7658
|
+
mockResponses.addType(stack.name, mockResponse);
|
|
7659
|
+
}
|
|
7660
|
+
types2.addCode(typeGenCode10);
|
|
7661
|
+
types2.addInterface("JobResources", resources2);
|
|
7662
|
+
types2.addInterface("JobMock", mocks);
|
|
7663
|
+
types2.addInterface("JobMockResponse", mockResponses);
|
|
7664
|
+
await ctx.write("job.d.ts", types2, true);
|
|
7665
|
+
}
|
|
7666
|
+
});
|
|
7667
|
+
|
|
7668
|
+
// src/feature/instance/index.ts
|
|
7669
|
+
import { Group as Group28 } from "@terraforge/core";
|
|
7670
|
+
import { aws as aws29 } from "@terraforge/aws";
|
|
7671
|
+
|
|
7672
|
+
// src/feature/instance/util.ts
|
|
7673
|
+
import { toDays as toDays10, toSeconds as toSeconds10 } from "@awsless/duration";
|
|
7674
|
+
import { toMebibytes as toMebibytes6 } from "@awsless/size";
|
|
7675
|
+
import { generateFileHash as generateFileHash3 } from "@awsless/ts-file-cache";
|
|
7676
|
+
import { aws as aws28 } from "@terraforge/aws";
|
|
7677
|
+
import { Group as Group27, Output as Output8, findInputDeps as findInputDeps5, resolveInputs as resolveInputs5 } from "@terraforge/core";
|
|
7678
|
+
import { constantCase as constantCase13, pascalCase as pascalCase4 } from "change-case";
|
|
7679
|
+
import deepmerge5 from "deepmerge";
|
|
7680
|
+
import { join as join19 } from "path";
|
|
7681
|
+
|
|
7682
|
+
// src/feature/instance/build/executable.ts
|
|
7683
|
+
import { createHash as createHash4 } from "crypto";
|
|
7684
|
+
import { readFile as readFile5 } from "fs/promises";
|
|
7685
|
+
import { join as join18 } from "path";
|
|
7686
|
+
var buildExecutable = async (input, outputPath, architecture) => {
|
|
7687
|
+
const filePath = join18(outputPath, "program");
|
|
7688
|
+
const target = architecture === "x86_64" ? "bun-linux-x64" : "bun-linux-arm64";
|
|
7689
|
+
let result;
|
|
7690
|
+
try {
|
|
7691
|
+
result = await Bun.build({
|
|
7692
|
+
entrypoints: [input],
|
|
7693
|
+
compile: {
|
|
7694
|
+
target,
|
|
7695
|
+
outfile: filePath
|
|
7696
|
+
},
|
|
7697
|
+
target: "bun"
|
|
7698
|
+
});
|
|
7699
|
+
} catch (error) {
|
|
7700
|
+
throw new ExpectedError(
|
|
7701
|
+
`Executable build failed: ${error instanceof Error ? error.message : JSON.stringify(error)}`
|
|
7702
|
+
);
|
|
7703
|
+
}
|
|
7704
|
+
if (!result.success) {
|
|
7705
|
+
throw new ExpectedError(`Executable build failed:
|
|
7706
|
+
${result.logs?.map((log35) => log35.message).join("\n")}`);
|
|
7707
|
+
}
|
|
7708
|
+
const file = await readFile5(filePath);
|
|
7709
|
+
return {
|
|
7710
|
+
hash: createHash4("sha1").update(file).update("x86_64").digest("hex"),
|
|
7711
|
+
file
|
|
7712
|
+
};
|
|
7713
|
+
};
|
|
7714
|
+
|
|
7715
|
+
// src/feature/instance/util.ts
|
|
7716
|
+
var createFargateTask = (parentGroup, ctx, ns, id, local) => {
|
|
7717
|
+
const group = new Group27(parentGroup, "instance", ns);
|
|
7718
|
+
const name = formatLocalResourceName({
|
|
7719
|
+
appName: ctx.app.name,
|
|
7720
|
+
stackName: ctx.stack.name,
|
|
7721
|
+
resourceType: ns,
|
|
7722
|
+
resourceName: id
|
|
7723
|
+
});
|
|
7724
|
+
const shortName = shortId(`${ctx.app.name}:${ctx.stack.name}:${ns}:${id}:${ctx.appId}`);
|
|
7725
|
+
const props = deepmerge5(ctx.appConfig.defaults.instance, local);
|
|
7726
|
+
const image2 = props.image || (props.architecture === "arm64" ? "public.ecr.aws/aws-cli/aws-cli:arm64" : "public.ecr.aws/aws-cli/aws-cli:amd64");
|
|
7727
|
+
ctx.registerBuild("instance", name, async (build3, { workspace }) => {
|
|
7728
|
+
const fingerprint = await generateFileHash3(workspace, local.code.file);
|
|
7729
|
+
return build3(fingerprint, async (write) => {
|
|
7730
|
+
const temp = await createTempFolder(`instance--${name}`);
|
|
7731
|
+
const executable = await buildExecutable(local.code.file, temp.path, props.architecture);
|
|
7732
|
+
await Promise.all([
|
|
7733
|
+
//
|
|
7734
|
+
write("HASH", executable.hash),
|
|
7735
|
+
write("program", executable.file),
|
|
7736
|
+
temp.delete()
|
|
7737
|
+
]);
|
|
7738
|
+
return {
|
|
7739
|
+
size: formatByteSize(executable.file.byteLength)
|
|
7740
|
+
};
|
|
7741
|
+
});
|
|
7742
|
+
});
|
|
7743
|
+
const code = new aws28.s3.BucketObject(group, "code", {
|
|
7744
|
+
bucket: ctx.shared.get("instance", "bucket-name"),
|
|
7745
|
+
key: name,
|
|
7746
|
+
source: relativePath(getBuildPath("instance", name, "program")),
|
|
7747
|
+
sourceHash: $file(getBuildPath("instance", name, "HASH"))
|
|
7748
|
+
});
|
|
7749
|
+
const executionRole = new aws28.iam.Role(group, "execution-role", {
|
|
7750
|
+
name: shortId(`${shortName}:execution-role`),
|
|
7751
|
+
description: name,
|
|
7752
|
+
assumeRolePolicy: JSON.stringify({
|
|
7753
|
+
Version: "2012-10-17",
|
|
7754
|
+
Statement: [
|
|
7755
|
+
{
|
|
7756
|
+
Effect: "Allow",
|
|
7757
|
+
Action: "sts:AssumeRole",
|
|
7758
|
+
Principal: {
|
|
7759
|
+
Service: ["ecs-tasks.amazonaws.com"]
|
|
7760
|
+
}
|
|
7761
|
+
}
|
|
7762
|
+
]
|
|
7763
|
+
}),
|
|
7764
|
+
managedPolicyArns: ["arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"]
|
|
7765
|
+
});
|
|
7766
|
+
const role = new aws28.iam.Role(
|
|
7767
|
+
group,
|
|
7768
|
+
"task-role",
|
|
7769
|
+
{
|
|
7770
|
+
name: shortId(`${shortName}:task-role`),
|
|
7771
|
+
description: name,
|
|
7772
|
+
assumeRolePolicy: JSON.stringify({
|
|
7773
|
+
Version: "2012-10-17",
|
|
7774
|
+
Statement: [
|
|
7775
|
+
{
|
|
7776
|
+
Effect: "Allow",
|
|
7777
|
+
Action: "sts:AssumeRole",
|
|
7778
|
+
Principal: {
|
|
7779
|
+
Service: ["ecs-tasks.amazonaws.com"]
|
|
7780
|
+
}
|
|
7781
|
+
}
|
|
7782
|
+
]
|
|
7783
|
+
}),
|
|
7784
|
+
inlinePolicy: [
|
|
7785
|
+
{
|
|
7786
|
+
name: "s3-code-access",
|
|
7787
|
+
policy: $resolve([code.bucket, code.key], (bucket, key) => {
|
|
7788
|
+
return JSON.stringify({
|
|
7789
|
+
Version: "2012-10-17",
|
|
7790
|
+
Statement: [
|
|
7791
|
+
{
|
|
7792
|
+
Effect: pascalCase4("allow"),
|
|
7793
|
+
Action: ["s3:getObject", "s3:HeadObject"],
|
|
7794
|
+
Resource: `arn:aws:s3:::${bucket}/${key}`
|
|
7795
|
+
}
|
|
7796
|
+
]
|
|
7797
|
+
});
|
|
7798
|
+
})
|
|
7799
|
+
}
|
|
7800
|
+
]
|
|
7801
|
+
},
|
|
7802
|
+
{
|
|
7803
|
+
dependsOn: [code]
|
|
7804
|
+
}
|
|
7805
|
+
);
|
|
7806
|
+
const statements = [];
|
|
7807
|
+
const statementDeps = /* @__PURE__ */ new Set();
|
|
7808
|
+
const policy = new aws28.iam.RolePolicy(group, "policy", {
|
|
7809
|
+
role: role.name,
|
|
7810
|
+
name: "task-policy",
|
|
7811
|
+
policy: new Output8(statementDeps, async (resolve2) => {
|
|
7812
|
+
const list3 = await resolveInputs5(statements);
|
|
7813
|
+
resolve2(
|
|
7814
|
+
JSON.stringify({
|
|
7815
|
+
Version: "2012-10-17",
|
|
7816
|
+
Statement: list3.map((statement) => ({
|
|
7817
|
+
Effect: pascalCase4(statement.effect ?? "allow"),
|
|
7818
|
+
Action: statement.actions,
|
|
7819
|
+
Resource: statement.resources
|
|
7820
|
+
}))
|
|
7821
|
+
})
|
|
7822
|
+
);
|
|
7823
|
+
})
|
|
7824
|
+
});
|
|
7825
|
+
const addPermission = (...permissions) => {
|
|
7826
|
+
statements.push(...permissions);
|
|
7827
|
+
for (const dep of findInputDeps5(permissions)) {
|
|
7828
|
+
statementDeps.add(dep);
|
|
7829
|
+
}
|
|
7830
|
+
};
|
|
7831
|
+
ctx.onPermission((statement) => {
|
|
7832
|
+
addPermission(statement);
|
|
7833
|
+
});
|
|
7834
|
+
let logGroup;
|
|
7835
|
+
if (props.log.retention && props.log.retention.value > 0n) {
|
|
7836
|
+
logGroup = new aws28.cloudwatch.LogGroup(group, "log", {
|
|
7837
|
+
name: `/aws/ecs/${name}`,
|
|
7838
|
+
// name: `/aws/lambda/${name}`,
|
|
7839
|
+
retentionInDays: toDays10(props.log.retention)
|
|
7840
|
+
});
|
|
7841
|
+
if (ctx.shared.has("on-error-log", "subscriber-arn")) {
|
|
7842
|
+
new aws28.cloudwatch.LogSubscriptionFilter(group, "on-error-log", {
|
|
7843
|
+
name: "error-log-subscription",
|
|
7844
|
+
destinationArn: ctx.shared.get("on-error-log", "subscriber-arn"),
|
|
7845
|
+
logGroupName: logGroup.name,
|
|
7846
|
+
filterPattern
|
|
7847
|
+
});
|
|
7848
|
+
}
|
|
7849
|
+
}
|
|
7850
|
+
const tags = {
|
|
7851
|
+
APP: ctx.appConfig.name,
|
|
7852
|
+
APP_ID: ctx.appId,
|
|
7853
|
+
STACK: ctx.stackConfig.name
|
|
7854
|
+
};
|
|
7855
|
+
const variables = {};
|
|
7856
|
+
const variableDeps = /* @__PURE__ */ new Set();
|
|
7857
|
+
const task2 = new aws28.ecs.TaskDefinition(
|
|
7858
|
+
group,
|
|
7859
|
+
"task",
|
|
7860
|
+
{
|
|
7861
|
+
family: name,
|
|
7862
|
+
networkMode: "awsvpc",
|
|
7863
|
+
cpu: props.cpu,
|
|
7864
|
+
memory: toMebibytes6(props.memorySize).toString(),
|
|
7865
|
+
requiresCompatibilities: ["FARGATE"],
|
|
7866
|
+
executionRoleArn: executionRole.arn,
|
|
7867
|
+
taskRoleArn: role.arn,
|
|
7868
|
+
runtimePlatform: {
|
|
7869
|
+
cpuArchitecture: constantCase13(props.architecture),
|
|
7870
|
+
operatingSystemFamily: "LINUX"
|
|
7871
|
+
},
|
|
7872
|
+
trackLatest: true,
|
|
7873
|
+
containerDefinitions: new Output8(variableDeps, async (resolve2) => {
|
|
7874
|
+
const data = await resolveInputs5(variables);
|
|
7875
|
+
const { s3Bucket, s3Key } = await resolveInputs5({
|
|
7876
|
+
s3Bucket: code.bucket,
|
|
7877
|
+
s3Key: code.key
|
|
7878
|
+
});
|
|
7879
|
+
resolve2(
|
|
7880
|
+
JSON.stringify([
|
|
7881
|
+
{
|
|
7882
|
+
name: `container-${id}`,
|
|
7883
|
+
essential: true,
|
|
7884
|
+
image: image2,
|
|
7885
|
+
protocol: "tcp",
|
|
7886
|
+
workingDirectory: "/usr/app",
|
|
7887
|
+
entryPoint: ["sh", "-c"],
|
|
7888
|
+
command: [
|
|
7889
|
+
[
|
|
7890
|
+
`aws s3 cp s3://${s3Bucket}/${s3Key} /usr/app/program`,
|
|
7891
|
+
`chmod +x /usr/app/program`,
|
|
7892
|
+
...props.startupCommand ?? [],
|
|
7893
|
+
`exec /usr/app/program`
|
|
7894
|
+
].join(" && ")
|
|
7895
|
+
],
|
|
7896
|
+
environment: Object.entries(data).map(([name2, value]) => ({
|
|
7897
|
+
name: name2,
|
|
7898
|
+
value
|
|
7899
|
+
})),
|
|
7900
|
+
portMappings: [
|
|
7901
|
+
{
|
|
7902
|
+
name: "http",
|
|
7903
|
+
protocol: "tcp",
|
|
7904
|
+
appProtocol: "http",
|
|
7905
|
+
containerPort: 80,
|
|
7906
|
+
hostPort: 80
|
|
7907
|
+
}
|
|
7908
|
+
],
|
|
7909
|
+
restartPolicy: {
|
|
7910
|
+
enabled: true,
|
|
7911
|
+
restartAttemptPeriod: 60
|
|
7912
|
+
},
|
|
7913
|
+
...logGroup && {
|
|
7914
|
+
logConfiguration: {
|
|
7915
|
+
logDriver: "awslogs",
|
|
7916
|
+
options: {
|
|
7917
|
+
// 'awslogs-group': `/aws/ecs/${name}`,
|
|
7918
|
+
"awslogs-group": `/aws/ecs/${name}`,
|
|
7919
|
+
"awslogs-region": ctx.appConfig.region,
|
|
7920
|
+
"awslogs-stream-prefix": "ecs",
|
|
7921
|
+
mode: "non-blocking"
|
|
7922
|
+
// 'awslogs-multiline-pattern': '',
|
|
7923
|
+
// 'max-buffer-size': '100m',
|
|
7924
|
+
}
|
|
7925
|
+
}
|
|
7926
|
+
},
|
|
7927
|
+
healthCheck: props.healthCheck ? {
|
|
7928
|
+
command: [
|
|
7929
|
+
"CMD-SHELL",
|
|
7930
|
+
`curl -f http://${join19("localhost", props.healthCheck.path)} || exit 1`
|
|
7931
|
+
],
|
|
7932
|
+
interval: toSeconds10(props.healthCheck.interval),
|
|
7933
|
+
retries: props.healthCheck.retries,
|
|
7934
|
+
startPeriod: toSeconds10(props.healthCheck.startPeriod),
|
|
7935
|
+
timeout: toSeconds10(props.healthCheck.timeout)
|
|
7936
|
+
} : void 0
|
|
7937
|
+
}
|
|
7938
|
+
])
|
|
7939
|
+
);
|
|
7940
|
+
}),
|
|
7941
|
+
tags
|
|
7942
|
+
},
|
|
7943
|
+
{
|
|
7944
|
+
replaceOnChanges: [
|
|
7945
|
+
"containerDefinitions",
|
|
7946
|
+
"cpu",
|
|
7947
|
+
"memory",
|
|
7948
|
+
"runtimePlatform",
|
|
7949
|
+
"executionRoleArn",
|
|
7950
|
+
"taskRoleArn"
|
|
7951
|
+
],
|
|
7952
|
+
dependsOn: [code]
|
|
7953
|
+
}
|
|
7954
|
+
);
|
|
7955
|
+
const securityGroup = new aws28.security.Group(group, "security-group", {
|
|
7956
|
+
name,
|
|
7957
|
+
description: "Security group for the instance",
|
|
7958
|
+
vpcId: ctx.shared.get("vpc", "id"),
|
|
7959
|
+
revokeRulesOnDelete: true,
|
|
7960
|
+
tags
|
|
7961
|
+
});
|
|
7962
|
+
new aws28.vpc.SecurityGroupEgressRule(group, "egress-rule", {
|
|
7963
|
+
securityGroupId: securityGroup.id,
|
|
7964
|
+
description: `Allow all outbound traffic from the ${name} instance`,
|
|
7965
|
+
ipProtocol: "-1",
|
|
7966
|
+
cidrIpv4: "0.0.0.0/0",
|
|
7967
|
+
tags
|
|
7968
|
+
});
|
|
7969
|
+
const clusterName = ctx.shared.get("instance", "cluster-name");
|
|
7970
|
+
const clusterArn = ctx.shared.get("instance", "cluster-arn");
|
|
7971
|
+
const service = new aws28.ecs.Service(group, "service", {
|
|
7972
|
+
name,
|
|
7973
|
+
cluster: clusterArn,
|
|
7974
|
+
taskDefinition: task2.arn,
|
|
7975
|
+
desiredCount: 1,
|
|
7976
|
+
launchType: "FARGATE",
|
|
7977
|
+
networkConfiguration: {
|
|
7978
|
+
subnets: ctx.shared.get("vpc", "public-subnets"),
|
|
7979
|
+
securityGroups: [securityGroup.id],
|
|
7980
|
+
assignPublicIp: true
|
|
7981
|
+
// https://stackoverflow.com/questions/76398247/cannotpullcontainererror-pull-image-manifest-has-been-retried-5-times-failed
|
|
7982
|
+
},
|
|
7983
|
+
forceNewDeployment: true,
|
|
7984
|
+
forceDelete: true,
|
|
7985
|
+
tags,
|
|
7986
|
+
// ------------------------------------------------------------
|
|
7987
|
+
// Deployment safeguards: keep the service pinned to one running task.
|
|
7988
|
+
schedulingStrategy: "REPLICA",
|
|
7989
|
+
deploymentMaximumPercent: 100,
|
|
7990
|
+
deploymentMinimumHealthyPercent: 0,
|
|
7991
|
+
deploymentCircuitBreaker: {
|
|
7992
|
+
enable: true,
|
|
7993
|
+
rollback: true
|
|
7994
|
+
},
|
|
7995
|
+
// ------------------------------------------------------------
|
|
7996
|
+
// Tag hygiene: let ECS manage and propagate runtime tags automatically.
|
|
7433
7997
|
enableEcsManagedTags: true,
|
|
7434
7998
|
propagateTags: "SERVICE"
|
|
7435
7999
|
});
|
|
7436
|
-
new
|
|
8000
|
+
new aws28.appautoscaling.Target(
|
|
7437
8001
|
group,
|
|
7438
8002
|
"autoscaling-target",
|
|
7439
8003
|
{
|
|
@@ -7452,7 +8016,7 @@ var createFargateTask = (parentGroup, ctx, ns, id, local) => {
|
|
|
7452
8016
|
);
|
|
7453
8017
|
ctx.onEnv((name2, value) => {
|
|
7454
8018
|
variables[name2] = value;
|
|
7455
|
-
for (const dep of
|
|
8019
|
+
for (const dep of findInputDeps5([value])) {
|
|
7456
8020
|
variableDeps.add(dep);
|
|
7457
8021
|
}
|
|
7458
8022
|
});
|
|
@@ -7461,6 +8025,11 @@ var createFargateTask = (parentGroup, ctx, ns, id, local) => {
|
|
|
7461
8025
|
variables.AWS_ACCOUNT_ID = ctx.accountId;
|
|
7462
8026
|
variables.STACK = ctx.stackConfig.name;
|
|
7463
8027
|
variables.CODE_HASH = code.sourceHash;
|
|
8028
|
+
if (props.environment) {
|
|
8029
|
+
for (const [key, value] of Object.entries(props.environment)) {
|
|
8030
|
+
variables[key] = value;
|
|
8031
|
+
}
|
|
8032
|
+
}
|
|
7464
8033
|
if (ctx.appConfig.defaults.instance.permissions) {
|
|
7465
8034
|
statements.push(...ctx.appConfig.defaults.instance.permissions);
|
|
7466
8035
|
}
|
|
@@ -7474,8 +8043,8 @@ var createFargateTask = (parentGroup, ctx, ns, id, local) => {
|
|
|
7474
8043
|
var instanceFeature = defineFeature({
|
|
7475
8044
|
name: "instance",
|
|
7476
8045
|
onBefore(ctx) {
|
|
7477
|
-
const group = new
|
|
7478
|
-
const bucket = new
|
|
8046
|
+
const group = new Group28(ctx.base, "instance", "asset");
|
|
8047
|
+
const bucket = new aws29.s3.Bucket(group, "bucket", {
|
|
7479
8048
|
bucket: formatGlobalResourceName({
|
|
7480
8049
|
appName: ctx.app.name,
|
|
7481
8050
|
resourceType: "instance",
|
|
@@ -7493,8 +8062,8 @@ var instanceFeature = defineFeature({
|
|
|
7493
8062
|
if (found.length === 0) {
|
|
7494
8063
|
return;
|
|
7495
8064
|
}
|
|
7496
|
-
const group = new
|
|
7497
|
-
const cluster = new
|
|
8065
|
+
const group = new Group28(ctx.base, "instance", "cluster");
|
|
8066
|
+
const cluster = new aws29.ecs.Cluster(group, "cluster", {
|
|
7498
8067
|
name: ctx.app.name
|
|
7499
8068
|
});
|
|
7500
8069
|
ctx.shared.set("instance", "cluster-name", cluster.name);
|
|
@@ -7502,18 +8071,18 @@ var instanceFeature = defineFeature({
|
|
|
7502
8071
|
},
|
|
7503
8072
|
onStack(ctx) {
|
|
7504
8073
|
for (const [id, props] of Object.entries(ctx.stackConfig.instances ?? {})) {
|
|
7505
|
-
const group = new
|
|
8074
|
+
const group = new Group28(ctx.stack, "instance", id);
|
|
7506
8075
|
createFargateTask(group, ctx, "instance", id, props);
|
|
7507
8076
|
}
|
|
7508
8077
|
}
|
|
7509
8078
|
});
|
|
7510
8079
|
|
|
7511
8080
|
// src/feature/metric/index.ts
|
|
7512
|
-
import { Group as
|
|
7513
|
-
import { aws as
|
|
7514
|
-
import { kebabCase as kebabCase8, constantCase as
|
|
7515
|
-
import { toSeconds as
|
|
7516
|
-
var
|
|
8081
|
+
import { Group as Group29 } from "@terraforge/core";
|
|
8082
|
+
import { aws as aws30 } from "@terraforge/aws";
|
|
8083
|
+
import { kebabCase as kebabCase8, constantCase as constantCase14 } from "change-case";
|
|
8084
|
+
import { toSeconds as toSeconds11 } from "@awsless/duration";
|
|
8085
|
+
var typeGenCode11 = `
|
|
7517
8086
|
import { type PutDataProps, putData, batchPutData } from '@awsless/cloudwatch'
|
|
7518
8087
|
import { type Duration } from '@awsless/duration'
|
|
7519
8088
|
import { type Size } from '@awsless/size'
|
|
@@ -7561,7 +8130,7 @@ var metricFeature = defineFeature({
|
|
|
7561
8130
|
resources2.addType(stack.name, stackResources);
|
|
7562
8131
|
}
|
|
7563
8132
|
resources2.addType("batch", "Batch");
|
|
7564
|
-
gen.addCode(
|
|
8133
|
+
gen.addCode(typeGenCode11);
|
|
7565
8134
|
gen.addInterface("MetricResources", resources2);
|
|
7566
8135
|
await ctx.write("metric.d.ts", gen, true);
|
|
7567
8136
|
},
|
|
@@ -7578,16 +8147,16 @@ var metricFeature = defineFeature({
|
|
|
7578
8147
|
}
|
|
7579
8148
|
});
|
|
7580
8149
|
for (const [id, props] of Object.entries(ctx.stackConfig.metrics ?? {})) {
|
|
7581
|
-
const group = new
|
|
7582
|
-
ctx.addEnv(`METRIC_${
|
|
8150
|
+
const group = new Group29(ctx.stack, "metric", id);
|
|
8151
|
+
ctx.addEnv(`METRIC_${constantCase14(id)}`, props.type);
|
|
7583
8152
|
for (const alarmId in props.alarms ?? []) {
|
|
7584
|
-
const alarmGroup = new
|
|
8153
|
+
const alarmGroup = new Group29(group, "alarm", alarmId);
|
|
7585
8154
|
const alarmName = kebabCase8(`${id}-${alarmId}`);
|
|
7586
8155
|
const alarmProps = props.alarms[alarmId];
|
|
7587
8156
|
let alarmAction;
|
|
7588
8157
|
let alarmLambda;
|
|
7589
8158
|
if (Array.isArray(alarmProps.trigger)) {
|
|
7590
|
-
const topic = new
|
|
8159
|
+
const topic = new aws30.sns.Topic(alarmGroup, "alarm-trigger", {
|
|
7591
8160
|
name: formatLocalResourceName({
|
|
7592
8161
|
appName: ctx.app.name,
|
|
7593
8162
|
stackName: ctx.stack.name,
|
|
@@ -7597,7 +8166,7 @@ var metricFeature = defineFeature({
|
|
|
7597
8166
|
});
|
|
7598
8167
|
alarmAction = topic.arn;
|
|
7599
8168
|
for (const email of alarmProps.trigger) {
|
|
7600
|
-
new
|
|
8169
|
+
new aws30.sns.TopicSubscription(alarmGroup, email, {
|
|
7601
8170
|
topicArn: topic.arn,
|
|
7602
8171
|
protocol: "email",
|
|
7603
8172
|
endpoint: email
|
|
@@ -7608,7 +8177,7 @@ var metricFeature = defineFeature({
|
|
|
7608
8177
|
alarmLambda = lambda;
|
|
7609
8178
|
alarmAction = lambda.arn;
|
|
7610
8179
|
}
|
|
7611
|
-
const alarm = new
|
|
8180
|
+
const alarm = new aws30.cloudwatch.MetricAlarm(alarmGroup, "alarm", {
|
|
7612
8181
|
namespace,
|
|
7613
8182
|
metricName: kebabCase8(id),
|
|
7614
8183
|
alarmName: formatLocalResourceName({
|
|
@@ -7620,13 +8189,13 @@ var metricFeature = defineFeature({
|
|
|
7620
8189
|
alarmDescription: alarmProps.description,
|
|
7621
8190
|
statistic: alarmProps.where.stat,
|
|
7622
8191
|
threshold: alarmProps.where.value,
|
|
7623
|
-
period:
|
|
8192
|
+
period: toSeconds11(alarmProps.period),
|
|
7624
8193
|
evaluationPeriods: alarmProps.minDataPoints,
|
|
7625
8194
|
comparisonOperator: alarmProps.where.op,
|
|
7626
8195
|
alarmActions: [alarmAction]
|
|
7627
8196
|
});
|
|
7628
8197
|
if (alarmLambda) {
|
|
7629
|
-
new
|
|
8198
|
+
new aws30.lambda.Permission(alarmGroup, "permission", {
|
|
7630
8199
|
action: "lambda:InvokeFunction",
|
|
7631
8200
|
principal: "lambda.alarms.cloudwatch.amazonaws.com",
|
|
7632
8201
|
functionName: alarmLambda.functionName,
|
|
@@ -7639,10 +8208,10 @@ var metricFeature = defineFeature({
|
|
|
7639
8208
|
});
|
|
7640
8209
|
|
|
7641
8210
|
// src/feature/router/index.ts
|
|
7642
|
-
import { days as
|
|
7643
|
-
import { Future, Group as
|
|
7644
|
-
import { aws as
|
|
7645
|
-
import { camelCase as
|
|
8211
|
+
import { days as days9, seconds as seconds10, toSeconds as toSeconds12, years } from "@awsless/duration";
|
|
8212
|
+
import { Future, Group as Group30 } from "@terraforge/core";
|
|
8213
|
+
import { aws as aws31 } from "@terraforge/aws";
|
|
8214
|
+
import { camelCase as camelCase9, constantCase as constantCase15 } from "change-case";
|
|
7646
8215
|
|
|
7647
8216
|
// src/feature/router/router-code.ts
|
|
7648
8217
|
var getViewerRequestFunctionCode = (props) => {
|
|
@@ -7875,18 +8444,18 @@ async function handler(event) {
|
|
|
7875
8444
|
`;
|
|
7876
8445
|
|
|
7877
8446
|
// src/feature/router/index.ts
|
|
7878
|
-
import { createHash as
|
|
8447
|
+
import { createHash as createHash5 } from "crypto";
|
|
7879
8448
|
var routerFeature = defineFeature({
|
|
7880
8449
|
name: "router",
|
|
7881
8450
|
onApp(ctx) {
|
|
7882
8451
|
for (const [id, props] of Object.entries(ctx.appConfig.defaults.router ?? {})) {
|
|
7883
|
-
const group = new
|
|
8452
|
+
const group = new Group30(ctx.base, "router", id);
|
|
7884
8453
|
const name = formatGlobalResourceName({
|
|
7885
8454
|
appName: ctx.app.name,
|
|
7886
8455
|
resourceType: "router",
|
|
7887
8456
|
resourceName: id
|
|
7888
8457
|
});
|
|
7889
|
-
const routeStore = new
|
|
8458
|
+
const routeStore = new aws31.cloudfront.KeyValueStore(group, "routes", {
|
|
7890
8459
|
name,
|
|
7891
8460
|
comment: "Store for routes"
|
|
7892
8461
|
});
|
|
@@ -7916,11 +8485,11 @@ var routerFeature = defineFeature({
|
|
|
7916
8485
|
);
|
|
7917
8486
|
importedRoutes.push(importKeys);
|
|
7918
8487
|
});
|
|
7919
|
-
const cache = new
|
|
8488
|
+
const cache = new aws31.cloudfront.CachePolicy(group, "cache", {
|
|
7920
8489
|
name,
|
|
7921
|
-
minTtl:
|
|
7922
|
-
maxTtl:
|
|
7923
|
-
defaultTtl:
|
|
8490
|
+
minTtl: toSeconds12(seconds10(0)),
|
|
8491
|
+
maxTtl: toSeconds12(days9(365)),
|
|
8492
|
+
defaultTtl: toSeconds12(days9(0)),
|
|
7924
8493
|
parametersInCacheKeyAndForwardedToOrigin: {
|
|
7925
8494
|
enableAcceptEncodingBrotli: true,
|
|
7926
8495
|
enableAcceptEncodingGzip: true,
|
|
@@ -7948,10 +8517,10 @@ var routerFeature = defineFeature({
|
|
|
7948
8517
|
}
|
|
7949
8518
|
}
|
|
7950
8519
|
});
|
|
7951
|
-
const originRequest = new
|
|
8520
|
+
const originRequest = new aws31.cloudfront.OriginRequestPolicy(group, "request", {
|
|
7952
8521
|
name,
|
|
7953
8522
|
headersConfig: {
|
|
7954
|
-
headerBehavior:
|
|
8523
|
+
headerBehavior: camelCase9("all-except"),
|
|
7955
8524
|
headers: {
|
|
7956
8525
|
items: [
|
|
7957
8526
|
"host"
|
|
@@ -7966,11 +8535,11 @@ var routerFeature = defineFeature({
|
|
|
7966
8535
|
queryStringBehavior: "all"
|
|
7967
8536
|
}
|
|
7968
8537
|
});
|
|
7969
|
-
const responseHeaders = new
|
|
8538
|
+
const responseHeaders = new aws31.cloudfront.ResponseHeadersPolicy(group, "response", {
|
|
7970
8539
|
name,
|
|
7971
8540
|
corsConfig: {
|
|
7972
8541
|
originOverride: props.cors?.override ?? true,
|
|
7973
|
-
accessControlMaxAgeSec:
|
|
8542
|
+
accessControlMaxAgeSec: toSeconds12(props.cors?.maxAge ?? years(1)),
|
|
7974
8543
|
accessControlAllowHeaders: { items: props.cors?.headers ?? ["*"] },
|
|
7975
8544
|
accessControlAllowMethods: { items: props.cors?.methods ?? ["ALL"] },
|
|
7976
8545
|
accessControlAllowOrigins: { items: props.cors?.origins ?? ["*"] },
|
|
@@ -7995,7 +8564,7 @@ var routerFeature = defineFeature({
|
|
|
7995
8564
|
strictTransportSecurity: {
|
|
7996
8565
|
override: true,
|
|
7997
8566
|
preload: true,
|
|
7998
|
-
accessControlMaxAgeSec:
|
|
8567
|
+
accessControlMaxAgeSec: toSeconds12(years(1)),
|
|
7999
8568
|
includeSubdomains: true
|
|
8000
8569
|
},
|
|
8001
8570
|
xssProtection: {
|
|
@@ -8005,7 +8574,7 @@ var routerFeature = defineFeature({
|
|
|
8005
8574
|
}
|
|
8006
8575
|
}
|
|
8007
8576
|
});
|
|
8008
|
-
const viewerRequest = new
|
|
8577
|
+
const viewerRequest = new aws31.cloudfront.Function(group, "viewer-request", {
|
|
8009
8578
|
name,
|
|
8010
8579
|
runtime: `cloudfront-js-2.0`,
|
|
8011
8580
|
comment: `Viewer Request - ${name}`,
|
|
@@ -8027,7 +8596,7 @@ var routerFeature = defineFeature({
|
|
|
8027
8596
|
rateBasedStatement: {
|
|
8028
8597
|
limit: wafSettingsConfig.rateLimiter.limit,
|
|
8029
8598
|
aggregateKeyType: "IP",
|
|
8030
|
-
evaluationWindowSec:
|
|
8599
|
+
evaluationWindowSec: toSeconds12(wafSettingsConfig.rateLimiter.window)
|
|
8031
8600
|
}
|
|
8032
8601
|
},
|
|
8033
8602
|
action: {
|
|
@@ -8107,7 +8676,7 @@ var routerFeature = defineFeature({
|
|
|
8107
8676
|
}
|
|
8108
8677
|
let waf;
|
|
8109
8678
|
if (wafRules.length && wafSettingsConfig) {
|
|
8110
|
-
waf = new
|
|
8679
|
+
waf = new aws31.wafv2.WebAcl(group, "waf", {
|
|
8111
8680
|
name: `${name}-wafv2`,
|
|
8112
8681
|
scope: "CLOUDFRONT",
|
|
8113
8682
|
defaultAction: {
|
|
@@ -8117,12 +8686,12 @@ var routerFeature = defineFeature({
|
|
|
8117
8686
|
rule: wafRules,
|
|
8118
8687
|
captchaConfig: {
|
|
8119
8688
|
immunityTimeProperty: {
|
|
8120
|
-
immunityTime:
|
|
8689
|
+
immunityTime: toSeconds12(wafSettingsConfig.captchaImmunityTime)
|
|
8121
8690
|
}
|
|
8122
8691
|
},
|
|
8123
8692
|
challengeConfig: {
|
|
8124
8693
|
immunityTimeProperty: {
|
|
8125
|
-
immunityTime:
|
|
8694
|
+
immunityTime: toSeconds12(wafSettingsConfig.challengeImmunityTime)
|
|
8126
8695
|
}
|
|
8127
8696
|
},
|
|
8128
8697
|
visibilityConfig: {
|
|
@@ -8132,7 +8701,7 @@ var routerFeature = defineFeature({
|
|
|
8132
8701
|
}
|
|
8133
8702
|
});
|
|
8134
8703
|
}
|
|
8135
|
-
const distribution = new
|
|
8704
|
+
const distribution = new aws31.cloudfront.MultitenantDistribution(group, "distribution", {
|
|
8136
8705
|
tags: {
|
|
8137
8706
|
name
|
|
8138
8707
|
},
|
|
@@ -8178,7 +8747,7 @@ var routerFeature = defineFeature({
|
|
|
8178
8747
|
}
|
|
8179
8748
|
return {
|
|
8180
8749
|
errorCode: Number(errorCode),
|
|
8181
|
-
errorCachingMinTtl: item.minTTL ?
|
|
8750
|
+
errorCachingMinTtl: item.minTTL ? toSeconds12(item.minTTL) : void 0,
|
|
8182
8751
|
responseCode: item.statusCode?.toString() ?? errorCode,
|
|
8183
8752
|
responsePagePath: item.path
|
|
8184
8753
|
};
|
|
@@ -8226,11 +8795,11 @@ var routerFeature = defineFeature({
|
|
|
8226
8795
|
{
|
|
8227
8796
|
distributionId: distribution.id,
|
|
8228
8797
|
paths,
|
|
8229
|
-
version: new Future((
|
|
8798
|
+
version: new Future((resolve2) => {
|
|
8230
8799
|
$combine(...versions).then((versions2) => {
|
|
8231
8800
|
const combined = versions2.filter((v) => !!v).sort().join(",");
|
|
8232
|
-
const version =
|
|
8233
|
-
|
|
8801
|
+
const version = createHash5("sha1").update(combined).digest("hex");
|
|
8802
|
+
resolve2(version);
|
|
8234
8803
|
});
|
|
8235
8804
|
})
|
|
8236
8805
|
},
|
|
@@ -8244,10 +8813,10 @@ var routerFeature = defineFeature({
|
|
|
8244
8813
|
const domainName = formatFullDomainName(ctx.appConfig, props.domain, props.subDomain);
|
|
8245
8814
|
const certificateArn = ctx.shared.entry("domain", `global-certificate-arn`, props.domain);
|
|
8246
8815
|
const zoneId = ctx.shared.entry("domain", "zone-id", props.domain);
|
|
8247
|
-
const connectionGroup = new
|
|
8816
|
+
const connectionGroup = new aws31.cloudfront.ConnectionGroup(group, "connection-group", {
|
|
8248
8817
|
name
|
|
8249
8818
|
});
|
|
8250
|
-
new
|
|
8819
|
+
new aws31.cloudfront.DistributionTenant(group, `tenant`, {
|
|
8251
8820
|
name,
|
|
8252
8821
|
enabled: true,
|
|
8253
8822
|
distributionId: distribution.id,
|
|
@@ -8255,7 +8824,7 @@ var routerFeature = defineFeature({
|
|
|
8255
8824
|
domain: [{ domain: domainName }],
|
|
8256
8825
|
customizations: [{ certificate: [{ arn: certificateArn }] }]
|
|
8257
8826
|
});
|
|
8258
|
-
new
|
|
8827
|
+
new aws31.route53.Record(group, `record`, {
|
|
8259
8828
|
zoneId,
|
|
8260
8829
|
type: "A",
|
|
8261
8830
|
name: domainName,
|
|
@@ -8265,7 +8834,7 @@ var routerFeature = defineFeature({
|
|
|
8265
8834
|
evaluateTargetHealth: false
|
|
8266
8835
|
}
|
|
8267
8836
|
});
|
|
8268
|
-
ctx.bind(`ROUTER_${
|
|
8837
|
+
ctx.bind(`ROUTER_${constantCase15(id)}_ENDPOINT`, domainName);
|
|
8269
8838
|
}
|
|
8270
8839
|
}
|
|
8271
8840
|
}
|
|
@@ -8288,6 +8857,7 @@ var features = [
|
|
|
8288
8857
|
// 5
|
|
8289
8858
|
functionFeature,
|
|
8290
8859
|
instanceFeature,
|
|
8860
|
+
jobFeature,
|
|
8291
8861
|
// graphqlFeature,
|
|
8292
8862
|
configFeature,
|
|
8293
8863
|
searchFeature,
|
|
@@ -9376,14 +9946,14 @@ import wildstring4 from "wildstring";
|
|
|
9376
9946
|
|
|
9377
9947
|
// src/cli/ui/complex/run-tests.ts
|
|
9378
9948
|
import { log as log18 } from "@awsless/clui";
|
|
9379
|
-
import { mkdir as mkdir4, readFile as
|
|
9380
|
-
import { join as
|
|
9949
|
+
import { mkdir as mkdir4, readFile as readFile6, writeFile as writeFile4 } from "fs/promises";
|
|
9950
|
+
import { join as join21 } from "path";
|
|
9381
9951
|
import wildstring3 from "wildstring";
|
|
9382
9952
|
import { parse as parse4, stringify } from "@awsless/json";
|
|
9383
9953
|
import { generateFolderHash, loadWorkspace as loadWorkspace2 } from "@awsless/ts-file-cache";
|
|
9384
9954
|
|
|
9385
9955
|
// src/test/start.ts
|
|
9386
|
-
import { dirname as dirname9, join as
|
|
9956
|
+
import { dirname as dirname9, join as join20 } from "path";
|
|
9387
9957
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
9388
9958
|
import { configDefaults } from "vitest/config";
|
|
9389
9959
|
import { startVitest } from "vitest/node";
|
|
@@ -9421,7 +9991,7 @@ var startTest = async (props) => {
|
|
|
9421
9991
|
// },
|
|
9422
9992
|
setupFiles: [
|
|
9423
9993
|
//
|
|
9424
|
-
|
|
9994
|
+
join20(__dirname5, "test-global-setup.js")
|
|
9425
9995
|
]
|
|
9426
9996
|
// globalSetup: [
|
|
9427
9997
|
// //
|
|
@@ -9615,12 +10185,12 @@ var logTestErrors = (event) => {
|
|
|
9615
10185
|
};
|
|
9616
10186
|
var runTest = async (stack, dir, filters, workspace, opts) => {
|
|
9617
10187
|
await mkdir4(directories.test, { recursive: true });
|
|
9618
|
-
const file =
|
|
10188
|
+
const file = join21(directories.test, `${stack}.json`);
|
|
9619
10189
|
const fingerprint = await generateFolderHash(workspace, dir);
|
|
9620
10190
|
if (!process.env.NO_CACHE) {
|
|
9621
10191
|
const exists = await fileExist(file);
|
|
9622
10192
|
if (exists) {
|
|
9623
|
-
const raw = await
|
|
10193
|
+
const raw = await readFile6(file, { encoding: "utf8" });
|
|
9624
10194
|
const data = parse4(raw);
|
|
9625
10195
|
if (data.fingerprint === fingerprint) {
|
|
9626
10196
|
log18.step(
|
|
@@ -9663,7 +10233,7 @@ var runTest = async (stack, dir, filters, workspace, opts) => {
|
|
|
9663
10233
|
logTestLogs(result);
|
|
9664
10234
|
}
|
|
9665
10235
|
logTestErrors(result);
|
|
9666
|
-
await
|
|
10236
|
+
await writeFile4(
|
|
9667
10237
|
file,
|
|
9668
10238
|
stringify({
|
|
9669
10239
|
...result,
|
|
@@ -10203,7 +10773,7 @@ var auth = (program2) => {
|
|
|
10203
10773
|
// src/cli/command/bind.ts
|
|
10204
10774
|
import { log as log24 } from "@awsless/clui";
|
|
10205
10775
|
import chalk4 from "chalk";
|
|
10206
|
-
import { constantCase as
|
|
10776
|
+
import { constantCase as constantCase16 } from "change-case";
|
|
10207
10777
|
var bind = (program2) => {
|
|
10208
10778
|
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 (commands11 = [], opts) => {
|
|
10209
10779
|
await layout("bind", async ({ appConfig, stackConfigs }) => {
|
|
@@ -10230,10 +10800,10 @@ var bind = (program2) => {
|
|
|
10230
10800
|
const configList = opts.config ?? [];
|
|
10231
10801
|
const configs = {};
|
|
10232
10802
|
for (const name of configList) {
|
|
10233
|
-
configs[`CONFIG_${
|
|
10803
|
+
configs[`CONFIG_${constantCase16(name)}`] = name;
|
|
10234
10804
|
}
|
|
10235
10805
|
if (configList.length ?? 0 > 0) {
|
|
10236
|
-
log24.note("Bind Config", configList.map((v) => color.label(
|
|
10806
|
+
log24.note("Bind Config", configList.map((v) => color.label(constantCase16(v))).join("\n"));
|
|
10237
10807
|
}
|
|
10238
10808
|
if (commands11.length === 0) {
|
|
10239
10809
|
return "No command to execute.";
|
|
@@ -10272,7 +10842,7 @@ var bind = (program2) => {
|
|
|
10272
10842
|
|
|
10273
10843
|
// src/config/load/watch.ts
|
|
10274
10844
|
import { watch } from "chokidar";
|
|
10275
|
-
var watchConfig = async (options,
|
|
10845
|
+
var watchConfig = async (options, resolve2, reject) => {
|
|
10276
10846
|
await loadAppConfig(options);
|
|
10277
10847
|
debug("Start watching...");
|
|
10278
10848
|
const ext = "{json,jsonc,json5}";
|
|
@@ -10287,7 +10857,7 @@ var watchConfig = async (options, resolve, reject) => {
|
|
|
10287
10857
|
const appConfig = await loadAppConfig(options);
|
|
10288
10858
|
const stackConfigs = await loadStackConfigs(options);
|
|
10289
10859
|
validateFeatures({ appConfig, stackConfigs });
|
|
10290
|
-
|
|
10860
|
+
resolve2({ appConfig, stackConfigs });
|
|
10291
10861
|
} catch (error) {
|
|
10292
10862
|
reject(error);
|
|
10293
10863
|
}
|
|
@@ -10299,8 +10869,8 @@ var watchConfig = async (options, resolve, reject) => {
|
|
|
10299
10869
|
import { log as log25 } from "@awsless/clui";
|
|
10300
10870
|
|
|
10301
10871
|
// src/type-gen/generate.ts
|
|
10302
|
-
import { mkdir as mkdir5, writeFile as
|
|
10303
|
-
import { dirname as dirname10, join as
|
|
10872
|
+
import { mkdir as mkdir5, writeFile as writeFile5 } from "fs/promises";
|
|
10873
|
+
import { dirname as dirname10, join as join22, relative as relative9 } from "path";
|
|
10304
10874
|
var generateTypes = async (props) => {
|
|
10305
10875
|
const files = [];
|
|
10306
10876
|
await Promise.all(
|
|
@@ -10309,13 +10879,13 @@ var generateTypes = async (props) => {
|
|
|
10309
10879
|
...props,
|
|
10310
10880
|
async write(file, data, include = false) {
|
|
10311
10881
|
const code = data?.toString("utf8");
|
|
10312
|
-
const path =
|
|
10882
|
+
const path = join22(directories.types, file);
|
|
10313
10883
|
if (code) {
|
|
10314
10884
|
if (include) {
|
|
10315
|
-
files.push(
|
|
10885
|
+
files.push(relative9(directories.root, path));
|
|
10316
10886
|
}
|
|
10317
10887
|
await mkdir5(dirname10(path), { recursive: true });
|
|
10318
|
-
await
|
|
10888
|
+
await writeFile5(path, code);
|
|
10319
10889
|
}
|
|
10320
10890
|
}
|
|
10321
10891
|
});
|
|
@@ -10323,7 +10893,7 @@ var generateTypes = async (props) => {
|
|
|
10323
10893
|
);
|
|
10324
10894
|
if (files.length) {
|
|
10325
10895
|
const code = files.map((file) => `/// <reference path='${file}' />`).join("\n");
|
|
10326
|
-
await
|
|
10896
|
+
await writeFile5(join22(directories.root, `awsless.d.ts`), code);
|
|
10327
10897
|
}
|
|
10328
10898
|
};
|
|
10329
10899
|
|
|
@@ -10347,9 +10917,9 @@ var dev = (program2) => {
|
|
|
10347
10917
|
logError(error);
|
|
10348
10918
|
}
|
|
10349
10919
|
);
|
|
10350
|
-
await new Promise((
|
|
10351
|
-
process.once("exit",
|
|
10352
|
-
process.once("SIGINT",
|
|
10920
|
+
await new Promise((resolve2) => {
|
|
10921
|
+
process.once("exit", resolve2);
|
|
10922
|
+
process.once("SIGINT", resolve2);
|
|
10353
10923
|
});
|
|
10354
10924
|
});
|
|
10355
10925
|
});
|
|
@@ -10749,7 +11319,7 @@ var domain = (program2) => {
|
|
|
10749
11319
|
// src/cli/command/logs.ts
|
|
10750
11320
|
import { CloudWatchLogsClient, StartLiveTailCommand } from "@aws-sdk/client-cloudwatch-logs";
|
|
10751
11321
|
import { log as log30 } from "@awsless/clui";
|
|
10752
|
-
import { aws as
|
|
11322
|
+
import { aws as aws32 } from "@terraforge/aws";
|
|
10753
11323
|
import chalk6 from "chalk";
|
|
10754
11324
|
import chunk2 from "chunk";
|
|
10755
11325
|
import { formatDate } from "date-fns";
|
|
@@ -10772,7 +11342,7 @@ var logs = (program2) => {
|
|
|
10772
11342
|
for (const stack of app.stacks) {
|
|
10773
11343
|
if (filters.find((f) => wildstring7.match(f, stack.name))) {
|
|
10774
11344
|
for (const resource of stack.resources) {
|
|
10775
|
-
if (resource instanceof
|
|
11345
|
+
if (resource instanceof aws32.cloudwatch.LogGroup) {
|
|
10776
11346
|
logGroupArns.push(await resource.arn);
|
|
10777
11347
|
}
|
|
10778
11348
|
}
|