Repositorio del curso CCOM4030 el semestre B91 del proyecto Artesanías con el Instituto de Cultura

build.js 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /**
  2. * Module dependencies.
  3. */
  4. var base64 = require('base64-js');
  5. var xmlbuilder = require('xmlbuilder');
  6. /**
  7. * Module exports.
  8. */
  9. exports.build = build;
  10. /**
  11. * Accepts a `Date` instance and returns an ISO date string.
  12. *
  13. * @param {Date} d - Date instance to serialize
  14. * @returns {String} ISO date string representation of `d`
  15. * @api private
  16. */
  17. function ISODateString(d){
  18. function pad(n){
  19. return n < 10 ? '0' + n : n;
  20. }
  21. return d.getUTCFullYear()+'-'
  22. + pad(d.getUTCMonth()+1)+'-'
  23. + pad(d.getUTCDate())+'T'
  24. + pad(d.getUTCHours())+':'
  25. + pad(d.getUTCMinutes())+':'
  26. + pad(d.getUTCSeconds())+'Z';
  27. }
  28. /**
  29. * Returns the internal "type" of `obj` via the
  30. * `Object.prototype.toString()` trick.
  31. *
  32. * @param {Mixed} obj - any value
  33. * @returns {String} the internal "type" name
  34. * @api private
  35. */
  36. var toString = Object.prototype.toString;
  37. function type (obj) {
  38. var m = toString.call(obj).match(/\[object (.*)\]/);
  39. return m ? m[1] : m;
  40. }
  41. /**
  42. * Generate an XML plist string from the input object `obj`.
  43. *
  44. * @param {Object} obj - the object to convert
  45. * @param {Object} [opts] - optional options object
  46. * @returns {String} converted plist XML string
  47. * @api public
  48. */
  49. function build (obj, opts) {
  50. var XMLHDR = {
  51. version: '1.0',
  52. encoding: 'UTF-8'
  53. };
  54. var XMLDTD = {
  55. pubid: '-//Apple//DTD PLIST 1.0//EN',
  56. sysid: 'http://www.apple.com/DTDs/PropertyList-1.0.dtd'
  57. };
  58. var doc = xmlbuilder.create('plist');
  59. doc.dec(XMLHDR.version, XMLHDR.encoding, XMLHDR.standalone);
  60. doc.dtd(XMLDTD.pubid, XMLDTD.sysid);
  61. doc.att('version', '1.0');
  62. walk_obj(obj, doc);
  63. if (!opts) opts = {};
  64. // default `pretty` to `true`
  65. opts.pretty = opts.pretty !== false;
  66. return doc.end(opts);
  67. }
  68. /**
  69. * depth first, recursive traversal of a javascript object. when complete,
  70. * next_child contains a reference to the build XML object.
  71. *
  72. * @api private
  73. */
  74. function walk_obj(next, next_child) {
  75. var tag_type, i, prop;
  76. var name = type(next);
  77. if ('Undefined' == name) {
  78. return;
  79. } else if (Array.isArray(next)) {
  80. next_child = next_child.ele('array');
  81. for (i = 0; i < next.length; i++) {
  82. walk_obj(next[i], next_child);
  83. }
  84. } else if (Buffer.isBuffer(next)) {
  85. next_child.ele('data').raw(next.toString('base64'));
  86. } else if ('Object' == name) {
  87. next_child = next_child.ele('dict');
  88. for (prop in next) {
  89. if (next.hasOwnProperty(prop)) {
  90. next_child.ele('key').txt(prop);
  91. walk_obj(next[prop], next_child);
  92. }
  93. }
  94. } else if ('Number' == name) {
  95. // detect if this is an integer or real
  96. // TODO: add an ability to force one way or another via a "cast"
  97. tag_type = (next % 1 === 0) ? 'integer' : 'real';
  98. next_child.ele(tag_type).txt(next.toString());
  99. } else if ('Date' == name) {
  100. next_child.ele('date').txt(ISODateString(new Date(next)));
  101. } else if ('Boolean' == name) {
  102. next_child.ele(next ? 'true' : 'false');
  103. } else if ('String' == name) {
  104. next_child.ele('string').txt(next);
  105. } else if ('ArrayBuffer' == name) {
  106. next_child.ele('data').raw(base64.fromByteArray(next));
  107. } else if (next && next.buffer && 'ArrayBuffer' == type(next.buffer)) {
  108. // a typed array
  109. next_child.ele('data').raw(base64.fromByteArray(new Uint8Array(next.buffer), next_child));
  110. }
  111. }