1+ // Copyright (c) .NET Foundation. All rights reserved.
2+ // Licensed under the MIT License. See License.txt in the project root for license information.
3+
4+ var util = require ( 'util' ) ;
5+ var process = require ( 'process' ) ;
6+ var request = require ( './http/request' ) ;
7+ var response = require ( './http/response' ) ;
8+
9+ module . exports = {
10+ globalInitialization : globalInitialization ,
11+ clearRequireCache : clearRequireCache ,
12+ createFunction : createFunction
13+ } ;
14+
15+ function globalInitialization ( context , callback ) {
16+ process . on ( 'uncaughtException' , function ( err ) {
17+ context . handleUncaughtException ( err . stack ) ;
18+ } ) ;
19+ callback ( ) ;
20+ }
21+
22+ function clearRequireCache ( context , callback ) {
23+ Object . keys ( require . cache ) . forEach ( function ( key ) {
24+ delete require . cache [ key ] ;
25+ } ) ;
26+ callback ( ) ;
27+ }
28+
29+ function createFunction ( f ) {
30+ return function ( context , callback ) {
31+ // TEMP HACK: workaround for https://github.com/tjanczuk/edge/issues/325
32+ setImmediate ( ( ) => { } ) ;
33+
34+ f = getEntryPoint ( f , context ) ;
35+
36+ // configure loggers
37+ var origLog = context . log ;
38+ var logLevel = function ( traceLevel ) {
39+ return function ( ) {
40+ var message = util . format . apply ( null , arguments ) ;
41+ origLog ( { lvl : traceLevel , msg : message } ) ;
42+ } ;
43+ } ;
44+ // set default log to 'info'
45+ var log = logLevel ( 3 ) ;
46+ [ 'error' , 'warn' , 'info' , 'verbose' ] . forEach ( ( level , index ) => {
47+ var traceLevel = index + 1 ;
48+ log [ level ] = logLevel ( traceLevel ) ;
49+ } ) ;
50+ context . log = log ;
51+
52+ var origMetric = context . _metric ;
53+ delete context . _metric ;
54+ context . log . metric = function ( name , value , properties ) {
55+ origMetric ( { name : name , value : value , properties : properties } ) ;
56+ } ;
57+
58+ context . done = function ( err , returnValue ) {
59+ if ( context . _done ) {
60+ if ( context . _promise ) {
61+ context . log ( "Error: Choose either to return a promise or call 'done'. Do not use both in your script." ) ;
62+ } else {
63+ context . log ( "Error: 'done' has already been called. Please check your script for extraneous calls to 'done'." ) ;
64+ }
65+ return ;
66+ }
67+ context . _done = true ;
68+
69+ if ( err ) {
70+ callback ( err ) ;
71+ }
72+ else {
73+ if ( context . res && context . bindings . res === undefined ) {
74+ context . bindings . res = context . res ;
75+ }
76+
77+ // because Edge.JS interop doesn't flow new values added to objects,
78+ // we capture the binding values and pass them back as part of the
79+ // result
80+ var bindingValues = { } ;
81+ for ( var name in context . bindings ) {
82+ bindingValues [ name ] = context . bindings [ name ] ;
83+ }
84+
85+ var result = {
86+ returnValue : returnValue ,
87+ bindingValues : bindingValues
88+ } ;
89+ callback ( null , result ) ;
90+ }
91+ } ;
92+
93+ var inputs = context . _inputs ;
94+ inputs . unshift ( context ) ;
95+ delete context . _inputs ;
96+
97+ var lowercaseTrigger = context . _triggerType && context . _triggerType . toLowerCase ( ) ;
98+ switch ( lowercaseTrigger ) {
99+ case "httptrigger" :
100+ context . req = request ( context ) ;
101+ context . res = response ( context ) ;
102+ break ;
103+ }
104+ delete context . _triggerType ;
105+
106+ var result = f . apply ( null , inputs ) ;
107+ if ( result && util . isFunction ( result . then ) ) {
108+ context . _promise = true ;
109+ result . then ( ( result ) => context . done ( null , result ) )
110+ . catch ( ( err ) => context . done ( err ) ) ;
111+ }
112+ } ;
113+ }
114+
115+ function getEntryPoint ( f , context ) {
116+ if ( util . isObject ( f ) ) {
117+ if ( context . _entryPoint ) {
118+ // the module exports multiple functions
119+ // and an explicit entry point was named
120+ f = f [ context . _entryPoint ] ;
121+ delete context . _entryPoint ;
122+ }
123+ else if ( Object . keys ( f ) . length === 1 ) {
124+ // a single named function was exported
125+ var name = Object . keys ( f ) [ 0 ] ;
126+ f = f [ name ] ;
127+ }
128+ else {
129+ // finally, see if there is an exported function named
130+ // 'run' or 'index' by convention
131+ f = f . run || f . index ;
132+ }
133+ }
134+
135+ if ( ! util . isFunction ( f ) ) {
136+ throw "Unable to determine function entry point. If multiple functions are exported, " +
137+ "you must indicate the entry point, either by naming it 'run' or 'index', or by naming it " +
138+ "explicitly via the 'entryPoint' metadata property." ;
139+ }
140+
141+ return f ;
142+ }
0 commit comments