11const Tail = require('tail').Tail;
2+ const { parse: parseDotenv } = require('dotenv');
23const chalk = require('chalk');
34const ignore = require("ignore");
45const tar = require("tar");
@@ -80,6 +81,7 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
8081 entrypoint: func.entrypoint,
8182 path: func.path,
8283 commands: func.commands,
84+ scopes: func.scopes ?? []
8385 };
8486
8587 drawTable([settings]);
@@ -110,7 +112,9 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
110112 fs.writeFileSync(errorsPath, '');
111113 }
112114
115+ const userVariables = {};
113116 const variables = {};
117+
114118 if(!noVariables) {
115119 try {
116120 const { variables: remoteVariables } = await paginate(functionsListVariables, {
@@ -120,12 +124,24 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
120124
121125 remoteVariables.forEach((v) => {
122126 variables[v.key] = v.value;
127+ userVariables[v.key] = v.value;
123128 });
124129 } catch(err) {
125130 warn("Remote variables not fetched. Production environment variables will not be avaiable. Reason: " + err.message);
126131 }
127132 }
128133
134+ const functionPath = path.join(process.cwd(), func.path);
135+ const envPath = path.join(functionPath, '.env');
136+ if(fs.existsSync(envPath)) {
137+ const env = parseDotenv(fs.readFileSync(envPath).toString() ?? '');
138+
139+ Object.keys(env).forEach((key) => {
140+ variables[key] = env[key];
141+ userVariables[key] = env[key];
142+ });
143+ }
144+
129145 variables['APPWRITE_FUNCTION_API_ENDPOINT'] = globalConfig.getFrom('endpoint');
130146 variables['APPWRITE_FUNCTION_ID'] = func.$id;
131147 variables['APPWRITE_FUNCTION_NAME'] = func.name;
@@ -148,6 +164,13 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
148164 headers['x-appwrite-user-jwt'] = JwtManager.userJwt ?? '';
149165 variables['OPEN_RUNTIMES_HEADERS'] = JSON.stringify(headers);
150166
167+ if(Object.keys(userVariables).length > 0) {
168+ drawTable(Object.keys(userVariables).map((key) => ({
169+ key,
170+ value: userVariables[key].split("").filter((_, i) => i < 16).map(() => "*").join("")
171+ })));
172+ }
173+
151174 await dockerPull(func);
152175
153176 new Tail(logsPath).on("line", function(data) {
@@ -158,10 +181,27 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
158181 });
159182
160183 if(!noReload) {
184+ const ignorer = ignore();
185+ ignorer.add('.appwrite');
186+ ignorer.add('code.tar.gz');
187+
188+ if (func.ignore) {
189+ ignorer.add(func.ignore);
190+ } else if (fs.existsSync(path.join(functionPath, '.gitignore'))) {
191+ ignorer.add(fs.readFileSync(path.join(functionPath, '.gitignore')).toString());
192+ }
193+
161194 chokidar.watch('.', {
162195 cwd: path.join(process.cwd(), func.path),
163196 ignoreInitial: true,
164- ignored: [ ...(func.ignore ?? []), 'code.tar.gz', '.appwrite', '.appwrite/', '.appwrite/*', '.appwrite/**', '.appwrite/*.*', '.appwrite/**/*.*' ]
197+ ignored: (xpath) => {
198+ const relativePath = path.relative(functionPath, xpath);
199+
200+ if(!relativePath) {
201+ return false;
202+ }
203+ return ignorer.ignores(relativePath);
204+ }
165205 }).on('all', async (_event, filePath) => {
166206 Queue.push(filePath);
167207 });
@@ -187,7 +227,6 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
187227 } else {
188228 log('Hot-swapping function.. Files with change are ' + files.join(', '));
189229
190- const functionPath = path.join(process.cwd(), func.path);
191230 const hotSwapPath = path.join(functionPath, '.appwrite/hot-swap');
192231 const buildPath = path.join(functionPath, '.appwrite/build.tar.gz');
193232
@@ -201,6 +240,7 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
201240
202241 await tar
203242 .extract({
243+ keep: true,
204244 gzip: true,
205245 sync: true,
206246 cwd: hotSwapPath,
@@ -211,6 +251,8 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
211251 ignorer.add('.appwrite');
212252 if (func.ignore) {
213253 ignorer.add(func.ignore);
254+ } else if (fs.existsSync(path.join(functionPath, '.gitignore'))) {
255+ ignorer.add(fs.readFileSync(path.join(functionPath, '.gitignore')).toString());
214256 }
215257
216258 const filesToCopy = getAllFiles(functionPath).map((file) => path.relative(functionPath, file)).filter((file) => !ignorer.ignores(file));
@@ -237,8 +279,6 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
237279 file: buildPath
238280 }, ['.']);
239281
240- fs.rmSync(hotSwapPath, { recursive: true, force: true });
241-
242282 await dockerStart(func, variables, port);
243283 }
244284 } catch(err) {
0 commit comments