@jaypie/constructs 1.2.57 → 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.
@@ -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 { ISecret, ISecretAttachmentTarget, RotationSchedule, RotationScheduleOptions } from "aws-cdk-lib/aws-secretsmanager";
5
- import { IKey } from "aws-cdk-lib/aws-kms";
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
- export declare class JaypieEnvSecret extends Construct implements ISecret {
19
- private readonly _envKey?;
20
- private readonly _secret;
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
- get stack(): Stack;
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 JaypieEnvSecret instances and strings:
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 JaypieEnvSecret instances and strings:
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 { JaypieEnvSecret } from "../JaypieEnvSecret.js";
2
+ import { JaypieSecret } from "../JaypieSecret.js";
3
3
  /**
4
- * Secrets input type that supports both JaypieEnvSecret instances and strings
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 = JaypieEnvSecret | string;
8
+ export type SecretsArrayItem = JaypieSecret | string;
9
9
  /**
10
- * Resolves secrets input to an array of JaypieEnvSecret instances.
10
+ * Resolves secrets input to an array of JaypieSecret instances.
11
11
  *
12
- * When an item is already a JaypieEnvSecret, it's passed through as-is.
13
- * When an item is a string, a JaypieEnvSecret is created (or reused from cache)
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[]): JaypieEnvSecret[];
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.
@@ -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, Fn, CfnOutput, SecretValue, RemovalPolicy, Duration, CfnStack } from 'aws-cdk-lib';
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
- // It is a consumer if the environment is ephemeral
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 ? `EnvSecret_${idOrEnvKey}` : idOrEnvKey;
953
+ const id = treatAsEnvKey ? `${prefix}${idOrEnvKey}` : idOrEnvKey;
983
954
  super(scope, id);
984
- const { consumer = checkEnvIsConsumer$1(), envKey: envKeyProp, export: exportParam, generateSecretString, provider = checkEnvIsProvider$1(), removalPolicy, roleTag, vendorTag, value, } = props || {};
985
- const envKey = treatAsEnvKey ? idOrEnvKey : envKeyProp;
955
+ const envKey = treatAsEnvKey ? idOrEnvKey : props?.envKey;
986
956
  this._envKey = envKey;
987
- let exportName;
988
- if (!exportParam) {
989
- // When shorthand detection is active, use the full construct id (which
990
- // includes the "EnvSecret_" prefix) so the export name matches what was
991
- // produced by earlier versions of this construct. Using the raw envKey
992
- // here produces a shorter name that breaks existing cross-stack imports.
993
- const exportSource = treatAsEnvKey ? id : envKey || id;
994
- exportName = exportEnvName$1(exportSource, process.env, consumer);
995
- }
996
- else {
997
- exportName = cleanName$1(exportParam);
998
- }
999
- if (!consumer &&
1000
- envKey &&
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(`JaypieEnvSecret(${id}): envKey "${envKey}" is empty in process.env and no value or generateSecretString was provided`);
977
+ throw new ConfigurationError(`JaypieSecret(${id}): envKey "${envKey}" is empty in process.env and no value or generateSecretString was provided`);
1005
978
  }
1006
- if (consumer) {
1007
- const secretName = Fn.importValue(exportName);
1008
- this._secret = secretsmanager.Secret.fromSecretNameV2(this, id, secretName);
1009
- // Add CfnOutput for consumer secrets
1010
- new CfnOutput(this, `ConsumedName`, {
1011
- value: this._secret.secretName,
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
- else {
1015
- const secretValue = envKey && process.env[envKey] ? process.env[envKey] : value;
1016
- const secretProps = {
1017
- generateSecretString,
1018
- secretStringValue: !generateSecretString && secretValue
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 JaypieEnvSecret instances.
1209
+ * Resolves secrets input to an array of JaypieSecret instances.
1147
1210
  *
1148
- * When an item is already a JaypieEnvSecret, it's passed through as-is.
1149
- * When an item is a string, a JaypieEnvSecret is created (or reused from cache)
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 JaypieEnvSecret instances)
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 JaypieEnvSecret array
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 JaypieEnvSecrets
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 JaypieEnvSecret instances)
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 JaypieEnvSecret array
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 JaypieEnvSecrets
3880
+ // Grant read permissions for JaypieSecrets
3808
3881
  secrets.forEach((secret) => {
3809
3882
  secret.grantRead(nextjs.serverFunction.lambdaFunction);
3810
3883
  });
@@ -4168,6 +4241,9 @@ class JaypieSsoPermissions extends Construct {
4168
4241
  {
4169
4242
  Effect: "Allow",
4170
4243
  Action: [
4244
+ "bedrock-agent:*",
4245
+ "bedrock-agentcore:*",
4246
+ "bedrock:*",
4171
4247
  "budgets:*",
4172
4248
  "ce:*",
4173
4249
  "cloudformation:*",
@@ -5343,5 +5419,5 @@ class JaypieWebSocketTable extends Construct {
5343
5419
  }
5344
5420
  }
5345
5421
 
5346
- 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 };
5347
5423
  //# sourceMappingURL=index.js.map