1- import {
2- FunctionOutput ,
3- functionOutputKey ,
4- } from '@aws-amplify/backend-output-schemas' ;
5- import { AttributionMetadataStorage } from '@aws-amplify/backend-output-storage' ;
1+ import { FunctionOutput } from '@aws-amplify/backend-output-schemas' ;
62import {
73 AmplifyUserError ,
84 CallerDirectoryExtractor ,
@@ -20,19 +16,19 @@ import {
2016 GenerateContainerEntryProps ,
2117 LogLevel ,
2218 LogRetention ,
19+ ResourceAccessAcceptor ,
2320 ResourceAccessAcceptorFactory ,
2421 ResourceNameValidator ,
2522 ResourceProvider ,
26- SsmEnvironmentEntry ,
2723 StackProvider ,
2824} from '@aws-amplify/plugin-types' ;
2925import { Duration , Size , Stack , Tags } from 'aws-cdk-lib' ;
3026import { Rule } from 'aws-cdk-lib/aws-events' ;
3127import * as targets from 'aws-cdk-lib/aws-events-targets' ;
32- import { Policy } from 'aws-cdk-lib/aws-iam' ;
3328import {
3429 Architecture ,
3530 CfnFunction ,
31+ IFunction ,
3632 ILayerVersion ,
3733 LayerVersion ,
3834 Runtime ,
@@ -41,16 +37,19 @@ import { NodejsFunction, OutputFormat } from 'aws-cdk-lib/aws-lambda-nodejs';
4137import { Construct } from 'constructs' ;
4238import { readFileSync } from 'fs' ;
4339import { createRequire } from 'module' ;
44- import { fileURLToPath } from 'node:url' ;
4540import { EOL } from 'os' ;
4641import * as path from 'path' ;
4742import { FunctionEnvironmentTranslator } from './function_env_translator.js' ;
4843import { FunctionEnvironmentTypeGenerator } from './function_env_type_generator.js' ;
4944import { FunctionLayerArnParser } from './layer_parser.js' ;
5045import { convertLoggingOptionsToCDK } from './logging_options_parser.js' ;
5146import { convertFunctionSchedulesToRuleSchedules } from './schedule_parser.js' ;
52-
53- const functionStackType = 'function-Lambda' ;
47+ import {
48+ ProvidedFunctionFactory ,
49+ ProvidedFunctionProps ,
50+ } from './provided_function_factory.js' ;
51+ import { AmplifyFunctionBase } from './function_construct_base.js' ;
52+ import { FunctionResourceAccessAcceptor } from './resource_access_acceptor.js' ;
5453
5554export type AddEnvironmentFactory = {
5655 addEnvironment : ( key : string , value : string | BackendSecret ) => void ;
@@ -74,17 +73,38 @@ export type FunctionLogLevel = Extract<
7473> ;
7574export type FunctionLogRetention = LogRetention ;
7675
77- /**
78- * Entry point for defining a function in the Amplify ecosystem
79- */
80- export const defineFunction = (
81- props : FunctionProps = { }
76+ export function defineFunction (
77+ props ?: FunctionProps
8278) : ConstructFactory <
8379 ResourceProvider < FunctionResources > &
8480 ResourceAccessAcceptorFactory &
8581 AddEnvironmentFactory &
8682 StackProvider
87- > => new FunctionFactory ( props , new Error ( ) . stack ) ;
83+ > ;
84+ export function defineFunction (
85+ provider : ( scope : Construct ) => IFunction ,
86+ providerProps ?: ProvidedFunctionProps
87+ ) : ConstructFactory <
88+ ResourceProvider < FunctionResources > &
89+ ResourceAccessAcceptorFactory &
90+ StackProvider
91+ > ;
92+ /**
93+ * Entry point for defining a function in the Amplify ecosystem
94+ */
95+ // This is the "implementation overload", it's not visible in public api.
96+ // We have to use function notation instead of arrow notation.
97+ // Arrow notation does not support overloads.
98+ // eslint-disable-next-line no-restricted-syntax
99+ export function defineFunction (
100+ propsOrProvider : FunctionProps | ( ( scope : Construct ) => IFunction ) = { } ,
101+ providerProps ?: ProvidedFunctionProps
102+ ) : unknown {
103+ if ( propsOrProvider && typeof propsOrProvider === 'function' ) {
104+ return new ProvidedFunctionFactory ( propsOrProvider , providerProps ) ;
105+ }
106+ return new FunctionFactory ( propsOrProvider , new Error ( ) . stack ) ;
107+ }
88108
89109export type FunctionProps = {
90110 /**
@@ -507,14 +527,10 @@ class FunctionGenerator implements ConstructContainerEntryGenerator {
507527}
508528
509529class AmplifyFunction
510- extends Construct
511- implements
512- ResourceProvider < FunctionResources > ,
513- ResourceAccessAcceptorFactory ,
514- AddEnvironmentFactory
530+ extends AmplifyFunctionBase
531+ implements AddEnvironmentFactory
515532{
516533 readonly resources : FunctionResources ;
517- readonly stack : Stack ;
518534 private readonly functionEnvironmentTranslator : FunctionEnvironmentTranslator ;
519535 constructor (
520536 scope : Construct ,
@@ -523,9 +539,7 @@ class AmplifyFunction
523539 backendSecretResolver : BackendSecretResolver ,
524540 outputStorageStrategy : BackendOutputStorageStrategy < FunctionOutput >
525541 ) {
526- super ( scope , id ) ;
527-
528- this . stack = Stack . of ( scope ) ;
542+ super ( scope , id , outputStorageStrategy ) ;
529543
530544 const runtime = nodeVersionMap [ props . runtime ] ;
531545
@@ -647,52 +661,18 @@ class AmplifyFunction
647661 } ,
648662 } ;
649663
650- this . storeOutput ( outputStorageStrategy ) ;
651-
652- new AttributionMetadataStorage ( ) . storeAttributionMetadata (
653- Stack . of ( this ) ,
654- functionStackType ,
655- fileURLToPath ( new URL ( '../package.json' , import . meta. url ) )
656- ) ;
664+ this . storeOutput ( ) ;
657665 }
658666
659667 addEnvironment = ( key : string , value : string | BackendSecret ) => {
660668 this . functionEnvironmentTranslator . addEnvironmentEntry ( key , value ) ;
661669 } ;
662670
663- getResourceAccessAcceptor = ( ) => ( {
664- identifier : `${ this . node . id } LambdaResourceAccessAcceptor` ,
665- acceptResourceAccess : (
666- policy : Policy ,
667- ssmEnvironmentEntries : SsmEnvironmentEntry [ ]
668- ) => {
669- const role = this . resources . lambda . role ;
670- if ( ! role ) {
671- // This should never happen since we are using the Function L2 construct
672- throw new Error (
673- 'No execution role found to attach lambda permissions to'
674- ) ;
675- }
676- policy . attachToRole ( role ) ;
677- ssmEnvironmentEntries . forEach ( ( { name, path } ) => {
678- this . functionEnvironmentTranslator . addSsmEnvironmentEntry ( name , path ) ;
679- } ) ;
680- } ,
681- } ) ;
682-
683- /**
684- * Store storage outputs using provided strategy
685- */
686- private storeOutput = (
687- outputStorageStrategy : BackendOutputStorageStrategy < FunctionOutput >
688- ) : void => {
689- outputStorageStrategy . appendToBackendOutputList ( functionOutputKey , {
690- version : '1' ,
691- payload : {
692- definedFunctions : this . resources . lambda . functionName ,
693- } ,
694- } ) ;
695- } ;
671+ getResourceAccessAcceptor = ( ) : ResourceAccessAcceptor =>
672+ new FunctionResourceAccessAcceptor (
673+ this ,
674+ this . functionEnvironmentTranslator
675+ ) ;
696676}
697677
698678const isWholeNumberBetweenInclusive = (
0 commit comments