server.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. const canPromise = require('./can-promise')
  2. const QRCode = require('./core/qrcode')
  3. const PngRenderer = require('./renderer/png')
  4. const Utf8Renderer = require('./renderer/utf8')
  5. const TerminalRenderer = require('./renderer/terminal')
  6. const SvgRenderer = require('./renderer/svg')
  7. function checkParams (text, opts, cb) {
  8. if (typeof text === 'undefined') {
  9. throw new Error('String required as first argument')
  10. }
  11. if (typeof cb === 'undefined') {
  12. cb = opts
  13. opts = {}
  14. }
  15. if (typeof cb !== 'function') {
  16. if (!canPromise()) {
  17. throw new Error('Callback required as last argument')
  18. } else {
  19. opts = cb || {}
  20. cb = null
  21. }
  22. }
  23. return {
  24. opts: opts,
  25. cb: cb
  26. }
  27. }
  28. function getTypeFromFilename (path) {
  29. return path.slice((path.lastIndexOf('.') - 1 >>> 0) + 2).toLowerCase()
  30. }
  31. function getRendererFromType (type) {
  32. switch (type) {
  33. case 'svg':
  34. return SvgRenderer
  35. case 'txt':
  36. case 'utf8':
  37. return Utf8Renderer
  38. case 'png':
  39. case 'image/png':
  40. default:
  41. return PngRenderer
  42. }
  43. }
  44. function getStringRendererFromType (type) {
  45. switch (type) {
  46. case 'svg':
  47. return SvgRenderer
  48. case 'terminal':
  49. return TerminalRenderer
  50. case 'utf8':
  51. default:
  52. return Utf8Renderer
  53. }
  54. }
  55. function render (renderFunc, text, params) {
  56. if (!params.cb) {
  57. return new Promise(function (resolve, reject) {
  58. try {
  59. const data = QRCode.create(text, params.opts)
  60. return renderFunc(data, params.opts, function (err, data) {
  61. return err ? reject(err) : resolve(data)
  62. })
  63. } catch (e) {
  64. reject(e)
  65. }
  66. })
  67. }
  68. try {
  69. const data = QRCode.create(text, params.opts)
  70. return renderFunc(data, params.opts, params.cb)
  71. } catch (e) {
  72. params.cb(e)
  73. }
  74. }
  75. exports.create = QRCode.create
  76. exports.toCanvas = require('./browser').toCanvas
  77. exports.toString = function toString (text, opts, cb) {
  78. const params = checkParams(text, opts, cb)
  79. const type = params.opts ? params.opts.type : undefined
  80. const renderer = getStringRendererFromType(type)
  81. return render(renderer.render, text, params)
  82. }
  83. exports.toDataURL = function toDataURL (text, opts, cb) {
  84. const params = checkParams(text, opts, cb)
  85. const renderer = getRendererFromType(params.opts.type)
  86. return render(renderer.renderToDataURL, text, params)
  87. }
  88. exports.toBuffer = function toBuffer (text, opts, cb) {
  89. const params = checkParams(text, opts, cb)
  90. const renderer = getRendererFromType(params.opts.type)
  91. return render(renderer.renderToBuffer, text, params)
  92. }
  93. exports.toFile = function toFile (path, text, opts, cb) {
  94. if (typeof path !== 'string' || !(typeof text === 'string' || typeof text === 'object')) {
  95. throw new Error('Invalid argument')
  96. }
  97. if ((arguments.length < 3) && !canPromise()) {
  98. throw new Error('Too few arguments provided')
  99. }
  100. const params = checkParams(text, opts, cb)
  101. const type = params.opts.type || getTypeFromFilename(path)
  102. const renderer = getRendererFromType(type)
  103. const renderToFile = renderer.renderToFile.bind(null, path)
  104. return render(renderToFile, text, params)
  105. }
  106. exports.toFileStream = function toFileStream (stream, text, opts) {
  107. if (arguments.length < 2) {
  108. throw new Error('Too few arguments provided')
  109. }
  110. const params = checkParams(text, opts, stream.emit.bind(stream, 'error'))
  111. const renderer = getRendererFromType('png') // Only png support for now
  112. const renderToFileStream = renderer.renderToFileStream.bind(null, stream)
  113. render(renderToFileStream, text, params)
  114. }