@jaypie/constructs 1.2.58 → 1.2.59
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/cjs/JaypieEnvSecret.d.ts +10 -35
- package/dist/cjs/JaypieLambda.d.ts +3 -2
- package/dist/cjs/JaypieNextJs.d.ts +2 -2
- package/dist/cjs/JaypieSecret.d.ts +59 -0
- package/dist/cjs/__tests__/JaypieSecret.spec.d.ts +1 -0
- package/dist/cjs/helpers/resolveSecrets.d.ts +10 -10
- package/dist/cjs/index.cjs +178 -104
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.ts +1 -0
- package/dist/esm/JaypieEnvSecret.d.ts +10 -35
- package/dist/esm/JaypieLambda.d.ts +3 -2
- package/dist/esm/JaypieNextJs.d.ts +2 -2
- package/dist/esm/JaypieSecret.d.ts +59 -0
- package/dist/esm/__tests__/JaypieSecret.spec.d.ts +1 -0
- package/dist/esm/helpers/resolveSecrets.d.ts +10 -10
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +179 -106
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cjs/index.d.ts
CHANGED
|
@@ -24,6 +24,7 @@ export { DomainNameConfig, JaypieNextJs, JaypieNextjsProps, } from "./JaypieNext
|
|
|
24
24
|
export { JaypieOpenAiSecret } from "./JaypieOpenAiSecret";
|
|
25
25
|
export { JaypieOrganizationTrail, JaypieOrganizationTrailProps, } from "./JaypieOrganizationTrail";
|
|
26
26
|
export { JaypieQueuedLambda } from "./JaypieQueuedLambda";
|
|
27
|
+
export { JaypieSecret, JaypieSecretProps } from "./JaypieSecret";
|
|
27
28
|
export { AccountAssignments, JaypieSsoPermissions, JaypieSsoPermissionsProps, } from "./JaypieSsoPermissions";
|
|
28
29
|
export { JaypieSsoSyncApplication, JaypieSsoSyncApplicationProps, } from "./JaypieSsoSyncApplication";
|
|
29
30
|
export { JaypieStack, JaypieStackProps } from "./JaypieStack";
|
|
@@ -1,43 +1,18 @@
|
|
|
1
1
|
import { Construct } from "constructs";
|
|
2
|
-
import { SecretValue, RemovalPolicy, Stack } from "aws-cdk-lib";
|
|
3
2
|
import * as secretsmanager from "aws-cdk-lib/aws-secretsmanager";
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
import { Grant, IGrantable, PolicyStatement, AddToResourcePolicyResult } from "aws-cdk-lib/aws-iam";
|
|
7
|
-
export interface JaypieEnvSecretProps {
|
|
3
|
+
import { BuildSecretContext, JaypieSecret, JaypieSecretProps } from "./JaypieSecret";
|
|
4
|
+
export interface JaypieEnvSecretProps extends JaypieSecretProps {
|
|
8
5
|
consumer?: boolean;
|
|
9
|
-
envKey?: string;
|
|
10
6
|
export?: string;
|
|
11
|
-
generateSecretString?: secretsmanager.SecretStringGenerator;
|
|
12
7
|
provider?: boolean;
|
|
13
|
-
removalPolicy?: boolean | RemovalPolicy;
|
|
14
|
-
roleTag?: string;
|
|
15
|
-
vendorTag?: string;
|
|
16
|
-
value?: string;
|
|
17
8
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
9
|
+
/**
|
|
10
|
+
* @deprecated Use {@link JaypieSecret}. JaypieEnvSecret layers an
|
|
11
|
+
* environment-driven provider/consumer cross-stack pattern on top of
|
|
12
|
+
* JaypieSecret and will be removed in 2.0.
|
|
13
|
+
*/
|
|
14
|
+
export declare class JaypieEnvSecret extends JaypieSecret {
|
|
15
|
+
protected static readonly shorthandPrefix: string;
|
|
21
16
|
constructor(scope: Construct, idOrEnvKey: string, props?: JaypieEnvSecretProps);
|
|
22
|
-
|
|
23
|
-
get env(): {
|
|
24
|
-
account: string;
|
|
25
|
-
region: string;
|
|
26
|
-
};
|
|
27
|
-
applyRemovalPolicy(policy: RemovalPolicy): void;
|
|
28
|
-
get secretArn(): string;
|
|
29
|
-
get secretFullArn(): string | undefined;
|
|
30
|
-
get secretName(): string;
|
|
31
|
-
get secretRef(): secretsmanager.SecretReference;
|
|
32
|
-
get encryptionKey(): IKey | undefined;
|
|
33
|
-
get secretValue(): SecretValue;
|
|
34
|
-
secretValueFromJson(key: string): SecretValue;
|
|
35
|
-
grantRead(grantee: IGrantable, versionStages?: string[]): Grant;
|
|
36
|
-
grantWrite(grantee: IGrantable): Grant;
|
|
37
|
-
addRotationSchedule(id: string, options: RotationScheduleOptions): RotationSchedule;
|
|
38
|
-
addToResourcePolicy(statement: PolicyStatement): AddToResourcePolicyResult;
|
|
39
|
-
denyAccountRootDelete(): void;
|
|
40
|
-
attach(target: ISecretAttachmentTarget): ISecret;
|
|
41
|
-
cfnDynamicReferenceKey(options?: Parameters<ISecret["cfnDynamicReferenceKey"]>[0]): string;
|
|
42
|
-
get envKey(): string | undefined;
|
|
17
|
+
protected buildSecret(context: BuildSecretContext): secretsmanager.ISecret;
|
|
43
18
|
}
|
|
@@ -64,13 +64,14 @@ export interface JaypieLambdaProps {
|
|
|
64
64
|
/**
|
|
65
65
|
* Secrets to make available to the Lambda function.
|
|
66
66
|
*
|
|
67
|
-
* Supports both
|
|
68
|
-
* - JaypieEnvSecret: used directly
|
|
67
|
+
* Supports both JaypieSecret instances and strings:
|
|
68
|
+
* - JaypieSecret (including JaypieEnvSecret): used directly
|
|
69
69
|
* - String: creates a JaypieEnvSecret with the string as envKey
|
|
70
70
|
* (reuses existing secrets within the same scope)
|
|
71
71
|
*/
|
|
72
72
|
secrets?: SecretsArrayItem[];
|
|
73
73
|
securityGroups?: ec2.ISecurityGroup[];
|
|
74
|
+
serviceTag?: string;
|
|
74
75
|
timeout?: Duration | number;
|
|
75
76
|
tracing?: lambda.Tracing;
|
|
76
77
|
vendorTag?: string;
|
|
@@ -44,8 +44,8 @@ export interface JaypieNextjsProps {
|
|
|
44
44
|
/**
|
|
45
45
|
* Secrets to make available to the Next.js application.
|
|
46
46
|
*
|
|
47
|
-
* Supports both
|
|
48
|
-
* - JaypieEnvSecret: used directly
|
|
47
|
+
* Supports both JaypieSecret instances and strings:
|
|
48
|
+
* - JaypieSecret (including JaypieEnvSecret): used directly
|
|
49
49
|
* - String: creates a JaypieEnvSecret with the string as envKey
|
|
50
50
|
* (reuses existing secrets within the same scope)
|
|
51
51
|
*/
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Construct } from "constructs";
|
|
2
|
+
import { RemovalPolicy, SecretValue, Stack } from "aws-cdk-lib";
|
|
3
|
+
import * as secretsmanager from "aws-cdk-lib/aws-secretsmanager";
|
|
4
|
+
import { ISecret, ISecretAttachmentTarget, RotationSchedule, RotationScheduleOptions } from "aws-cdk-lib/aws-secretsmanager";
|
|
5
|
+
import { IKey } from "aws-cdk-lib/aws-kms";
|
|
6
|
+
import { AddToResourcePolicyResult, Grant, IGrantable, PolicyStatement } from "aws-cdk-lib/aws-iam";
|
|
7
|
+
export interface JaypieSecretProps {
|
|
8
|
+
envKey?: string;
|
|
9
|
+
generateSecretString?: secretsmanager.SecretStringGenerator;
|
|
10
|
+
removalPolicy?: boolean | RemovalPolicy;
|
|
11
|
+
roleTag?: string;
|
|
12
|
+
vendorTag?: string;
|
|
13
|
+
value?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Context handed to {@link JaypieSecret.buildSecret} so subclasses can build the
|
|
17
|
+
* underlying secret differently (e.g. import vs. create) while reusing the
|
|
18
|
+
* shared id/envKey resolution and the full ISecret passthrough.
|
|
19
|
+
*/
|
|
20
|
+
export interface BuildSecretContext {
|
|
21
|
+
envKey?: string;
|
|
22
|
+
id: string;
|
|
23
|
+
props: JaypieSecretProps;
|
|
24
|
+
treatAsEnvKey: boolean;
|
|
25
|
+
}
|
|
26
|
+
export declare class JaypieSecret extends Construct implements ISecret {
|
|
27
|
+
protected static readonly shorthandPrefix: string;
|
|
28
|
+
protected readonly _envKey?: string;
|
|
29
|
+
protected readonly _secret: secretsmanager.ISecret;
|
|
30
|
+
constructor(scope: Construct, idOrEnvKey: string, props?: JaypieSecretProps);
|
|
31
|
+
/**
|
|
32
|
+
* Builds the underlying secret. The base implementation always creates a new
|
|
33
|
+
* Secrets Manager secret from an envKey value, an explicit value, or a
|
|
34
|
+
* generated string. Subclasses may override to import an existing secret or
|
|
35
|
+
* emit cross-stack outputs.
|
|
36
|
+
*/
|
|
37
|
+
protected buildSecret(context: BuildSecretContext): secretsmanager.ISecret;
|
|
38
|
+
get stack(): Stack;
|
|
39
|
+
get env(): {
|
|
40
|
+
account: string;
|
|
41
|
+
region: string;
|
|
42
|
+
};
|
|
43
|
+
applyRemovalPolicy(policy: RemovalPolicy): void;
|
|
44
|
+
get secretArn(): string;
|
|
45
|
+
get secretFullArn(): string | undefined;
|
|
46
|
+
get secretName(): string;
|
|
47
|
+
get secretRef(): secretsmanager.SecretReference;
|
|
48
|
+
get encryptionKey(): IKey | undefined;
|
|
49
|
+
get secretValue(): SecretValue;
|
|
50
|
+
secretValueFromJson(key: string): SecretValue;
|
|
51
|
+
grantRead(grantee: IGrantable, versionStages?: string[]): Grant;
|
|
52
|
+
grantWrite(grantee: IGrantable): Grant;
|
|
53
|
+
addRotationSchedule(id: string, options: RotationScheduleOptions): RotationSchedule;
|
|
54
|
+
addToResourcePolicy(statement: PolicyStatement): AddToResourcePolicyResult;
|
|
55
|
+
denyAccountRootDelete(): void;
|
|
56
|
+
attach(target: ISecretAttachmentTarget): ISecret;
|
|
57
|
+
cfnDynamicReferenceKey(options?: Parameters<ISecret["cfnDynamicReferenceKey"]>[0]): string;
|
|
58
|
+
get envKey(): string | undefined;
|
|
59
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { Construct } from "constructs";
|
|
2
|
-
import {
|
|
2
|
+
import { JaypieSecret } from "../JaypieSecret.js";
|
|
3
3
|
/**
|
|
4
|
-
* Secrets input type that supports both
|
|
5
|
-
* - JaypieEnvSecret: passed through as-is
|
|
6
|
-
* - string: converted to JaypieEnvSecret with the string as envKey
|
|
4
|
+
* Secrets input type that supports both JaypieSecret instances and strings
|
|
5
|
+
* - JaypieSecret (including JaypieEnvSecret subclasses): passed through as-is
|
|
6
|
+
* - string: converted to a JaypieEnvSecret with the string as envKey
|
|
7
7
|
*/
|
|
8
|
-
export type SecretsArrayItem =
|
|
8
|
+
export type SecretsArrayItem = JaypieSecret | string;
|
|
9
9
|
/**
|
|
10
|
-
* Resolves secrets input to an array of
|
|
10
|
+
* Resolves secrets input to an array of JaypieSecret instances.
|
|
11
11
|
*
|
|
12
|
-
* When an item is already a JaypieEnvSecret, it's
|
|
13
|
-
* When an item is a string, a JaypieEnvSecret is created
|
|
14
|
-
* with the string as the envKey.
|
|
12
|
+
* When an item is already a JaypieSecret (including a JaypieEnvSecret), it's
|
|
13
|
+
* passed through as-is. When an item is a string, a JaypieEnvSecret is created
|
|
14
|
+
* (or reused from cache) with the string as the envKey.
|
|
15
15
|
*
|
|
16
16
|
* Secrets are cached per scope to avoid creating duplicate secrets when
|
|
17
17
|
* multiple constructs in the same scope reference the same secret.
|
|
@@ -39,7 +39,7 @@ export type SecretsArrayItem = JaypieEnvSecret | string;
|
|
|
39
39
|
* const secrets2 = resolveSecrets(scope, ["SHARED_SECRET"]);
|
|
40
40
|
* // secrets1[0] === secrets2[0] (same instance)
|
|
41
41
|
*/
|
|
42
|
-
export declare function resolveSecrets(scope: Construct, secrets?: SecretsArrayItem[]):
|
|
42
|
+
export declare function resolveSecrets(scope: Construct, secrets?: SecretsArrayItem[]): JaypieSecret[];
|
|
43
43
|
/**
|
|
44
44
|
* Clears the secrets cache for a given scope.
|
|
45
45
|
* Primarily useful for testing.
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -24,6 +24,7 @@ export { DomainNameConfig, JaypieNextJs, JaypieNextjsProps, } from "./JaypieNext
|
|
|
24
24
|
export { JaypieOpenAiSecret } from "./JaypieOpenAiSecret";
|
|
25
25
|
export { JaypieOrganizationTrail, JaypieOrganizationTrailProps, } from "./JaypieOrganizationTrail";
|
|
26
26
|
export { JaypieQueuedLambda } from "./JaypieQueuedLambda";
|
|
27
|
+
export { JaypieSecret, JaypieSecretProps } from "./JaypieSecret";
|
|
27
28
|
export { AccountAssignments, JaypieSsoPermissions, JaypieSsoPermissionsProps, } from "./JaypieSsoPermissions";
|
|
28
29
|
export { JaypieSsoSyncApplication, JaypieSsoSyncApplicationProps, } from "./JaypieSsoSyncApplication";
|
|
29
30
|
export { JaypieStack, JaypieStackProps } from "./JaypieStack";
|
package/dist/esm/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as cdk from 'aws-cdk-lib';
|
|
2
|
-
import { Tags, Stack,
|
|
2
|
+
import { Tags, Stack, SecretValue, RemovalPolicy, Fn, CfnOutput, Duration, CfnStack } from 'aws-cdk-lib';
|
|
3
3
|
import * as s3 from 'aws-cdk-lib/aws-s3';
|
|
4
4
|
import { Bucket, StorageClass, BucketAccessControl, EventType } from 'aws-cdk-lib/aws-s3';
|
|
5
5
|
import { Construct } from 'constructs';
|
|
@@ -937,115 +937,67 @@ const resolveParamsAndSecrets = ({ paramsAndSecrets, options, } = {}) => {
|
|
|
937
937
|
return resolvedParamsAndSecrets;
|
|
938
938
|
};
|
|
939
939
|
|
|
940
|
-
|
|
941
|
-
function checkEnvIsConsumer$1(env = process.env) {
|
|
942
|
-
return (env.PROJECT_ENV === CDK$2.ENV.PERSONAL ||
|
|
943
|
-
!!env.CDK_ENV_PERSONAL ||
|
|
944
|
-
/** @deprecated */ env.PROJECT_ENV === "ephemeral" ||
|
|
945
|
-
/** @deprecated */ !!env.CDK_ENV_EPHEMERAL);
|
|
946
|
-
}
|
|
947
|
-
function checkEnvIsProvider$1(env = process.env) {
|
|
948
|
-
return env.PROJECT_ENV === CDK$2.ENV.SANDBOX;
|
|
949
|
-
}
|
|
950
|
-
function cleanName$1(name) {
|
|
951
|
-
return name.replace(/[^a-zA-Z0-9:-]/g, "");
|
|
952
|
-
}
|
|
953
|
-
function exportEnvName$1(name, env = process.env, consumer = false) {
|
|
954
|
-
let rawName;
|
|
955
|
-
if (checkEnvIsProvider$1(env)) {
|
|
956
|
-
rawName = `env-${env.PROJECT_ENV}-${env.PROJECT_KEY}-${name}`;
|
|
957
|
-
// Clean the entire name to only allow alphanumeric, colons, and hyphens
|
|
958
|
-
return cleanName$1(rawName);
|
|
959
|
-
}
|
|
960
|
-
else {
|
|
961
|
-
if (consumer || checkEnvIsConsumer$1(env)) {
|
|
962
|
-
rawName = `env-${CDK$2.ENV.SANDBOX}-${env.PROJECT_KEY}-${name}`;
|
|
963
|
-
}
|
|
964
|
-
else {
|
|
965
|
-
rawName = `env-${env.PROJECT_ENV}-${env.PROJECT_KEY}-${name}`;
|
|
966
|
-
}
|
|
967
|
-
}
|
|
968
|
-
return cleanName$1(rawName);
|
|
969
|
-
}
|
|
970
|
-
class JaypieEnvSecret extends Construct {
|
|
940
|
+
class JaypieSecret extends Construct {
|
|
971
941
|
constructor(scope, idOrEnvKey, props) {
|
|
972
942
|
// Shorthand detection: treat idOrEnvKey as envKey when envKey prop is
|
|
973
943
|
// not set and idOrEnvKey either looks like a SCREAMING_SNAKE_CASE env
|
|
974
944
|
// var name or is already present in process.env. Convention-based
|
|
975
945
|
// detection ensures missing env vars still go through envKey validation
|
|
976
946
|
// instead of silently creating an empty secret.
|
|
947
|
+
const prefix = new.target.shorthandPrefix;
|
|
977
948
|
const looksLikeEnvKey = /^[A-Z][A-Z0-9_]*$/.test(idOrEnvKey);
|
|
978
949
|
const treatAsEnvKey = (!props || props.envKey === undefined) &&
|
|
979
950
|
(looksLikeEnvKey ||
|
|
980
951
|
(typeof process.env[idOrEnvKey] === "string" &&
|
|
981
952
|
process.env[idOrEnvKey] !== ""));
|
|
982
|
-
const id = treatAsEnvKey ?
|
|
953
|
+
const id = treatAsEnvKey ? `${prefix}${idOrEnvKey}` : idOrEnvKey;
|
|
983
954
|
super(scope, id);
|
|
984
|
-
const
|
|
985
|
-
const envKey = treatAsEnvKey ? idOrEnvKey : envKeyProp;
|
|
955
|
+
const envKey = treatAsEnvKey ? idOrEnvKey : props?.envKey;
|
|
986
956
|
this._envKey = envKey;
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
957
|
+
this._secret = this.buildSecret({
|
|
958
|
+
envKey,
|
|
959
|
+
id,
|
|
960
|
+
props: props || {},
|
|
961
|
+
treatAsEnvKey,
|
|
962
|
+
});
|
|
963
|
+
}
|
|
964
|
+
/**
|
|
965
|
+
* Builds the underlying secret. The base implementation always creates a new
|
|
966
|
+
* Secrets Manager secret from an envKey value, an explicit value, or a
|
|
967
|
+
* generated string. Subclasses may override to import an existing secret or
|
|
968
|
+
* emit cross-stack outputs.
|
|
969
|
+
*/
|
|
970
|
+
buildSecret(context) {
|
|
971
|
+
const { envKey, id, props } = context;
|
|
972
|
+
const { generateSecretString, removalPolicy, roleTag, vendorTag, value } = props;
|
|
973
|
+
if (envKey &&
|
|
1001
974
|
!process.env[envKey] &&
|
|
1002
975
|
value === undefined &&
|
|
1003
976
|
!generateSecretString) {
|
|
1004
|
-
throw new ConfigurationError(`
|
|
977
|
+
throw new ConfigurationError(`JaypieSecret(${id}): envKey "${envKey}" is empty in process.env and no value or generateSecretString was provided`);
|
|
1005
978
|
}
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
979
|
+
const secretValue = envKey && process.env[envKey] ? process.env[envKey] : value;
|
|
980
|
+
const secret = new secretsmanager.Secret(this, id, {
|
|
981
|
+
generateSecretString,
|
|
982
|
+
secretStringValue: !generateSecretString && secretValue
|
|
983
|
+
? SecretValue.unsafePlainText(secretValue)
|
|
984
|
+
: undefined,
|
|
985
|
+
});
|
|
986
|
+
if (removalPolicy !== undefined) {
|
|
987
|
+
const policy = typeof removalPolicy === "boolean"
|
|
988
|
+
? removalPolicy
|
|
989
|
+
? RemovalPolicy.RETAIN
|
|
990
|
+
: RemovalPolicy.DESTROY
|
|
991
|
+
: removalPolicy;
|
|
992
|
+
secret.applyRemovalPolicy(policy);
|
|
1013
993
|
}
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
? SecretValue.unsafePlainText(secretValue)
|
|
1020
|
-
: undefined,
|
|
1021
|
-
};
|
|
1022
|
-
this._secret = new secretsmanager.Secret(this, id, secretProps);
|
|
1023
|
-
if (removalPolicy !== undefined) {
|
|
1024
|
-
const policy = typeof removalPolicy === "boolean"
|
|
1025
|
-
? removalPolicy
|
|
1026
|
-
? RemovalPolicy.RETAIN
|
|
1027
|
-
: RemovalPolicy.DESTROY
|
|
1028
|
-
: removalPolicy;
|
|
1029
|
-
this._secret.applyRemovalPolicy(policy);
|
|
1030
|
-
}
|
|
1031
|
-
if (roleTag) {
|
|
1032
|
-
Tags.of(this._secret).add(CDK$2.TAG.ROLE, roleTag);
|
|
1033
|
-
}
|
|
1034
|
-
if (vendorTag) {
|
|
1035
|
-
Tags.of(this._secret).add(CDK$2.TAG.VENDOR, vendorTag);
|
|
1036
|
-
}
|
|
1037
|
-
if (provider) {
|
|
1038
|
-
new CfnOutput(this, `ProvidedName`, {
|
|
1039
|
-
value: this._secret.secretName,
|
|
1040
|
-
exportName,
|
|
1041
|
-
});
|
|
1042
|
-
}
|
|
1043
|
-
else {
|
|
1044
|
-
new CfnOutput(this, `CreatedName`, {
|
|
1045
|
-
value: this._secret.secretName,
|
|
1046
|
-
});
|
|
1047
|
-
}
|
|
994
|
+
if (roleTag) {
|
|
995
|
+
Tags.of(secret).add(CDK$2.TAG.ROLE, roleTag);
|
|
996
|
+
}
|
|
997
|
+
if (vendorTag) {
|
|
998
|
+
Tags.of(secret).add(CDK$2.TAG.VENDOR, vendorTag);
|
|
1048
999
|
}
|
|
1000
|
+
return secret;
|
|
1049
1001
|
}
|
|
1050
1002
|
// IResource implementation
|
|
1051
1003
|
get stack() {
|
|
@@ -1107,6 +1059,117 @@ class JaypieEnvSecret extends Construct {
|
|
|
1107
1059
|
return this._envKey;
|
|
1108
1060
|
}
|
|
1109
1061
|
}
|
|
1062
|
+
// Construct id prefix used when an envKey is detected via shorthand.
|
|
1063
|
+
// Subclasses override this to preserve their own naming conventions.
|
|
1064
|
+
JaypieSecret.shorthandPrefix = "Secret_";
|
|
1065
|
+
|
|
1066
|
+
// It is a consumer if the environment is ephemeral
|
|
1067
|
+
function checkEnvIsConsumer$1(env = process.env) {
|
|
1068
|
+
return (env.PROJECT_ENV === CDK$2.ENV.PERSONAL ||
|
|
1069
|
+
!!env.CDK_ENV_PERSONAL ||
|
|
1070
|
+
/** @deprecated */ env.PROJECT_ENV === "ephemeral" ||
|
|
1071
|
+
/** @deprecated */ !!env.CDK_ENV_EPHEMERAL);
|
|
1072
|
+
}
|
|
1073
|
+
function checkEnvIsProvider$1(env = process.env) {
|
|
1074
|
+
return env.PROJECT_ENV === CDK$2.ENV.SANDBOX;
|
|
1075
|
+
}
|
|
1076
|
+
function cleanName$1(name) {
|
|
1077
|
+
return name.replace(/[^a-zA-Z0-9:-]/g, "");
|
|
1078
|
+
}
|
|
1079
|
+
function exportEnvName$1(name, env = process.env, consumer = false) {
|
|
1080
|
+
let rawName;
|
|
1081
|
+
if (checkEnvIsProvider$1(env)) {
|
|
1082
|
+
rawName = `env-${env.PROJECT_ENV}-${env.PROJECT_KEY}-${name}`;
|
|
1083
|
+
// Clean the entire name to only allow alphanumeric, colons, and hyphens
|
|
1084
|
+
return cleanName$1(rawName);
|
|
1085
|
+
}
|
|
1086
|
+
else {
|
|
1087
|
+
if (consumer || checkEnvIsConsumer$1(env)) {
|
|
1088
|
+
rawName = `env-${CDK$2.ENV.SANDBOX}-${env.PROJECT_KEY}-${name}`;
|
|
1089
|
+
}
|
|
1090
|
+
else {
|
|
1091
|
+
rawName = `env-${env.PROJECT_ENV}-${env.PROJECT_KEY}-${name}`;
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
return cleanName$1(rawName);
|
|
1095
|
+
}
|
|
1096
|
+
/**
|
|
1097
|
+
* @deprecated Use {@link JaypieSecret}. JaypieEnvSecret layers an
|
|
1098
|
+
* environment-driven provider/consumer cross-stack pattern on top of
|
|
1099
|
+
* JaypieSecret and will be removed in 2.0.
|
|
1100
|
+
*/
|
|
1101
|
+
class JaypieEnvSecret extends JaypieSecret {
|
|
1102
|
+
constructor(scope, idOrEnvKey, props) {
|
|
1103
|
+
super(scope, idOrEnvKey, props);
|
|
1104
|
+
}
|
|
1105
|
+
buildSecret(context) {
|
|
1106
|
+
const { envKey, id, treatAsEnvKey } = context;
|
|
1107
|
+
const props = context.props;
|
|
1108
|
+
const { consumer = checkEnvIsConsumer$1(), export: exportParam, generateSecretString, provider = checkEnvIsProvider$1(), removalPolicy, roleTag, vendorTag, value, } = props;
|
|
1109
|
+
let exportName;
|
|
1110
|
+
if (!exportParam) {
|
|
1111
|
+
// When shorthand detection is active, use the full construct id (which
|
|
1112
|
+
// includes the "EnvSecret_" prefix) so the export name matches what was
|
|
1113
|
+
// produced by earlier versions of this construct. Using the raw envKey
|
|
1114
|
+
// here produces a shorter name that breaks existing cross-stack imports.
|
|
1115
|
+
const exportSource = treatAsEnvKey ? id : envKey || id;
|
|
1116
|
+
exportName = exportEnvName$1(exportSource, process.env, consumer);
|
|
1117
|
+
}
|
|
1118
|
+
else {
|
|
1119
|
+
exportName = cleanName$1(exportParam);
|
|
1120
|
+
}
|
|
1121
|
+
if (!consumer &&
|
|
1122
|
+
envKey &&
|
|
1123
|
+
!process.env[envKey] &&
|
|
1124
|
+
value === undefined &&
|
|
1125
|
+
!generateSecretString) {
|
|
1126
|
+
throw new ConfigurationError(`JaypieEnvSecret(${id}): envKey "${envKey}" is empty in process.env and no value or generateSecretString was provided`);
|
|
1127
|
+
}
|
|
1128
|
+
if (consumer) {
|
|
1129
|
+
const secretName = Fn.importValue(exportName);
|
|
1130
|
+
const secret = secretsmanager.Secret.fromSecretNameV2(this, id, secretName);
|
|
1131
|
+
// Add CfnOutput for consumer secrets
|
|
1132
|
+
new CfnOutput(this, `ConsumedName`, {
|
|
1133
|
+
value: secret.secretName,
|
|
1134
|
+
});
|
|
1135
|
+
return secret;
|
|
1136
|
+
}
|
|
1137
|
+
const secretValue = envKey && process.env[envKey] ? process.env[envKey] : value;
|
|
1138
|
+
const secret = new secretsmanager.Secret(this, id, {
|
|
1139
|
+
generateSecretString,
|
|
1140
|
+
secretStringValue: !generateSecretString && secretValue
|
|
1141
|
+
? SecretValue.unsafePlainText(secretValue)
|
|
1142
|
+
: undefined,
|
|
1143
|
+
});
|
|
1144
|
+
if (removalPolicy !== undefined) {
|
|
1145
|
+
const policy = typeof removalPolicy === "boolean"
|
|
1146
|
+
? removalPolicy
|
|
1147
|
+
? RemovalPolicy.RETAIN
|
|
1148
|
+
: RemovalPolicy.DESTROY
|
|
1149
|
+
: removalPolicy;
|
|
1150
|
+
secret.applyRemovalPolicy(policy);
|
|
1151
|
+
}
|
|
1152
|
+
if (roleTag) {
|
|
1153
|
+
Tags.of(secret).add(CDK$2.TAG.ROLE, roleTag);
|
|
1154
|
+
}
|
|
1155
|
+
if (vendorTag) {
|
|
1156
|
+
Tags.of(secret).add(CDK$2.TAG.VENDOR, vendorTag);
|
|
1157
|
+
}
|
|
1158
|
+
if (provider) {
|
|
1159
|
+
new CfnOutput(this, `ProvidedName`, {
|
|
1160
|
+
value: secret.secretName,
|
|
1161
|
+
exportName,
|
|
1162
|
+
});
|
|
1163
|
+
}
|
|
1164
|
+
else {
|
|
1165
|
+
new CfnOutput(this, `CreatedName`, {
|
|
1166
|
+
value: secret.secretName,
|
|
1167
|
+
});
|
|
1168
|
+
}
|
|
1169
|
+
return secret;
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
JaypieEnvSecret.shorthandPrefix = "EnvSecret_";
|
|
1110
1173
|
|
|
1111
1174
|
/**
|
|
1112
1175
|
* Cache for secrets by scope to avoid creating duplicates.
|
|
@@ -1143,11 +1206,11 @@ function getOrCreateSecret(scope, envKey, props) {
|
|
|
1143
1206
|
return secret;
|
|
1144
1207
|
}
|
|
1145
1208
|
/**
|
|
1146
|
-
* Resolves secrets input to an array of
|
|
1209
|
+
* Resolves secrets input to an array of JaypieSecret instances.
|
|
1147
1210
|
*
|
|
1148
|
-
* When an item is already a JaypieEnvSecret, it's
|
|
1149
|
-
* When an item is a string, a JaypieEnvSecret is created
|
|
1150
|
-
* with the string as the envKey.
|
|
1211
|
+
* When an item is already a JaypieSecret (including a JaypieEnvSecret), it's
|
|
1212
|
+
* passed through as-is. When an item is a string, a JaypieEnvSecret is created
|
|
1213
|
+
* (or reused from cache) with the string as the envKey.
|
|
1151
1214
|
*
|
|
1152
1215
|
* Secrets are cached per scope to avoid creating duplicate secrets when
|
|
1153
1216
|
* multiple constructs in the same scope reference the same secret.
|
|
@@ -1183,7 +1246,7 @@ function resolveSecrets(scope, secrets) {
|
|
|
1183
1246
|
if (typeof item === "string") {
|
|
1184
1247
|
return getOrCreateSecret(scope, item);
|
|
1185
1248
|
}
|
|
1186
|
-
// Already a JaypieEnvSecret instance
|
|
1249
|
+
// Already a JaypieSecret (or JaypieEnvSecret) instance
|
|
1187
1250
|
return item;
|
|
1188
1251
|
});
|
|
1189
1252
|
}
|
|
@@ -1393,12 +1456,12 @@ class JaypieLambda extends Construct {
|
|
|
1393
1456
|
super(scope, id);
|
|
1394
1457
|
const { allowAllOutbound, allowPublicSubnet, architecture = lambda.Architecture.X86_64, code, datadogApiKeyArn, deadLetterQueue, deadLetterQueueEnabled, deadLetterTopic, description, tables = [], environment: environmentInput, envSecrets = {}, ephemeralStorageSize, filesystem, handler = "index.handler", initialPolicy, layers = [], logGroup, logRetention = CDK$2.LAMBDA.LOG_RETENTION, maxEventAge, memorySize = CDK$2.LAMBDA.MEMORY_SIZE, paramsAndSecrets, paramsAndSecretsOptions, profiling, profilingGroup, provisionedConcurrentExecutions, reservedConcurrentExecutions, retryAttempts, roleTag = CDK$2.ROLE.PROCESSING, runtime = new lambda.Runtime("nodejs24.x", lambda.RuntimeFamily.NODEJS, {
|
|
1395
1458
|
supportsInlineCode: true,
|
|
1396
|
-
}), runtimeManagementMode, secrets: secretsInput = [], securityGroups, timeout = Duration.seconds(CDK$2.DURATION.LAMBDA_WORKER), tracing, vendorTag, vpc, vpcSubnets, } = props;
|
|
1459
|
+
}), runtimeManagementMode, secrets: secretsInput = [], securityGroups, serviceTag, timeout = Duration.seconds(CDK$2.DURATION.LAMBDA_WORKER), tracing, vendorTag, vpc, vpcSubnets, } = props;
|
|
1397
1460
|
// Resolve environment from array or object syntax
|
|
1398
1461
|
const initialEnvironment = resolveEnvironment(environmentInput);
|
|
1399
1462
|
// Get base environment with defaults
|
|
1400
1463
|
const environment = jaypieLambdaEnv({ initialEnvironment });
|
|
1401
|
-
// Resolve secrets from mixed array (strings and
|
|
1464
|
+
// Resolve secrets from mixed array (strings and JaypieSecret instances)
|
|
1402
1465
|
// Use Stack.of(this) to ensure secrets are shared at stack level across all constructs
|
|
1403
1466
|
const secrets = resolveSecrets(Stack.of(this), secretsInput);
|
|
1404
1467
|
const codeAsset = typeof code === "string" ? lambda.Code.fromAsset(code) : code;
|
|
@@ -1409,7 +1472,7 @@ class JaypieLambda extends Construct {
|
|
|
1409
1472
|
...acc,
|
|
1410
1473
|
[`SECRET_${key}`]: secret.secretName,
|
|
1411
1474
|
}), {});
|
|
1412
|
-
// Process
|
|
1475
|
+
// Process JaypieSecret array
|
|
1413
1476
|
const jaypieSecretsEnvironment = secrets.reduce((acc, secret) => {
|
|
1414
1477
|
if (secret.envKey) {
|
|
1415
1478
|
return {
|
|
@@ -1479,7 +1542,7 @@ class JaypieLambda extends Construct {
|
|
|
1479
1542
|
Object.values(envSecrets).forEach((secret) => {
|
|
1480
1543
|
secret.grantRead(this._lambda);
|
|
1481
1544
|
});
|
|
1482
|
-
// Grant read permissions for
|
|
1545
|
+
// Grant read permissions for JaypieSecrets
|
|
1483
1546
|
secrets.forEach((secret) => {
|
|
1484
1547
|
secret.grantRead(this._lambda);
|
|
1485
1548
|
});
|
|
@@ -1507,6 +1570,9 @@ class JaypieLambda extends Construct {
|
|
|
1507
1570
|
if (roleTag) {
|
|
1508
1571
|
Tags.of(this._lambda).add(CDK$2.TAG.ROLE, roleTag);
|
|
1509
1572
|
}
|
|
1573
|
+
if (serviceTag) {
|
|
1574
|
+
Tags.of(this._lambda).add(CDK$2.TAG.SERVICE, serviceTag);
|
|
1575
|
+
}
|
|
1510
1576
|
if (vendorTag) {
|
|
1511
1577
|
Tags.of(this._lambda).add(CDK$2.TAG.VENDOR, vendorTag);
|
|
1512
1578
|
}
|
|
@@ -1631,7 +1697,7 @@ class JaypieQueuedLambda extends Construct {
|
|
|
1631
1697
|
super(scope, id);
|
|
1632
1698
|
const { allowAllOutbound, allowPublicSubnet, architecture, batchSize = 1, code, datadogApiKeyArn, deadLetterQueue, deadLetterQueueEnabled, deadLetterTopic, description, environment = {}, envSecrets = {}, ephemeralStorageSize, fifo = true, filesystem, handler = "index.handler", initialPolicy, layers = [], logGroup, logRetention = CDK$2.LAMBDA.LOG_RETENTION, maxEventAge, memorySize = CDK$2.LAMBDA.MEMORY_SIZE, paramsAndSecrets, paramsAndSecretsOptions, profiling, profilingGroup, provisionedConcurrentExecutions, reservedConcurrentExecutions, retryAttempts, roleTag, runtime = new lambda.Runtime("nodejs24.x", lambda.RuntimeFamily.NODEJS, {
|
|
1633
1699
|
supportsInlineCode: true,
|
|
1634
|
-
}), runtimeManagementMode, secrets = [], securityGroups, tables = [], timeout = Duration.seconds(CDK$2.DURATION.LAMBDA_WORKER), tracing, vendorTag, visibilityTimeout = Duration.seconds(CDK$2.DURATION.LAMBDA_WORKER), vpc, vpcSubnets, } = props;
|
|
1700
|
+
}), runtimeManagementMode, secrets = [], securityGroups, serviceTag, tables = [], timeout = Duration.seconds(CDK$2.DURATION.LAMBDA_WORKER), tracing, vendorTag, visibilityTimeout = Duration.seconds(CDK$2.DURATION.LAMBDA_WORKER), vpc, vpcSubnets, } = props;
|
|
1635
1701
|
// Create SQS Queue
|
|
1636
1702
|
this._queue = new sqs.Queue(this, "Queue", {
|
|
1637
1703
|
fifo,
|
|
@@ -1642,6 +1708,9 @@ class JaypieQueuedLambda extends Construct {
|
|
|
1642
1708
|
if (roleTag) {
|
|
1643
1709
|
Tags.of(this._queue).add(CDK$2.TAG.ROLE, roleTag);
|
|
1644
1710
|
}
|
|
1711
|
+
if (serviceTag) {
|
|
1712
|
+
Tags.of(this._queue).add(CDK$2.TAG.SERVICE, serviceTag);
|
|
1713
|
+
}
|
|
1645
1714
|
if (vendorTag) {
|
|
1646
1715
|
Tags.of(this._queue).add(CDK$2.TAG.VENDOR, vendorTag);
|
|
1647
1716
|
}
|
|
@@ -1679,6 +1748,7 @@ class JaypieQueuedLambda extends Construct {
|
|
|
1679
1748
|
runtimeManagementMode,
|
|
1680
1749
|
secrets,
|
|
1681
1750
|
securityGroups,
|
|
1751
|
+
serviceTag,
|
|
1682
1752
|
tables,
|
|
1683
1753
|
timeout,
|
|
1684
1754
|
tracing,
|
|
@@ -1873,7 +1943,7 @@ class JaypieBucketQueuedLambda extends JaypieQueuedLambda {
|
|
|
1873
1943
|
constructor(scope, id, props) {
|
|
1874
1944
|
props.fifo = false; // S3 event notifications are not supported for FIFO queues
|
|
1875
1945
|
super(scope, id, props);
|
|
1876
|
-
const { bucketName, roleTag, vendorTag, bucketOptions = {} } = props;
|
|
1946
|
+
const { bucketName, roleTag, serviceTag, vendorTag, bucketOptions = {}, } = props;
|
|
1877
1947
|
// Create S3 Bucket
|
|
1878
1948
|
this._bucket = new s3.Bucket(this, "Bucket", {
|
|
1879
1949
|
bucketName: bucketOptions.bucketName || bucketName,
|
|
@@ -1884,6 +1954,9 @@ class JaypieBucketQueuedLambda extends JaypieQueuedLambda {
|
|
|
1884
1954
|
if (roleTag) {
|
|
1885
1955
|
Tags.of(this._bucket).add(CDK$2.TAG.ROLE, roleTag);
|
|
1886
1956
|
}
|
|
1957
|
+
if (serviceTag) {
|
|
1958
|
+
Tags.of(this._bucket).add(CDK$2.TAG.SERVICE, serviceTag);
|
|
1959
|
+
}
|
|
1887
1960
|
if (vendorTag) {
|
|
1888
1961
|
Tags.of(this._bucket).add(CDK$2.TAG.VENDOR, vendorTag);
|
|
1889
1962
|
}
|
|
@@ -3721,7 +3794,7 @@ class JaypieNextJs extends Construct {
|
|
|
3721
3794
|
? path.join(process.cwd(), props.nextjsPath)
|
|
3722
3795
|
: props?.nextjsPath || path.join(process.cwd(), "..", "nextjs");
|
|
3723
3796
|
const paramsAndSecrets = resolveParamsAndSecrets();
|
|
3724
|
-
// Resolve secrets from mixed array (strings and
|
|
3797
|
+
// Resolve secrets from mixed array (strings and JaypieSecret instances)
|
|
3725
3798
|
// Use Stack.of(this) to ensure secrets are shared at stack level across all constructs
|
|
3726
3799
|
const secrets = resolveSecrets(Stack.of(this), props?.secrets);
|
|
3727
3800
|
// Process secrets environment variables
|
|
@@ -3729,7 +3802,7 @@ class JaypieNextJs extends Construct {
|
|
|
3729
3802
|
...acc,
|
|
3730
3803
|
[`SECRET_${key}`]: secret.secretName,
|
|
3731
3804
|
}), {});
|
|
3732
|
-
// Process
|
|
3805
|
+
// Process JaypieSecret array
|
|
3733
3806
|
const jaypieSecretsEnvironment = secrets.reduce((acc, secret) => {
|
|
3734
3807
|
if (secret.envKey) {
|
|
3735
3808
|
return {
|
|
@@ -3804,7 +3877,7 @@ class JaypieNextJs extends Construct {
|
|
|
3804
3877
|
Object.values(envSecrets).forEach((secret) => {
|
|
3805
3878
|
secret.grantRead(nextjs.serverFunction.lambdaFunction);
|
|
3806
3879
|
});
|
|
3807
|
-
// Grant read permissions for
|
|
3880
|
+
// Grant read permissions for JaypieSecrets
|
|
3808
3881
|
secrets.forEach((secret) => {
|
|
3809
3882
|
secret.grantRead(nextjs.serverFunction.lambdaFunction);
|
|
3810
3883
|
});
|
|
@@ -5346,5 +5419,5 @@ class JaypieWebSocketTable extends Construct {
|
|
|
5346
5419
|
}
|
|
5347
5420
|
}
|
|
5348
5421
|
|
|
5349
|
-
export { CDK$2 as CDK, JaypieAccountLoggingBucket, JaypieApiGateway, JaypieAppStack, JaypieBucketQueuedLambda, JaypieCertificate, JaypieDatadogBucket, JaypieDatadogForwarder, JaypieDatadogSecret, JaypieDistribution, JaypieDnsRecord, JaypieDynamoDb, JaypieEnvSecret, JaypieEventsRule, JaypieExpressLambda, JaypieGitHubDeployRole, JaypieHostedZone, JaypieInfrastructureStack, JaypieLambda, JaypieMigration, JaypieMongoDbSecret, JaypieNextJs, JaypieOpenAiSecret, JaypieOrganizationTrail, JaypieQueuedLambda, JaypieSsoPermissions, JaypieSsoSyncApplication, JaypieStack, JaypieStaticWebBucket, JaypieTraceSigningKeySecret, JaypieWebDeploymentBucket, JaypieWebSocket, JaypieWebSocketLambda, JaypieWebSocketTable, addDatadogLayers, clearAllCertificateCaches, clearAllSecretsCaches, clearCertificateCache, clearSecretsCache, constructEnvName, constructStackName, constructTagger, constructWafLogBucketName, ensureRoute53QueryLoggingPolicy, envHostname, extendDatadogRole, isEnv, isProductionEnv, isSandboxEnv, isValidHostname$1 as isValidHostname, isValidSubdomain, jaypieLambdaEnv, mergeDomain, resolveCertificate, resolveDatadogForwarderFunction, resolveDatadogLayers, resolveDatadogLoggingDestination, resolveEnvironment, resolveHostedZone, resolveParamsAndSecrets, resolveSecrets };
|
|
5422
|
+
export { CDK$2 as CDK, JaypieAccountLoggingBucket, JaypieApiGateway, JaypieAppStack, JaypieBucketQueuedLambda, JaypieCertificate, JaypieDatadogBucket, JaypieDatadogForwarder, JaypieDatadogSecret, JaypieDistribution, JaypieDnsRecord, JaypieDynamoDb, JaypieEnvSecret, JaypieEventsRule, JaypieExpressLambda, JaypieGitHubDeployRole, JaypieHostedZone, JaypieInfrastructureStack, JaypieLambda, JaypieMigration, JaypieMongoDbSecret, JaypieNextJs, JaypieOpenAiSecret, JaypieOrganizationTrail, JaypieQueuedLambda, JaypieSecret, JaypieSsoPermissions, JaypieSsoSyncApplication, JaypieStack, JaypieStaticWebBucket, JaypieTraceSigningKeySecret, JaypieWebDeploymentBucket, JaypieWebSocket, JaypieWebSocketLambda, JaypieWebSocketTable, addDatadogLayers, clearAllCertificateCaches, clearAllSecretsCaches, clearCertificateCache, clearSecretsCache, constructEnvName, constructStackName, constructTagger, constructWafLogBucketName, ensureRoute53QueryLoggingPolicy, envHostname, extendDatadogRole, isEnv, isProductionEnv, isSandboxEnv, isValidHostname$1 as isValidHostname, isValidSubdomain, jaypieLambdaEnv, mergeDomain, resolveCertificate, resolveDatadogForwarderFunction, resolveDatadogLayers, resolveDatadogLoggingDestination, resolveEnvironment, resolveHostedZone, resolveParamsAndSecrets, resolveSecrets };
|
|
5350
5423
|
//# sourceMappingURL=index.js.map
|