189 lines
4.5 KiB
JavaScript
189 lines
4.5 KiB
JavaScript
|
"use strict";
|
||
|
|
||
|
Object.defineProperty(exports, "__esModule", {
|
||
|
value: true
|
||
|
});
|
||
|
exports.evalConfig = evalConfig;
|
||
|
exports.resolveConfigExport = resolveConfigExport;
|
||
|
|
||
|
function _fs() {
|
||
|
const data = require("fs");
|
||
|
|
||
|
_fs = function () {
|
||
|
return data;
|
||
|
};
|
||
|
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
function _requireFromString() {
|
||
|
const data = _interopRequireDefault(require("require-from-string"));
|
||
|
|
||
|
_requireFromString = function () {
|
||
|
return data;
|
||
|
};
|
||
|
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
function _sucrase() {
|
||
|
const data = require("sucrase");
|
||
|
|
||
|
_sucrase = function () {
|
||
|
return data;
|
||
|
};
|
||
|
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
function _Errors() {
|
||
|
const data = require("./Errors");
|
||
|
|
||
|
_Errors = function () {
|
||
|
return data;
|
||
|
};
|
||
|
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
function _Serialize() {
|
||
|
const data = require("./Serialize");
|
||
|
|
||
|
_Serialize = function () {
|
||
|
return data;
|
||
|
};
|
||
|
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||
|
|
||
|
/**
|
||
|
* Transpile and evaluate the dynamic config object.
|
||
|
* This method is shared between the standard reading method in getConfig, and the headless script.
|
||
|
*
|
||
|
* @param options configFile path to the dynamic app.config.*, request to send to the dynamic config if it exports a function.
|
||
|
* @returns the serialized and evaluated config along with the exported object type (object or function).
|
||
|
*/
|
||
|
function evalConfig(configFile, request) {
|
||
|
const contents = (0, _fs().readFileSync)(configFile, 'utf8');
|
||
|
let result;
|
||
|
|
||
|
try {
|
||
|
const {
|
||
|
code
|
||
|
} = (0, _sucrase().transform)(contents, {
|
||
|
filePath: configFile,
|
||
|
transforms: ['typescript', 'imports']
|
||
|
});
|
||
|
result = (0, _requireFromString().default)(code, configFile);
|
||
|
} catch (error) {
|
||
|
const location = extractLocationFromSyntaxError(error); // Apply a code frame preview to the error if possible, sucrase doesn't do this by default.
|
||
|
|
||
|
if (location) {
|
||
|
const {
|
||
|
codeFrameColumns
|
||
|
} = require('@babel/code-frame');
|
||
|
|
||
|
const codeFrame = codeFrameColumns(contents, {
|
||
|
start: error.loc
|
||
|
}, {
|
||
|
highlightCode: true
|
||
|
});
|
||
|
error.codeFrame = codeFrame;
|
||
|
error.message += `\n${codeFrame}`;
|
||
|
} else {
|
||
|
const importantStack = extractImportantStackFromNodeError(error);
|
||
|
|
||
|
if (importantStack) {
|
||
|
error.message += `\n${importantStack}`;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
throw error;
|
||
|
}
|
||
|
|
||
|
return resolveConfigExport(result, configFile, request);
|
||
|
}
|
||
|
|
||
|
function extractLocationFromSyntaxError(error) {
|
||
|
// sucrase provides the `loc` object
|
||
|
if (error.loc) {
|
||
|
return error.loc;
|
||
|
} // `SyntaxError`s provide the `lineNumber` and `columnNumber` properties
|
||
|
|
||
|
|
||
|
if ('lineNumber' in error && 'columnNumber' in error) {
|
||
|
return {
|
||
|
line: error.lineNumber,
|
||
|
column: error.columnNumber
|
||
|
};
|
||
|
}
|
||
|
|
||
|
return null;
|
||
|
} // These kinda errors often come from syntax errors in files that were imported by the main file.
|
||
|
// An example is a module that includes an import statement.
|
||
|
|
||
|
|
||
|
function extractImportantStackFromNodeError(error) {
|
||
|
if (isSyntaxError(error)) {
|
||
|
var _error$stack;
|
||
|
|
||
|
const traces = (_error$stack = error.stack) === null || _error$stack === void 0 ? void 0 : _error$stack.split('\n').filter(line => !line.startsWith(' at '));
|
||
|
if (!traces) return null; // Remove redundant line
|
||
|
|
||
|
if (traces[traces.length - 1].startsWith('SyntaxError:')) {
|
||
|
traces.pop();
|
||
|
}
|
||
|
|
||
|
return traces.join('\n');
|
||
|
}
|
||
|
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
function isSyntaxError(error) {
|
||
|
return error instanceof SyntaxError || error.constructor.name === 'SyntaxError';
|
||
|
}
|
||
|
/**
|
||
|
* - Resolve the exported contents of an Expo config (be it default or module.exports)
|
||
|
* - Assert no promise exports
|
||
|
* - Return config type
|
||
|
* - Serialize config
|
||
|
*
|
||
|
* @param result
|
||
|
* @param configFile
|
||
|
* @param request
|
||
|
*/
|
||
|
|
||
|
|
||
|
function resolveConfigExport(result, configFile, request) {
|
||
|
var _result;
|
||
|
|
||
|
if (result.default != null) {
|
||
|
result = result.default;
|
||
|
}
|
||
|
|
||
|
const exportedObjectType = typeof result;
|
||
|
|
||
|
if (typeof result === 'function') {
|
||
|
result = result(request);
|
||
|
}
|
||
|
|
||
|
if (result instanceof Promise) {
|
||
|
throw new (_Errors().ConfigError)(`Config file ${configFile} cannot return a Promise.`, 'INVALID_CONFIG');
|
||
|
} // If the expo object exists, ignore all other values.
|
||
|
|
||
|
|
||
|
if ((_result = result) !== null && _result !== void 0 && _result.expo) {
|
||
|
result = (0, _Serialize().serializeSkippingMods)(result.expo);
|
||
|
} else {
|
||
|
result = (0, _Serialize().serializeSkippingMods)(result);
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
config: result,
|
||
|
exportedObjectType
|
||
|
};
|
||
|
}
|
||
|
//# sourceMappingURL=evalConfig.js.map
|