Skip to content

Commit

Permalink
feat(ics): removes download() method
Browse files Browse the repository at this point in the history
BREAKING CHANGE: the download() method is now removed from ICalendar.
  • Loading branch information
jshor committed Jan 10, 2023
1 parent 5e7dd8c commit 41ae072
Show file tree
Hide file tree
Showing 9 changed files with 14 additions and 270 deletions.
10 changes: 0 additions & 10 deletions docs/api/icalendar.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,13 +216,3 @@ const blob = new Blob([ics], {

FileSaver.saveAs(blob, 'my-calendar-event.ics')
```

## `download(fileName?: string)` <Badge text="Deprecated" type="warning" vertical="middle" />

* **`fileName: string`** - optional file name

Downloads a `.ics` file on the user's browser for use in local calendars and email clients.

:::warning Deprecation Notice
This feature is deprecated and will be removed in v8.
:::
10 changes: 3 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,19 @@
"dist"
],
"scripts": {
"build": "rollup -c",
"build": "rollup --config rollup.config.ts --configPlugin @rollup/plugin-typescript",
"test": "jest",
"lint": "yarn eslint ./src",
"docs:dev": "vuepress dev docs",
"docs:build": "vuepress build docs",
"release": "standard-version -n"
},
"dependencies": {
"file-saver": "^2.0.5"
},
"dependencies": {},
"devDependencies": {
"@commitlint/cli": "^17.3.0",
"@commitlint/config-conventional": "^17.3.0",
"@rollup/plugin-commonjs": "^23.0.2",
"@rollup/plugin-node-resolve": "^15.0.1",
"@rollup/plugin-typescript": "^9.0.2",
"@types/file-saver": "^2.0.5",
"@types/jest": "^29.2.3",
"@types/node": "^18.11.9",
"@typescript-eslint/eslint-plugin": "^5.44.0",
Expand All @@ -69,4 +65,4 @@
"resolutions": {
"vuepress-vite": "2.0.0-beta.53"
}
}
}
19 changes: 7 additions & 12 deletions rollup.config.mjs → rollup.config.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,28 @@
import { ModuleFormat, OutputOptions, RollupOptions } from 'rollup'
import { terser } from 'rollup-plugin-terser'
import { nodeResolve } from '@rollup/plugin-node-resolve'
import typescript from '@rollup/plugin-typescript'
import commonjs from '@rollup/plugin-commonjs'
import { terser } from 'rollup-plugin-terser'

const plugins = [
// TODO: this commonjs plugin will no longer be needed after file-saver is removed
// once commonjs plugin is removed, this file can also be renamed to rollup.config.ts
commonjs({
namedExports: {
'file-saver': ['saveAs']
}
}),
typescript(),
nodeResolve()
]

const getOutput = (format, ext, config) => ({
const getOutput = (format: ModuleFormat, ext: string, config: OutputOptions = {}): OutputOptions => ({
format,
sourcemap: true,
exports: 'named',
file: `dist/datebook.min.${ext}`,
...config
})

export default [
const options: RollupOptions[] = [
{
// UMD
input: 'src/index.ts',
plugins: plugins.concat(terser()),
output: getOutput('umd', 'js', {
name: 'datebook', // this is the name of the global object
name: 'datebook', // allows window.datebook to be accessible
esModule: false
})
},
Expand All @@ -43,3 +36,5 @@ export default [
]
}
]

export default options
16 changes: 0 additions & 16 deletions src/ICalendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,22 +203,6 @@ export default class ICalendar extends CalendarBase {
return this.addProperty('VALARM', value)
}

/**
* Downloads the rendered iCalendar.
*
* @deprecated This method will be removed in the next major release. See {@link https://datebook.dev/api/icalendar.html#example-for-downloading-an-ics-file}.
* @remark Only works in browsers.
* @param {string} fileName optional explicit file name, if not provided then will be constructed from title
*/
public download = (fileName?: string): void => {
console.warn([
'ICalendar.download() is deprecated and will be removed in the next major release.',
'See https://datebook.dev/api/icalendar.html#example-for-downloading-an-ics-file for more info on how to download ICS files.'
].join(' '))

ics.download(fileName || ics.getFileName(this.title), this.render())
}

/**
* Generates the iCalendar data.
*
Expand Down
40 changes: 0 additions & 40 deletions src/__tests__/ICalendar.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,46 +182,6 @@ describe('ICalendar', () => {
})
})

describe('download()', () => {
it('should call render and the download util', () => {
const obj = new ICalendar(baseOpts)
const mockRender = 'renderedstring'

jest
.spyOn(ics, 'download')
.mockImplementation(jest.fn())
jest
.spyOn(obj, 'render')
.mockReturnValue(mockRender)

obj.download()

expect(obj.render).toHaveBeenCalledTimes(1)
expect(ics.download).toHaveBeenCalledTimes(1)
expect(ics.download).toHaveBeenCalledWith(`${baseOpts.title}.ics`, mockRender)
})
})

describe('download(filename)', () => {
it('should call render and the download util with provided filename', () => {
const obj = new ICalendar(baseOpts)
const mockRender = 'renderedstring'

jest
.spyOn(ics, 'download')
.mockImplementation(jest.fn())
jest
.spyOn(obj, 'render')
.mockReturnValue(mockRender)

obj.download('test.ics')

expect(obj.render).toHaveBeenCalledTimes(1)
expect(ics.download).toHaveBeenCalledTimes(1)
expect(ics.download).toHaveBeenCalledWith('test.ics', mockRender)
})
})

describe('render()', () => {
const mockUuid = 'mock-uuid-1234'

Expand Down
73 changes: 0 additions & 73 deletions src/utils/__tests__/ics.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,29 +30,6 @@ describe('IcsUtil', () => {
})
})

describe('getBlob()', () => {
it('should set the MIME type as `application/octet-stream`', () => {
const icsData = 'foobar'
const blob: Blob = ics.getBlob(icsData)

expect(blob.type).toEqual('application/octet-stream')
})
})

describe('getFileName()', () => {
it('should return event.ics if no title is specified', () => {
expect(ics.getFileName('')).toBe('event.ics')
})

it('should remove all non-alphanumeric except underscore', () => {
const testTitle = 'abcdef_ABCDEF1234567890-.,/[])(!@*#$^%^'
const expectedFileName = 'abcdef_ABCDEF1234567890.ics'
const filename = ics.getFileName(testTitle)

expect(filename).toBe(expectedFileName)
})
})

describe('getUid()', () => {
it('should return a base-32 random UID', () => {
jest
Expand Down Expand Up @@ -113,54 +90,4 @@ describe('IcsUtil', () => {
expect(actualRrule).toBe(expectedRrule)
})
})

describe.skip('download()', () => {
beforeEach(() => {
jest
.spyOn(FileSaver, 'saveAs')
.mockImplementation(jest.fn())
})

afterEach(() => {
Object.defineProperty(window, 'navigator', {
value: {
userAgent: 'trident'
},
writable: true
})
})

it('should invoke FileSaver.saveAs() on iOS Chrome', () => {
Object.defineProperty(navigator, 'userAgent', {
value: 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) CriOS/56.0.2924.75 Mobile/14E5239e Safari/602.1',
writable: true
})

ics.download('july 4.ics', 'foobar')

expect(FileSaver.saveAs).toHaveBeenCalledTimes(1)
})

it('should invoke FileSaver.saveAs() on iOS Firefox', () => {
Object.defineProperty(navigator, 'userAgent', {
value: 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) FxiOS/11.0b9935 Mobile/15E216 Safari/605.1.15',
writable: true
})

ics.download('july 4.ics', 'foobar')

expect(FileSaver.saveAs).toHaveBeenCalledTimes(1)
})

it('should invoke FileSaver.saveAs() on non-iOS browsers', () => {
Object.defineProperty(navigator, 'userAgent', {
value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.74 Safari/537.36 Edg/79.0.309.43',
writable: true
})

ics.download('july 4.ics', 'foobar')

expect(FileSaver.saveAs).toHaveBeenCalledTimes(1)
})
})
})
45 changes: 1 addition & 44 deletions src/utils/ics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,6 @@ const formatText = (str = ''): string => {
.replace(/[,;]/g, '\\$&')
}

/**
* The name of the file will be the event title with alphanumeric chars with the extension `.ics`.
*
* @deprecated
* @param {string} icsData
* @returns {Blob}
*/
const getBlob = (icsData: string): Blob => {
return new Blob([icsData], {
type: 'application/octet-stream' // TODO: change to text/calendar?
})
}

/**
* Transforms given string to be valid file name.
*
* @deprecated
* @param {string} title
* @returns {string}
*/
const getFileName = (title: string): string => {
if (!title) {
return 'event.ics'
}
return `${title.replace(/[^\w ]/g, '')}.ics`
}

/**
* Returns a random base 36 hash for iCal UID.
*
Expand Down Expand Up @@ -87,25 +60,9 @@ const getRrule = (recurrence: CalendarRecurrence): string => {
return data.toIcsParamString(rrule)
}

/**
* Downloads the given ics as an iCalendar file.
*
* @deprecated
* @param {string} fileName - filename of the event file
* @param {string} data - ics data
*/
const download = (fileName: string, data: string): void => {
const blob = getBlob(data)

FileSaver.saveAs(blob, fileName)
}

export default {
formatText,
getBlob,
getFileName,
getUid,
getProdId,
getRrule,
download
getRrule
}
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"skipLibCheck": true
},
"include": [
"rollup.config.ts",
"./src/**/*.ts"
],
"exclude": [
Expand Down
Loading

0 comments on commit 41ae072

Please sign in to comment.