get-amd-module-type
Version:
Get the type of an AMD module used for an AST node or within a file
98 lines (80 loc) • 2.29 kB
JavaScript
;
const fs = require('fs');
const Walker = require('node-source-walk');
const types = require('ast-module-types');
/**
* Asynchronously identifies the AMD module type of the given file
*
* @param {Object|String} file - filename
* @param {Function} callback - Executed with (error, type)
*
* @example
* define('name', [deps], func) 'named'
* define([deps], func) 'deps'
* define(func(require)) 'factory'
* define({}) 'nodeps'
*
* @returns {String|null} the supported type of module syntax used, or null
*/
module.exports = function(file, callback) {
if (!file) throw new Error('filename missing');
if (!callback) throw new Error('callback missing');
// eslint-disable-next-line n/prefer-promises/fs
fs.readFile(file, 'utf8', (error, data) => {
if (error) return callback(error);
let type;
try {
type = fromSource(data);
} catch (error) {
return callback(error);
}
if (callback) callback(null, type);
});
};
/**
* Determine the module type from an AST node
*
* @param {Object} node
* @return {String | null}
*/
function fromAST(node) {
if (types.isNamedForm(node)) return 'named';
if (types.isDependencyForm(node)) return 'deps';
if (types.isREMForm(node)) return 'rem';
if (types.isFactoryForm(node)) return 'factory';
if (types.isNoDependencyForm(node)) return 'nodeps';
if (types.isAMDDriverScriptRequire(node)) return 'driver';
return null;
}
/**
* Determine the module type by walking the supplied source code's AST
*
* @param {String} source
* @return {String|null}
*/
function fromSource(source) {
if (source === undefined) throw new Error('source missing');
const walker = new Walker();
let type;
walker.walk(source, node => {
type = fromAST(node);
if (type) {
walker.stopWalking();
}
});
return type;
}
/**
* Synchronously determine the module type of the given filepath.
*
* @param {String} file - filename
* @return {String|null}
*/
function sync(file) {
if (!file) throw new Error('filename missing');
const source = fs.readFileSync(file, 'utf8');
return fromSource(source);
}
module.exports.fromAST = fromAST;
module.exports.fromSource = fromSource;
module.exports.sync = sync;