ts-types.js 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. const fs = require('fs')
  2. const gulp = require('gulp')
  3. const gutil = require('gulp-util')
  4. const watch = require('gulp-watch') // better than gulp.watch because detects new files
  5. const generateDts = require('dts-generator').default
  6. gulp.task('ts-types', exec)
  7. /*
  8. Waits for fullcalendar.js to be created/modified before computing,
  9. to avoid competing with and slowing down main build watcher.
  10. */
  11. gulp.task('ts-types:watch', function() {
  12. watch('dist/fullcalendar.js', exec)
  13. })
  14. function exec() {
  15. gutil.log('Computing TypeScript definitions file...')
  16. return generateDts({
  17. project: '.', // where the tsconfig is
  18. name: 'fullcalendar',
  19. main: 'fullcalendar/src/main',
  20. out: 'tmp/fullcalendar.d.ts'
  21. }).then(function() {
  22. let content = fs.readFileSync('tmp/fullcalendar.d.ts', { encoding: 'utf8' })
  23. content = filterModuleDeclaration(content)
  24. if (!fs.existsSync('dist')) {
  25. fs.mkdirSync('dist')
  26. }
  27. fs.writeFileSync('dist/fullcalendar.d.ts', content, { encoding: 'utf8' })
  28. gutil.log('Wrote TypeScript definitions file.')
  29. })
  30. }
  31. // Typedef Source Code Transformation Hacks
  32. // ----------------------------------------
  33. function filterModuleDeclaration(s) {
  34. return s.replace(
  35. /^declare module '([^']*)' \{([\S\s]*?)[\n\r]+\}/mg,
  36. function(whole, id, body) {
  37. return "declare module '" + filterModuleId(id) + "' {" + filterModuleBody(body) + '\n}'
  38. }
  39. )
  40. }
  41. function filterModuleId(id) {
  42. // fullcalendar/src/something/MyClass -> fullcalendar/MyClass
  43. return id.replace(
  44. /\/src\/([^/]*\/)*([A-Z][A-Za-z0-9]*)$/,
  45. '/$2'
  46. )
  47. }
  48. function filterModuleBody(s) {
  49. var defaultExportName
  50. // changes the name of the default export to `Default` and exports it as a *named* export.
  51. // this allows ambient declaration merging to grab onto it.
  52. // workaround for https://github.com/Microsoft/TypeScript/issues/14080
  53. s = s.replace(/export default( abstract)? class ([A-Z][A-Za-z0-9]*)/, function(m0, m1, m2) {
  54. defaultExportName = m2
  55. return 'export' + (m1 || '') + ' class Default'
  56. })
  57. if (defaultExportName) {
  58. // replace any references to the original class' name
  59. s = s.replace(new RegExp('\\b' + defaultExportName + '\\b'), 'Default')
  60. // still needs to be exported as default
  61. s += '\n\texport default Default;'
  62. }
  63. s = s.replace(/from '([^']*)'/g, function(whole, id) {
  64. return "from '" + filterModuleId(id) + "'"
  65. })
  66. return s
  67. }