1
+ const fs = require('fs');
2
+ const path = require('path');
1
3
const chalk = require('chalk');
2
4
const inquirer = require("inquirer");
3
5
const JSONbig = require("json-bigint")({ storeAsString: false });
@@ -12,7 +14,7 @@ const { proxyCreateFunctionRule, proxyCreateSiteRule, proxyListRules } = require
12
14
const { consoleVariables } = require('./console');
13
15
const { sdkForConsole } = require('../sdks')
14
16
const { functionsGet, functionsCreate, functionsUpdate, functionsCreateDeployment, functionsGetDeployment, functionsListVariables, functionsDeleteVariable, functionsCreateVariable } = require('./functions');
15
- const { sitesGet, sitesCreate, sitesUpdate, sitesCreateDeployment, sitesGetDeployment, sitesCreateVariable } = require('./sites');
17
+ const { sitesGet, sitesCreate, sitesUpdate, sitesCreateDeployment, sitesGetDeployment, sitesCreateVariable, sitesListVariables, sitesDeleteVariable } = require('./sites');
16
18
const {
17
19
databasesGet,
18
20
databasesCreate,
@@ -376,6 +378,50 @@ const getConfirmation = async () => {
376
378
};
377
379
const isEmpty = (value) => (value === null || value === undefined || (typeof value === "string" && value.trim().length === 0) || (Array.isArray(value) && value.length === 0));
378
380
381
+ const parseEnvFile = (filePath) => {
382
+ const envVars = [];
383
+
384
+ try {
385
+ if (!fs.existsSync(filePath)) {
386
+ return envVars;
387
+ }
388
+
389
+ const envContent = fs.readFileSync(filePath, 'utf8');
390
+ const lines = envContent.split('\n');
391
+
392
+ for (const line of lines) {
393
+ const trimmedLine = line.trim();
394
+
395
+ // Skip empty lines and comments
396
+ if (!trimmedLine || trimmedLine.startsWith('#')) {
397
+ continue;
398
+ }
399
+
400
+ // Parse KEY=VALUE format
401
+ const equalIndex = trimmedLine.indexOf('=');
402
+ if (equalIndex > 0) {
403
+ const key = trimmedLine.substring(0, equalIndex).trim();
404
+ let value = trimmedLine.substring(equalIndex + 1).trim();
405
+
406
+ // Remove surrounding quotes if present
407
+ if ((value.startsWith('"') && value.endsWith('"')) ||
408
+ (value.startsWith("'") && value.endsWith("'"))) {
409
+ value = value.slice(1, -1);
410
+ }
411
+
412
+ if (key) {
413
+ envVars.push({ key, value });
414
+ }
415
+ }
416
+ }
417
+ } catch (error) {
418
+ // Silently ignore file reading errors
419
+ console.warn(`Warning: Could not read .env file at ${filePath}: ${error.message}`);
420
+ }
421
+
422
+ return envVars;
423
+ };
424
+
379
425
const approveChanges = async (resource, resourceGetFunction, keys, resourceName, resourcePlural, skipKeys = [], secondId = '', secondResourceName = '') => {
380
426
log('Checking for changes ...');
381
427
const changes = [];
@@ -1047,7 +1093,7 @@ const pushSettings = async () => {
1047
1093
}
1048
1094
}
1049
1095
1050
- const pushSite = async({ siteId, async, code } = { returnOnZero: false }) => {
1096
+ const pushSite = async({ siteId, async, code, withVariables } = { returnOnZero: false }) => {
1051
1097
process.chdir(localConfig.configDirectoryPath)
1052
1098
1053
1099
const siteIds = [];
@@ -1180,7 +1226,6 @@ const pushSite = async({ siteId, async, code } = { returnOnZero: false }) => {
1180
1226
timeout: site.timeout,
1181
1227
enabled: site.enabled,
1182
1228
logging: site.logging,
1183
- vars: JSON.stringify(site.vars),
1184
1229
parseOutput: false
1185
1230
});
1186
1231
@@ -1213,16 +1258,39 @@ const pushSite = async({ siteId, async, code } = { returnOnZero: false }) => {
1213
1258
}
1214
1259
}
1215
1260
1216
- updaterRow.update({ status: 'Creating variables' }).replaceSpinner(SPINNER_ARC);
1261
+ if (withVariables) {
1262
+ updaterRow.update({ status: 'Creating variables' }).replaceSpinner(SPINNER_ARC);
1217
1263
1218
- await Promise.all((site['vars'] ?? []).map(async variable => {
1219
- await sitesCreateVariable({
1264
+ const { variables } = await paginate(sitesListVariables, {
1220
1265
siteId: site['$id'],
1221
- key: variable['key'],
1222
- value: variable['value'],
1223
1266
parseOutput: false
1224
- });
1225
- }));
1267
+ }, 100, 'variables');
1268
+
1269
+ await Promise.all(variables.map(async variable => {
1270
+ await sitesDeleteVariable({
1271
+ siteId: site['$id'],
1272
+ variableId: variable['$id'],
1273
+ parseOutput: false
1274
+ });
1275
+ }));
1276
+
1277
+ let result = await awaitPools.wipeVariables(site['$id']);
1278
+ if (!result) {
1279
+ updaterRow.fail({ errorMessage: `Variable deletion timed out.` })
1280
+ return;
1281
+ }
1282
+
1283
+ const envFileLocation = `${site['path']}/.env`;
1284
+ const envVariables = parseEnvFile(envFileLocation);
1285
+ await Promise.all(envVariables.map(async variable => {
1286
+ await sitesCreateVariable({
1287
+ siteId: site['$id'],
1288
+ key: variable['key'],
1289
+ value: variable['value'],
1290
+ parseOutput: false
1291
+ });
1292
+ }));
1293
+ }
1226
1294
1227
1295
if (code === false) {
1228
1296
successfullyPushed++;
@@ -1475,7 +1543,6 @@ const pushFunction = async ({ functionId, async, code, withVariables } = { retur
1475
1543
entrypoint: func.entrypoint,
1476
1544
commands: func.commands,
1477
1545
scopes: func.scopes,
1478
- vars: JSON.stringify(func.vars),
1479
1546
parseOutput: false
1480
1547
});
1481
1548
@@ -1530,13 +1597,16 @@ const pushFunction = async ({ functionId, async, code, withVariables } = { retur
1530
1597
return;
1531
1598
}
1532
1599
1533
- // Deploy local variables
1534
- await Promise.all((func['vars'] ?? []).map(async variable => {
1600
+ const envFileLocation = `${func['path']}/.env`;
1601
+ const envVariables = parseEnvFile(envFileLocation);
1602
+ await Promise.all(envVariables.map(async variable => {
1535
1603
await functionsCreateVariable({
1536
1604
functionId: func['$id'],
1537
- key: variable['key'],
1538
- value: variable['value'],
1539
- parseOutput: false
1605
+ variableId: ID.unique(),
1606
+ key: variable.key,
1607
+ value: variable.value,
1608
+ parseOutput: false,
1609
+ secret: false
1540
1610
});
1541
1611
}));
1542
1612
}
@@ -2065,6 +2135,7 @@ push
2065
2135
.option(`-f, --site-id <site -id >`, `ID of site to run`)
2066
2136
.option(`-A, --async`, `Don't wait for sites deployments status`)
2067
2137
.option("--no-code", "Don't push the site's code")
2138
+ .option("--with-variables", `Push site variables.`)
2068
2139
.action(actionRunner(pushSite));
2069
2140
2070
2141
push
0 commit comments