server.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #!/usr/bin/env node
  2. /* eslint-disable compat/compat */
  3. import http from 'node:http'
  4. import qs from 'node:querystring'
  5. import he from 'he'
  6. const e = he.encode
  7. function Header () {
  8. return `
  9. <!DOCTYPE html>
  10. <html>
  11. <head>
  12. <style>
  13. body { background: #f1f1f1; }
  14. main {
  15. padding: 20px;
  16. font: 12pt sans-serif;
  17. background: white;
  18. width: 800px;
  19. margin: auto;
  20. }
  21. </style>
  22. </head>
  23. <body>
  24. <main>
  25. `
  26. }
  27. function Footer () {
  28. return `
  29. </main>
  30. </body>
  31. </html>
  32. `
  33. }
  34. function FormFields (fields) {
  35. function Field ([name, value]) {
  36. if (name === 'transloadit') return ''
  37. let isValueJSON = false
  38. if (value.startsWith('{') || value.startsWith('[')) {
  39. try {
  40. // eslint-disable-next-line no-param-reassign
  41. value = JSON.stringify(
  42. JSON.parse(value),
  43. null,
  44. 2,
  45. )
  46. isValueJSON = true
  47. } catch {
  48. // Nothing
  49. }
  50. }
  51. const prettyValue = isValueJSON ? `
  52. <details open>
  53. <code>
  54. <pre style="max-width: 100%; max-height: 400px; white-space: pre-wrap; overflow: auto;">${e(value)}</pre>
  55. </code>
  56. </details>
  57. ` : e(value)
  58. return `
  59. <dt>${e(name)}</dt>
  60. <dd>
  61. ${prettyValue}
  62. </dd>
  63. `
  64. }
  65. return `
  66. <h1>Form Fields</h1>
  67. <dl>
  68. ${Object.entries(fields).map(Field).join('\n')}
  69. </dl>
  70. `
  71. }
  72. function UploadsList (uploads) {
  73. function Upload (upload) {
  74. return `<li>${e(upload.name)}</li>`
  75. }
  76. return `
  77. <ul>
  78. ${uploads.map(Upload).join('\n')}
  79. </ul>
  80. `
  81. }
  82. function ResultsList (results) {
  83. function Result (result) {
  84. return `<li>${e(result.name)} <a href="${result.ssl_url}" target="_blank">View</a></li>`
  85. }
  86. function ResultsSection (stepName) {
  87. return `
  88. <h2>${e(stepName)}</h2>
  89. <ul>
  90. ${results[stepName].map(Result).join('\n')}
  91. </ul>
  92. `
  93. }
  94. return Object.keys(results)
  95. .map(ResultsSection)
  96. .join('\n')
  97. }
  98. function AssemblyResult (assembly) {
  99. return `
  100. <h1>${e(assembly.assembly_id)} (${e(assembly.ok)})</h1>
  101. ${UploadsList(assembly.uploads)}
  102. ${ResultsList(assembly.results)}
  103. `
  104. }
  105. function onrequest (req, res) {
  106. if (req.url !== '/test') {
  107. res.writeHead(404, { 'content-type': 'text/html' })
  108. res.end('404')
  109. return
  110. }
  111. function onbody (body) {
  112. const fields = qs.parse(body)
  113. const result = JSON.parse(fields.uppyResult)
  114. const assemblies = result[0].transloadit
  115. res.setHeader('content-type', 'text/html')
  116. res.write(Header())
  117. res.write(FormFields(fields))
  118. assemblies.forEach((assembly) => {
  119. res.write(AssemblyResult(assembly))
  120. })
  121. res.end(Footer())
  122. }
  123. {
  124. let body = ''
  125. req.on('data', (chunk) => { body += chunk })
  126. req.on('end', () => {
  127. onbody(body)
  128. })
  129. }
  130. }
  131. /**
  132. * A very haxxor server that outputs some of the data it receives in a POST form parameter.
  133. */
  134. const server = http.createServer(onrequest)
  135. server.listen(9967)