get-method-name.js 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. /**
  2. * Module dependencies
  3. */
  4. var util = require('util');
  5. var flaverr = require('flaverr');
  6. var X_VALID_ECMA51_VARNAME = require('./private/X_VALID_ECMA51_VARNAME');
  7. var X_INVALID_CHARACTERS_IN_ECMA51_VARNAME = require('./private/X_INVALID_CHARACTERS_IN_ECMA51_VARNAME');
  8. var X_INVALID_FIRST_CHARACTER = require('./private/X_INVALID_FIRST_CHARACTER');
  9. /**
  10. * .getMethodName()
  11. *
  12. * Determine the method name for a machine: a conventional (ECMAScript-compatible)
  13. * method-name-looking thing, determined from its identity (dash-delimited words).
  14. *
  15. * @param {String} identity
  16. * @returns {String}
  17. * @throws {Error} E_RESERVED
  18. * If `identity` cannot be coerced into a valid machine identity (similar to a ECMAScript 5.1 variable name)
  19. */
  20. module.exports = function getMethodName(identity){
  21. // Save original string for error messages in this file.
  22. var original = identity;
  23. if (!identity || typeof identity !== 'string') {
  24. throw new Error('Cannot derive a method name from that (`'+util.inspect(identity)+'`). Please pass in the source identity as a non-empty string.');
  25. }
  26. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  27. // FUTURE: Better handling for special identities like `entry/login.js`
  28. // (e.g. maybe use something like `_loadedFrom` instead)
  29. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  30. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  31. // FUTURE: Include a general-case warning like we do currently in .pack() for any
  32. // identity that's technically allowed, but that might be weird (e.g. "inspect").
  33. // Note that if we do this, we'll need to extrapolate all revelant cases where we
  34. // currently warn in .pack() to avoid being annoying & logging the warning twice.
  35. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  36. // Camel-case any kebab-cased things.
  37. var str = identity.replace(/-+([a-z])/g, function($all, $1) {
  38. return $1.toUpperCase();
  39. });
  40. // Remove any other naughty characters
  41. str = str.replace(X_INVALID_CHARACTERS_IN_ECMA51_VARNAME, '');
  42. // Ensure `str` doesn't start with a character which is not a letter or $.
  43. // (NOTE: ECMA5.1 is actually more permissive than this, i.e. you can use weird
  44. // unicode characters, but we're preventing that here. Because... cm'on, really?)
  45. str = str.replace(X_INVALID_FIRST_CHARACTER, '');
  46. // One last check to make sure we ended up with a valid variable name:
  47. // (i.e. don't clash with special JavaScript keywords, like "delete")
  48. if (!str.match(X_VALID_ECMA51_VARNAME)) {
  49. throw flaverr('E_RESERVED', new Error('A method name cannot be derived from "'+original+'", because it collides with a JavaScript reserved word, or is otherwise probably a bad idea to use.'));
  50. }
  51. return str;
  52. };