publication-payload.spec.ts 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import { describe, expect, it } from 'vitest'
  2. import {
  3. hasTypeRTRemoteNavigation,
  4. isForbiddenPublicationFile,
  5. validateTarballPayload,
  6. } from './publication-payload.ts'
  7. function validateFixtureTarball(files: readonly string[]): () => void {
  8. return () => {
  9. validateTarballPayload(files, 'fixture.tgz')
  10. }
  11. }
  12. describe('publication payload policy', () => {
  13. it.each([
  14. 'lib/index.js',
  15. 'lib/types/index.d.ts',
  16. 'lib/styles/base.css',
  17. ])('accepts %s', (file) => {
  18. expect(isForbiddenPublicationFile(file)).toBe(false)
  19. })
  20. it.each([
  21. 'src',
  22. './src',
  23. 'src/',
  24. 'src/index.ts',
  25. './src/index.ts',
  26. String.raw`src\index.ts`,
  27. 'lib/types/index.d.ts.map',
  28. './lib/types/index.d.ts.map',
  29. ])('rejects static manifest path %s', (file) => {
  30. expect(isForbiddenPublicationFile(file)).toBe(true)
  31. })
  32. it('rejects source members in packed tarballs', () => {
  33. expect(validateFixtureTarball([
  34. 'package/package.json',
  35. 'package/src/index.ts',
  36. ])).toThrow('fixture.tgz publishes source file package/src/index.ts')
  37. })
  38. it('rejects declaration maps in packed tarballs', () => {
  39. expect(validateFixtureTarball([
  40. 'package/package.json',
  41. 'package/lib/types/index.d.ts.map',
  42. ])).toThrow('fixture.tgz publishes declaration map package/lib/types/index.d.ts.map')
  43. })
  44. it('accepts a clean packed tarball', () => {
  45. expect(validateFixtureTarball([
  46. 'package/package.json',
  47. 'package/lib/index.js',
  48. 'package/lib/types/index.d.ts',
  49. 'package/lib/styles/base.css',
  50. ])).not.toThrow()
  51. })
  52. it('allows only the TypeRT declaration map and its navigable source tree when requested', () => {
  53. const policy = { typeRTRemoteNavigation: true }
  54. expect(isForbiddenPublicationFile('src/index.ts', policy)).toBe(false)
  55. expect(isForbiddenPublicationFile('lib/typert.remote-client.d.ts.map', policy)).toBe(false)
  56. expect(isForbiddenPublicationFile('lib/types/index.d.ts.map', policy)).toBe(true)
  57. expect(() => {
  58. validateTarballPayload([
  59. 'package/lib/typert.remote-client.d.ts.map',
  60. 'package/src/index.ts',
  61. ], 'fixture.tgz', policy)
  62. }).not.toThrow()
  63. })
  64. it('recognizes only the canonical Host-for-Client export pair', () => {
  65. expect(hasTypeRTRemoteNavigation({
  66. exports: {
  67. './remote': {
  68. types: './lib/typert.remote-client.d.ts',
  69. default: './lib/typert.remote-client.js',
  70. },
  71. },
  72. })).toBe(true)
  73. expect(hasTypeRTRemoteNavigation({ exports: { './remote': './lib/remote.js' } })).toBe(false)
  74. })
  75. })