@jaypie/constructs 1.1.60 → 1.1.62-rc.0

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.
@@ -0,0 +1,65 @@
1
+ import { RemovalPolicy, Stack } from "aws-cdk-lib";
2
+ import * as acm from "aws-cdk-lib/aws-certificatemanager";
3
+ import * as cloudfront from "aws-cdk-lib/aws-cloudfront";
4
+ import * as lambda from "aws-cdk-lib/aws-lambda";
5
+ import * as route53 from "aws-cdk-lib/aws-route53";
6
+ import { Construct } from "constructs";
7
+ export interface JaypieDistributionProps extends Omit<cloudfront.DistributionProps, "certificate" | "defaultBehavior"> {
8
+ /**
9
+ * SSL certificate for the CloudFront distribution
10
+ * @default true (creates a new certificate)
11
+ */
12
+ certificate?: boolean | acm.ICertificate;
13
+ /**
14
+ * Override default behavior (optional if handler is provided)
15
+ */
16
+ defaultBehavior?: cloudfront.BehaviorOptions;
17
+ /**
18
+ * The origin handler - can be an IOrigin, IFunctionUrl, or IFunction
19
+ * If IFunction, a FunctionUrl will be created with auth NONE
20
+ */
21
+ handler?: cloudfront.IOrigin | lambda.IFunctionUrl | lambda.IFunction;
22
+ /**
23
+ * The domain name for the distribution
24
+ * @default mergeDomain(CDK_ENV_API_SUBDOMAIN, CDK_ENV_API_HOSTED_ZONE || CDK_ENV_HOSTED_ZONE)
25
+ */
26
+ host?: string;
27
+ /**
28
+ * Invoke mode for Lambda Function URLs
29
+ * @default InvokeMode.BUFFERED
30
+ */
31
+ invokeMode?: lambda.InvokeMode;
32
+ /**
33
+ * Role tag for tagging resources
34
+ * @default CDK.ROLE.HOSTING
35
+ */
36
+ roleTag?: string;
37
+ /**
38
+ * The hosted zone for DNS records
39
+ * @default CDK_ENV_API_HOSTED_ZONE || CDK_ENV_HOSTED_ZONE
40
+ */
41
+ zone?: string | route53.IHostedZone;
42
+ }
43
+ export declare class JaypieDistribution extends Construct implements cloudfront.IDistribution {
44
+ readonly certificate?: acm.ICertificate;
45
+ readonly distribution: cloudfront.Distribution;
46
+ readonly distributionArn: string;
47
+ readonly distributionDomainName: string;
48
+ readonly distributionId: string;
49
+ readonly domainName: string;
50
+ readonly functionUrl?: lambda.FunctionUrl;
51
+ readonly host?: string;
52
+ constructor(scope: Construct, id: string, props: JaypieDistributionProps);
53
+ private isIOrigin;
54
+ private isIFunctionUrl;
55
+ private isIFunction;
56
+ get env(): {
57
+ account: string;
58
+ region: string;
59
+ };
60
+ get stack(): Stack;
61
+ applyRemovalPolicy(policy: RemovalPolicy): void;
62
+ grant(identity: import("aws-cdk-lib/aws-iam").IGrantable, ...actions: string[]): import("aws-cdk-lib/aws-iam").Grant;
63
+ grantCreateInvalidation(identity: import("aws-cdk-lib/aws-iam").IGrantable): import("aws-cdk-lib/aws-iam").Grant;
64
+ get distributionRef(): cloudfront.DistributionReference;
65
+ }
@@ -17,7 +17,7 @@ export interface JaypieEnvSecretProps {
17
17
  export declare class JaypieEnvSecret extends Construct implements ISecret {
18
18
  private readonly _envKey?;
19
19
  private readonly _secret;
20
- constructor(scope: Construct, id: string, props?: JaypieEnvSecretProps);
20
+ constructor(scope: Construct, idOrEnvKey: string, props?: JaypieEnvSecretProps);
21
21
  get stack(): Stack;
22
22
  get env(): {
23
23
  account: string;
@@ -0,0 +1,121 @@
1
+ import { Construct } from "constructs";
2
+ import * as sso from "aws-cdk-lib/aws-sso";
3
+ /**
4
+ * Account categories for SSO group assignments
5
+ */
6
+ export interface JaypieSsoAccountMap {
7
+ development: string[];
8
+ management: string[];
9
+ operations: string[];
10
+ production: string[];
11
+ sandbox: string[];
12
+ security: string[];
13
+ stage: string[];
14
+ }
15
+ /**
16
+ * Mapping of group types to Google Workspace group GUIDs
17
+ */
18
+ export interface JaypieSsoGroupMap {
19
+ administrators: string;
20
+ analysts: string;
21
+ developers: string;
22
+ }
23
+ /**
24
+ * IAM Policy Statement structure for inline policies
25
+ */
26
+ export interface PolicyStatement {
27
+ Effect: "Allow" | "Deny";
28
+ Action: string[] | string;
29
+ Resource: string[] | string;
30
+ Condition?: Record<string, unknown>;
31
+ }
32
+ /**
33
+ * Properties for the JaypieSsoGroups construct
34
+ */
35
+ export interface JaypieSsoGroupsProps {
36
+ /**
37
+ * ARN of the IAM Identity Center instance
38
+ */
39
+ instanceArn: string;
40
+ /**
41
+ * Mapping of account categories to AWS account IDs
42
+ */
43
+ accountMap: JaypieSsoAccountMap;
44
+ /**
45
+ * Mapping of group types to Google Workspace group GUIDs
46
+ */
47
+ groupMap: JaypieSsoGroupMap;
48
+ /**
49
+ * Additional inline policy statements to append to each group's permission set
50
+ * Each group can have its own set of policy statements that will be merged
51
+ * with the default policies.
52
+ */
53
+ inlinePolicyStatements?: {
54
+ administrators?: PolicyStatement[];
55
+ analysts?: PolicyStatement[];
56
+ developers?: PolicyStatement[];
57
+ };
58
+ }
59
+ /**
60
+ * Permission set types with corresponding AWS managed policies
61
+ */
62
+ export declare enum PermissionSetType {
63
+ ADMINISTRATOR = "Administrator",
64
+ ANALYST = "Analyst",
65
+ DEVELOPER = "Developer"
66
+ }
67
+ /**
68
+ * Construct to simplify AWS SSO group management.
69
+ * This construct encapsulates the complexity of creating permission sets
70
+ * and assigning them to groups across multiple AWS accounts.
71
+ */
72
+ export declare class JaypieSsoGroups extends Construct {
73
+ private readonly permissionSets;
74
+ private readonly instanceArn;
75
+ private readonly props;
76
+ constructor(scope: Construct, id: string, props: JaypieSsoGroupsProps);
77
+ /**
78
+ * Creates the Administrator permission set with AdministratorAccess policy
79
+ * and billing access
80
+ */
81
+ private createAdministratorPermissionSet;
82
+ /**
83
+ * Creates the Analyst permission set with ReadOnlyAccess policy
84
+ * and limited write access
85
+ */
86
+ private createAnalystPermissionSet;
87
+ /**
88
+ * Creates the Developer permission set with SystemAdministrator policy
89
+ * and expanded write access
90
+ */
91
+ private createDeveloperPermissionSet;
92
+ /**
93
+ * Gets the permission set for the specified type
94
+ */
95
+ getPermissionSet(type: PermissionSetType): sso.CfnPermissionSet;
96
+ /**
97
+ * Merges default inline policies with additional user-provided policy statements
98
+ *
99
+ * @param defaultPolicy - The default policy object with Version and Statement properties
100
+ * @param additionalStatements - Optional additional policy statements to merge
101
+ * @returns The merged policy object
102
+ */
103
+ private mergeInlinePolicies;
104
+ /**
105
+ * Creates assignments between permission sets, groups, and accounts
106
+ * based on the provided configuration
107
+ */
108
+ private createPermissionSetAssignments;
109
+ /**
110
+ * Assigns Administrator permissions to appropriate accounts
111
+ */
112
+ private assignAdministratorPermissions;
113
+ /**
114
+ * Assigns Analyst permissions to appropriate accounts
115
+ */
116
+ private assignAnalystPermissions;
117
+ /**
118
+ * Assigns Developer permissions to appropriate accounts
119
+ */
120
+ private assignDeveloperPermissions;
121
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ import * as lambda from "aws-cdk-lib/aws-lambda";
2
+ export interface AddDatadogLayerOptions {
3
+ datadogApiKeyArn?: string;
4
+ }
5
+ export declare function addDatadogLayer(lambdaFunction: lambda.Function, options?: AddDatadogLayerOptions): boolean;
@@ -0,0 +1,12 @@
1
+ import { Duration } from "aws-cdk-lib";
2
+ import * as lambda from "aws-cdk-lib/aws-lambda";
3
+ export interface AddParamsAndSecretsOptions {
4
+ paramsAndSecrets?: lambda.ParamsAndSecretsLayerVersion | boolean;
5
+ paramsAndSecretsOptions?: {
6
+ cacheSize?: number;
7
+ logLevel?: lambda.ParamsAndSecretsLogLevel;
8
+ parameterStoreTtl?: Duration;
9
+ secretsManagerTtl?: Duration;
10
+ };
11
+ }
12
+ export declare function addParamsAndSecrets(lambdaFunction: lambda.Function, options?: AddParamsAndSecretsOptions): boolean;
@@ -0,0 +1,5 @@
1
+ export declare function projectEnvName(name: string, opts?: {
2
+ env?: string;
3
+ key?: string;
4
+ nonce?: string;
5
+ }): string;
@@ -0,0 +1,4 @@
1
+ import { Stack } from "aws-cdk-lib";
2
+ export declare function stackTagger(stack: Stack, { name }?: {
3
+ name?: string;
4
+ }): boolean;
@@ -18,14 +18,14 @@ var sqs = require('aws-cdk-lib/aws-sqs');
18
18
  var lambdaEventSources = require('aws-cdk-lib/aws-lambda-event-sources');
19
19
  var awsEvents = require('aws-cdk-lib/aws-events');
20
20
  var awsEventsTargets = require('aws-cdk-lib/aws-events-targets');
21
+ var cloudfront = require('aws-cdk-lib/aws-cloudfront');
22
+ var origins = require('aws-cdk-lib/aws-cloudfront-origins');
21
23
  var awsLogs = require('aws-cdk-lib/aws-logs');
22
24
  var cdkNextjsStandalone = require('cdk-nextjs-standalone');
23
25
  var path = require('path');
24
26
  var awsCloudtrail = require('aws-cdk-lib/aws-cloudtrail');
25
27
  var awsSso = require('aws-cdk-lib/aws-sso');
26
28
  var awsSam = require('aws-cdk-lib/aws-sam');
27
- var cloudfront = require('aws-cdk-lib/aws-cloudfront');
28
- var origins = require('aws-cdk-lib/aws-cloudfront-origins');
29
29
 
30
30
  function _interopNamespaceDefault(e) {
31
31
  var n = Object.create(null);
@@ -56,9 +56,9 @@ var logDestinations__namespace = /*#__PURE__*/_interopNamespaceDefault(logDestin
56
56
  var s3n__namespace = /*#__PURE__*/_interopNamespaceDefault(s3n);
57
57
  var sqs__namespace = /*#__PURE__*/_interopNamespaceDefault(sqs);
58
58
  var lambdaEventSources__namespace = /*#__PURE__*/_interopNamespaceDefault(lambdaEventSources);
59
- var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
60
59
  var cloudfront__namespace = /*#__PURE__*/_interopNamespaceDefault(cloudfront);
61
60
  var origins__namespace = /*#__PURE__*/_interopNamespaceDefault(origins);
61
+ var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
62
62
 
63
63
  const CDK$2 = {
64
64
  ACCOUNT: {
@@ -1659,6 +1659,180 @@ class JaypieDatadogForwarder extends constructs.Construct {
1659
1659
  }
1660
1660
  }
1661
1661
 
1662
+ class JaypieDistribution extends constructs.Construct {
1663
+ constructor(scope, id, props) {
1664
+ super(scope, id);
1665
+ const { certificate: certificateProp = true, handler, host: propsHost, invokeMode = lambda__namespace.InvokeMode.BUFFERED, roleTag = CDK$2.ROLE.HOSTING, zone: propsZone, defaultBehavior: propsDefaultBehavior, ...distributionProps } = props;
1666
+ // Validate environment variables
1667
+ if (process.env.CDK_ENV_API_SUBDOMAIN &&
1668
+ !isValidSubdomain(process.env.CDK_ENV_API_SUBDOMAIN)) {
1669
+ throw new Error("CDK_ENV_API_SUBDOMAIN is not a valid subdomain");
1670
+ }
1671
+ if (process.env.CDK_ENV_API_HOSTED_ZONE &&
1672
+ !isValidHostname$1(process.env.CDK_ENV_API_HOSTED_ZONE)) {
1673
+ throw new Error("CDK_ENV_API_HOSTED_ZONE is not a valid hostname");
1674
+ }
1675
+ if (process.env.CDK_ENV_HOSTED_ZONE &&
1676
+ !isValidHostname$1(process.env.CDK_ENV_HOSTED_ZONE)) {
1677
+ throw new Error("CDK_ENV_HOSTED_ZONE is not a valid hostname");
1678
+ }
1679
+ // Determine host from props or environment
1680
+ let host = propsHost;
1681
+ if (!host) {
1682
+ try {
1683
+ if (process.env.CDK_ENV_API_HOST_NAME) {
1684
+ host = process.env.CDK_ENV_API_HOST_NAME;
1685
+ }
1686
+ else if (process.env.CDK_ENV_API_SUBDOMAIN) {
1687
+ host = mergeDomain(process.env.CDK_ENV_API_SUBDOMAIN, process.env.CDK_ENV_API_HOSTED_ZONE ||
1688
+ process.env.CDK_ENV_HOSTED_ZONE ||
1689
+ "");
1690
+ }
1691
+ }
1692
+ catch {
1693
+ host = undefined;
1694
+ }
1695
+ }
1696
+ if (host && !isValidHostname$1(host)) {
1697
+ throw new Error("Host is not a valid hostname");
1698
+ }
1699
+ this.host = host;
1700
+ // Determine zone from props or environment
1701
+ const zone = propsZone ||
1702
+ process.env.CDK_ENV_API_HOSTED_ZONE ||
1703
+ process.env.CDK_ENV_HOSTED_ZONE;
1704
+ // Resolve the origin from handler
1705
+ // Check order matters: IFunctionUrl before IOrigin (FunctionUrl also has bind method)
1706
+ // IFunction before IFunctionUrl (IFunction doesn't have functionUrlId)
1707
+ let origin;
1708
+ if (handler) {
1709
+ if (this.isIFunction(handler)) {
1710
+ // Create FunctionUrl for the Lambda function
1711
+ const functionUrl = new lambda__namespace.FunctionUrl(this, "FunctionUrl", {
1712
+ function: handler,
1713
+ authType: lambda__namespace.FunctionUrlAuthType.NONE,
1714
+ invokeMode,
1715
+ });
1716
+ this.functionUrl = functionUrl;
1717
+ origin = new origins__namespace.FunctionUrlOrigin(functionUrl);
1718
+ }
1719
+ else if (this.isIFunctionUrl(handler)) {
1720
+ origin = new origins__namespace.FunctionUrlOrigin(handler);
1721
+ }
1722
+ else if (this.isIOrigin(handler)) {
1723
+ origin = handler;
1724
+ }
1725
+ }
1726
+ // Build default behavior
1727
+ let defaultBehavior;
1728
+ if (propsDefaultBehavior) {
1729
+ defaultBehavior = propsDefaultBehavior;
1730
+ }
1731
+ else if (origin) {
1732
+ defaultBehavior = {
1733
+ cachePolicy: cloudfront__namespace.CachePolicy.CACHING_DISABLED,
1734
+ origin,
1735
+ originRequestPolicy: cloudfront__namespace.OriginRequestPolicy.ALL_VIEWER_EXCEPT_HOST_HEADER,
1736
+ viewerProtocolPolicy: cloudfront__namespace.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
1737
+ };
1738
+ }
1739
+ else {
1740
+ throw new Error("Either handler or defaultBehavior must be provided to JaypieDistribution");
1741
+ }
1742
+ // Resolve hosted zone and certificate
1743
+ // Only resolve zone when we need it (for certificate or DNS)
1744
+ let hostedZone;
1745
+ let certificateToUse;
1746
+ if (host && zone && certificateProp !== false) {
1747
+ hostedZone = resolveHostedZone(this, { zone });
1748
+ if (certificateProp === true) {
1749
+ certificateToUse = new acm__namespace.Certificate(this, constructEnvName("Certificate"), {
1750
+ domainName: host,
1751
+ validation: acm__namespace.CertificateValidation.fromDns(hostedZone),
1752
+ });
1753
+ cdk.Tags.of(certificateToUse).add(CDK$2.TAG.ROLE, roleTag);
1754
+ }
1755
+ else if (typeof certificateProp === "object") {
1756
+ certificateToUse = certificateProp;
1757
+ }
1758
+ this.certificate = certificateToUse;
1759
+ }
1760
+ // Create the CloudFront distribution
1761
+ this.distribution = new cloudfront__namespace.Distribution(this, constructEnvName("Distribution"), {
1762
+ defaultBehavior,
1763
+ ...(host && certificateToUse
1764
+ ? {
1765
+ certificate: certificateToUse,
1766
+ domainNames: [host],
1767
+ }
1768
+ : {}),
1769
+ ...distributionProps,
1770
+ });
1771
+ cdk.Tags.of(this.distribution).add(CDK$2.TAG.ROLE, roleTag);
1772
+ this.distributionArn = `arn:aws:cloudfront::${cdk.Stack.of(this).account}:distribution/${this.distribution.distributionId}`;
1773
+ this.distributionDomainName = this.distribution.distributionDomainName;
1774
+ this.distributionId = this.distribution.distributionId;
1775
+ this.domainName = this.distribution.domainName;
1776
+ // Create DNS record if we have host and zone
1777
+ if (host && hostedZone) {
1778
+ const record = new route53__namespace.ARecord(this, "AliasRecord", {
1779
+ recordName: host,
1780
+ target: route53__namespace.RecordTarget.fromAlias(new route53Targets__namespace.CloudFrontTarget(this.distribution)),
1781
+ zone: hostedZone,
1782
+ });
1783
+ cdk.Tags.of(record).add(CDK$2.TAG.ROLE, CDK$2.ROLE.NETWORKING);
1784
+ }
1785
+ }
1786
+ // Type guards for handler types
1787
+ isIOrigin(handler) {
1788
+ return (typeof handler === "object" &&
1789
+ handler !== null &&
1790
+ "bind" in handler &&
1791
+ typeof handler.bind === "function");
1792
+ }
1793
+ isIFunctionUrl(handler) {
1794
+ // FunctionUrl has 'url' property which is the function URL string
1795
+ // IFunction does not have 'url' property
1796
+ return (typeof handler === "object" &&
1797
+ handler !== null &&
1798
+ "url" in handler &&
1799
+ "functionArn" in handler);
1800
+ }
1801
+ isIFunction(handler) {
1802
+ // IFunction has functionArn and functionName but NOT 'url'
1803
+ // (FunctionUrl also has functionArn but also has 'url')
1804
+ return (typeof handler === "object" &&
1805
+ handler !== null &&
1806
+ "functionArn" in handler &&
1807
+ "functionName" in handler &&
1808
+ !("url" in handler));
1809
+ }
1810
+ // Implement IDistribution interface
1811
+ get env() {
1812
+ return {
1813
+ account: cdk.Stack.of(this).account,
1814
+ region: cdk.Stack.of(this).region,
1815
+ };
1816
+ }
1817
+ get stack() {
1818
+ return this.distribution.stack;
1819
+ }
1820
+ applyRemovalPolicy(policy) {
1821
+ this.distribution.applyRemovalPolicy(policy);
1822
+ }
1823
+ grant(identity, ...actions) {
1824
+ return this.distribution.grant(identity, ...actions);
1825
+ }
1826
+ grantCreateInvalidation(identity) {
1827
+ return this.distribution.grantCreateInvalidation(identity);
1828
+ }
1829
+ get distributionRef() {
1830
+ return {
1831
+ distributionId: this.distribution.distributionId,
1832
+ };
1833
+ }
1834
+ }
1835
+
1662
1836
  // It is a consumer if the environment is ephemeral
1663
1837
  function checkEnvIsConsumer(env = process.env) {
1664
1838
  return (env.PROJECT_ENV === CDK$2.ENV.PERSONAL ||
@@ -1690,9 +1864,17 @@ function exportEnvName(name, env = process.env) {
1690
1864
  return cleanName(rawName);
1691
1865
  }
1692
1866
  class JaypieEnvSecret extends constructs.Construct {
1693
- constructor(scope, id, props) {
1867
+ constructor(scope, idOrEnvKey, props) {
1868
+ // Check if idOrEnvKey should be treated as envKey:
1869
+ // - No props provided OR props.envKey is not set
1870
+ // - AND idOrEnvKey exists as a non-empty string in process.env
1871
+ const treatAsEnvKey = (!props || props.envKey === undefined) &&
1872
+ typeof process.env[idOrEnvKey] === "string" &&
1873
+ process.env[idOrEnvKey] !== "";
1874
+ const id = treatAsEnvKey ? `EnvSecret_${idOrEnvKey}` : idOrEnvKey;
1694
1875
  super(scope, id);
1695
- const { consumer = checkEnvIsConsumer(), envKey, export: exportParam, generateSecretString, provider = checkEnvIsProvider(), roleTag, vendorTag, value, } = props || {};
1876
+ const { consumer = checkEnvIsConsumer(), envKey: envKeyProp, export: exportParam, generateSecretString, provider = checkEnvIsProvider(), roleTag, vendorTag, value, } = props || {};
1877
+ const envKey = treatAsEnvKey ? idOrEnvKey : envKeyProp;
1696
1878
  this._envKey = envKey;
1697
1879
  let exportName;
1698
1880
  if (!exportParam) {
@@ -3012,6 +3194,7 @@ exports.JaypieBucketQueuedLambda = JaypieBucketQueuedLambda;
3012
3194
  exports.JaypieDatadogBucket = JaypieDatadogBucket;
3013
3195
  exports.JaypieDatadogForwarder = JaypieDatadogForwarder;
3014
3196
  exports.JaypieDatadogSecret = JaypieDatadogSecret;
3197
+ exports.JaypieDistribution = JaypieDistribution;
3015
3198
  exports.JaypieDnsRecord = JaypieDnsRecord;
3016
3199
  exports.JaypieEnvSecret = JaypieEnvSecret;
3017
3200
  exports.JaypieEventsRule = JaypieEventsRule;