diff --git a/README.md b/README.md
index 965772c8..1304ccae 100644
--- a/README.md
+++ b/README.md
@@ -781,6 +781,7 @@ $ yarn build
* [Jakub Roztocil](http://roztocil.co/)
([@jakubroztocil](http://twitter.com/jakubroztocil))
* Lars Schöning ([@lyschoening](http://twitter.com/lyschoening))
+* David Golightly ([@davigoli](http://twitter.com/davigoli))
Python `dateutil` is written by [Gustavo
Niemeyer](http://niemeyer.net/).
diff --git a/demo/demo.coffee b/demo/demo.coffee
deleted file mode 100644
index d4870c45..00000000
--- a/demo/demo.coffee
+++ /dev/null
@@ -1,218 +0,0 @@
-RRule = rrule.RRule
-
-getFormValues = ($form) ->
- paramObj = {}
- $.each $form.serializeArray(), (_, kv) ->
- if paramObj.hasOwnProperty(kv.name)
- paramObj[kv.name] = $.makeArray(paramObj[kv.name])
- paramObj[kv.name].push kv.value
- else
- paramObj[kv.name] = kv.value
-
- paramObj
-
-
-getOptionsCode = (options) ->
- days = [
- "RRule.MO"
- "RRule.TU"
- "RRule.WE"
- "RRule.TH"
- "RRule.FR"
- "RRule.SA"
- "RRule.SU"
- ]
-
- items = for k, v of options
- if v == null
- v = 'null'
- else if k is 'freq'
- v = 'RRule.' + RRule.FREQUENCIES[v]
- else if k in ["dtstart", "until"]
- v = "new Date(Date.UTC(" + [
- v.getUTCFullYear()
- v.getUTCMonth()
- v.getUTCDate()
- v.getUTCHours()
- v.getUTCMinutes()
- v.getUTCSeconds()
- ].join(', ') + "))"
- else if k is "byweekday"
- if v instanceof Array
- v = v.map (wday)->
- console.log 'wday', wday
- s = days[wday.weekday]
- if wday.n
- s+= '.nth(' + wday.n + ')'
- s
- else
- v = days[v.weekday]
- else if k is "wkst"
- if v is RRule.MO
- continue
- v = days[v.weekday]
-
- if v instanceof Array
- v = '[' + v.join(', ') + ']'
-
- console.log k, ' =', v
- "#{k}: #{v}"
-
- "{\n #{items.join(',\n ')}\n}"
-
-
-makeRows = (dates)->
- prevParts = []
- prevStates = []
- index = 1
- rows = for date in dates
-
- states = []
- parts = date.toUTCString().split(' ')
-
- cells = for part, i in parts
- if part != prevParts[i]
- states[i] = not prevStates[i]
- else
- states[i] = prevStates[i]
- cls = if states[i] then 'a' else 'b'
- "
#{ part } | "
-
- prevParts = parts
- prevStates = states
-
- "#{ index++ } | #{ cells.join('\n') }
"
-
- rows.join('\n\n')
-
-
-$ ->
- $tabs = $("#tabs")
-
- activateTab = ($a) ->
- id = $a.attr("href").split("#")[1]
- $tabs.find("a").removeClass "active"
- $a.addClass "active"
- $("#input-types section").hide()
- $("#input-types #" + id).show().find("input:first").focus().change()
-
-
- $("#input-types section").hide().each ->
- $("",
- href: "#" + $(this).attr("id")
- ).text($(this).find("h3").hide().text()).appendTo($tabs).on "click", ->
- activateTab $(this)
- false
-
- $(".examples code").on "click", ->
- $code = $(this)
- $code.parents("section:first").find("input").val($code.text()).change()
-
- $("input, select").on 'keyup change', ->
- $in = $(this)
- $section = $in.parents("section:first")
- inputMethod = $section.attr("id").split("-")[0]
-
- switch inputMethod
- when "text"
- makeRule = -> RRule.fromText($in.val())
- init = "RRule.fromText(\"" + @value + "\")"
- when "rfc"
- makeRule = => RRule.fromString(@value)
- init = "RRule.fromString(\"" + @value + "\")"
- when 'options'
- values = getFormValues($in.parents("form"))
- options = {}
- days = [
- RRule.MO
- RRule.TU
- RRule.WE
- RRule.TH
- RRule.FR
- RRule.SA
- RRule.SU
- ]
- getDay = (i)-> days[i]
-
- for key, value of values
-
- if not value
- continue
- else if key in ['dtstart', 'until']
- date = new Date(Date.parse(value + 'Z'))
- value = date
- else if key is 'byweekday'
- if value instanceof Array
- value = value.map(getDay)
- else
- value = getDay(value)
- else if key is 'tzid'
- value = value
- else if /^by/.test(key)
- if not (value instanceof Array)
- value = value.split(/[,\s]+/)
- value = (v for v in value when v)
- value = value.map (n) -> parseInt(n, 10)
- else
- value = parseInt(value, 10)
-
- if key is 'wkst'
- value = getDay(value)
-
- if key is 'interval' and (value is 1 or not value)
- continue
-
- options[key] = value
-
- makeRule = -> new RRule(options)
- init = "new RRule(" + getOptionsCode(options) + ")"
- console.log options
-
- $("#init").html init
- $("#rfc-output a").html ""
- $("#text-output a").html ""
- $("#options-output").html ""
- $("#dates").html ""
-
- try
- rule = makeRule()
- catch e
- $("#init").append($('').text('=> ' + String(e||null)))
- return
-
- rfc = rule.toString()
- text = rule.toText()
- $("#rfc-output a").text(rfc).attr('href', "#/rfc/#{rfc}")
- $("#text-output a").text(text).attr('href', "#/text/#{text}")
- $("#options-output").text(getOptionsCode(rule.origOptions))
- if inputMethod is 'options'
- $("#options-output").parents('tr').hide()
- else
- $("#options-output").parents('tr').show()
- max = 500
- dates = rule.all (date, i)->
- if not rule.options.count and i == max
- return false # That's enough
- return true
-
- html = makeRows dates
- if not rule.options.count
- html += """
- Showing first #{max} dates, set
- count to see more. |
- """
- $("#dates").html html
-
- activateTab $tabs.find("a:first")
-
- processHash = ->
- hash = location.hash.substring(1)
- if hash
- match = /^\/(rfc|text)\/(.+)$/.exec(hash)
- if match
- method = match[1] # rfc | text
- arg = match[2]
- activateTab($("a[href='##{method}-input']"))
- $("##{method}-input input:first").val(arg).change()
- processHash()
- $(window).on('hashchange', processHash)
diff --git a/demo/demo.ts b/demo/demo.ts
new file mode 100644
index 00000000..009381e4
--- /dev/null
+++ b/demo/demo.ts
@@ -0,0 +1,275 @@
+import * as $ from 'jquery'
+import {
+ RRule,
+ Options,
+ Weekday
+} from '../src/index'
+
+const getDay = (i: number) => [
+ RRule.MO,
+ RRule.TU,
+ RRule.WE,
+ RRule.TH,
+ RRule.FR,
+ RRule.SA,
+ RRule.SU
+][i]
+
+const makeArray = (s: string | string[]) =>
+ Array.isArray(s) ? s : [s]
+
+const getFormValues = function ($form: JQuery) {
+ const paramObj: { [K in keyof Partial]: string | string[] } = {}
+ $form.serializeArray().forEach(kv => {
+ const k = kv.name as keyof Options
+ if (paramObj.hasOwnProperty(k)) {
+ const v = makeArray(paramObj[k]!)
+ v.push(kv.value)
+ paramObj[k] = v
+ } else {
+ paramObj[k] = kv.value
+ }
+ })
+
+ return paramObj
+}
+
+const getOptionsCode = function (options: Partial) {
+ const days = [
+ 'RRule.MO',
+ 'RRule.TU',
+ 'RRule.WE',
+ 'RRule.TH',
+ 'RRule.FR',
+ 'RRule.SA',
+ 'RRule.SU'
+ ]
+
+ const items = Object.keys(options).map((k: keyof Options) => {
+ let v: unknown = options[k]
+ if (v === null) {
+ v = 'null'
+ } else if (k === 'freq') {
+ v = `RRule.${RRule.FREQUENCIES[v as number]}`
+ } else if (k === 'dtstart' || k === 'until') {
+ const d = v as Date
+ v = 'new Date(Date.UTC(' + [
+ d.getUTCFullYear(),
+ d.getUTCMonth(),
+ d.getUTCDate(),
+ d.getUTCHours(),
+ d.getUTCMinutes(),
+ d.getUTCSeconds()
+ ].join(', ') + '))'
+ } else if (k === 'byweekday') {
+ if (Array.isArray(v)) {
+ v = (v as Weekday[]).map(function (wday) {
+ console.log('wday', wday)
+ let s = days[wday.weekday]
+ if (wday.n) {
+ return s + `.nth(${wday.n})`
+ }
+ return s
+ })
+ } else {
+ const w = v as Weekday
+ v = days[w.weekday]
+ }
+ } else if (k === 'wkst') {
+ if (v === RRule.MO) {
+ return ''
+ }
+ const w = v as Weekday
+ v = days[w.weekday]
+ }
+
+ if (Array.isArray(v)) {
+ v = `[${v.join(', ')}]`
+ }
+
+ console.log(k, ' =', v)
+ return `${k}: ${v}`
+ })
+
+ return `{\n ${items.filter(v => !!v).join(',\n ')}\n}`
+}
+
+const makeRows = function (dates: Date[]) {
+ let prevParts: string[] = []
+ let prevStates: boolean[] = []
+
+ const rows = dates.map((date, index) => {
+ let states: boolean[] = []
+ let parts = date.toUTCString().split(' ')
+
+ const cells = parts.map((part, i) => {
+ if (part !== prevParts[i]) {
+ states[i] = !prevStates[i]
+ } else {
+ states[i] = prevStates[i]
+ }
+ const cls = states[i] ? 'a' : 'b'
+ return `${ part } | `
+ })
+
+ prevParts = parts
+ prevStates = states
+
+ return `${ index + 1 } | ${ cells.join('\n') }
`
+ })
+
+ return rows.join('\n\n')
+}
+
+$(function () {
+ const $tabs = $('#tabs')
+
+ const activateTab = function ($a: JQuery) {
+ const id = $a.attr('href')!.split('#')[1]
+ $tabs.find('a').removeClass('active')
+ $a.addClass('active')
+ $('#input-types section').hide()
+ return $(`#input-types #${id}`).show().find('input:first').trigger('focus').trigger('change')
+ }
+
+ $('#input-types section').hide().each(function () {
+ $('', {
+ href: `#${$(this).attr('id')}`
+ }).text($(this).find('h3').hide().text()).appendTo($tabs).on('click', function () {
+ activateTab($(this))
+ return false
+ })
+ })
+
+ $('.examples code').on('click', function () {
+ const $code = $(this)
+ return $code.parents('section:first').find('input').val($code.text()).trigger('change')
+ })
+
+ let init: string
+ let makeRule: () => RRule
+
+ $('input, select').on('keyup change', function () {
+ const $in = $(this)
+ const $section = $in.parents('section:first')
+ const inputMethod = $section.attr('id')!.split('-')[0]
+
+ switch (inputMethod) {
+ case 'text':
+ makeRule = () => RRule.fromText($in.val()!.toString())
+ init = `RRule.fromText("${(this as HTMLFormElement).value}")`
+ break
+ case 'rfc':
+ makeRule = () => RRule.fromString((this as HTMLFormElement).value)
+ init = `RRule.fromString("${(this as HTMLFormElement).value}")`
+ break
+ case 'options':
+ let values = getFormValues($in.parents('form'))
+ let options: Partial = {}
+
+ for (let k in values) {
+ const key = k as keyof Options
+
+ let value: string | string[] | Date | Weekday | Weekday[] | number | number[] = values[key]!
+ if (!value) {
+ continue
+ } else if (key === 'dtstart' || key === 'until') {
+ const date = new Date(Date.parse(value + 'Z'))
+ options[key] = date
+ } else if (key === 'byweekday') {
+ if (Array.isArray(value)) {
+ options[key] = value.map(i => getDay(parseInt(i, 10)))
+ } else {
+ options[key] = getDay(parseInt(value, 10))
+ }
+ } else if (/^by/.test(key)) {
+ if (!Array.isArray(value)) {
+ value = value.split(/[,\s]+/)
+ }
+ value = value.filter(v => v)
+ options[key] = value.map(n => parseInt(n, 10))
+ } else if (key === 'tzid') {
+ options[key] = value as string
+ } else {
+ options[key] = parseInt(value as string, 10)
+ }
+
+ if (key === 'wkst') {
+ options[key] = getDay(parseInt(value as string, 10))
+ }
+
+ if (key === 'interval') {
+ const i = parseInt(value as string, 10)
+ if (i === 1 || !value) {
+ continue
+ }
+
+ options[key] = i
+ }
+ }
+
+ makeRule = () => new RRule(options)
+ init = `new RRule(${getOptionsCode(options)})`
+ console.log(options)
+ break
+ }
+
+ $('#init').html(init)
+ $('#rfc-output a').html('')
+ $('#text-output a').html('')
+ $('#options-output').html('')
+ $('#dates').html('')
+
+ let rule: RRule
+ try {
+ rule = makeRule()
+ } catch (e) {
+ $('#init').append($('').text(`=> ${String(e || null)}`))
+ return
+ }
+
+ const rfc = rule.toString()
+ const text = rule.toText()
+ $('#rfc-output a').text(rfc).attr('href', `#/rfc/${rfc}`)
+ $('#text-output a').text(text).attr('href', `#/text/${text}`)
+ $('#options-output').text(getOptionsCode(rule.origOptions))
+ if (inputMethod === 'options') {
+ $('#options-output').parents('tr').hide()
+ } else {
+ $('#options-output').parents('tr').show()
+ }
+ const max = 500
+ const dates = rule.all(function (date, i) {
+ if (!rule.options.count && (i === max)) {
+ return false // That's enough
+ }
+ return true
+ })
+
+ let html = makeRows(dates)
+ if (!rule.options.count) {
+ html += `\
+Showing first ${max} dates, set
+count to see more. |
\
+`
+ }
+ return $('#dates').html(html)
+ })
+
+ activateTab($tabs.find('a:first'))
+
+ const processHash = function () {
+ const hash = location.hash.substring(1)
+ if (hash) {
+ const match = /^\/(rfc|text)\/(.+)$/.exec(hash)
+ if (match) {
+ const method = match[1] // rfc | text
+ const arg = match[2]
+ activateTab($(`a[href='#${method}-input']`))
+ return $(`#${method}-input input:first`).val(arg).trigger('change')
+ }
+ }
+ }
+ processHash()
+ return $(window).on('hashchange', processHash)
+})
diff --git a/demo/index.html b/demo/index.html
index e3f51fec..7a83376c 100644
--- a/demo/index.html
+++ b/demo/index.html
@@ -4,9 +4,7 @@
rrule.js demo
-
-
-
+
diff --git a/package.json b/package.json
index f54cefd3..2c6008ff 100644
--- a/package.json
+++ b/package.json
@@ -11,10 +11,10 @@
"icalendar",
"rfc"
],
- "author": "Jakub Roztocil and Lars Schöning",
+ "author": "Jakub Roztocil, Lars Schöning, and David Golightly",
"main": "dist/es5/rrule.js",
- "module": "dist/esm/index.js",
- "typings": "dist/esm/index.d.ts",
+ "module": "dist/esm/src/index.js",
+ "typings": "dist/esm/src/index.d.ts",
"repository": {
"type": "git",
"url": "git://github.com/jakubroztocil/rrule.git"
@@ -25,7 +25,7 @@
}
},
"scripts": {
- "build": "yarn lint && tsc && webpack && tsc dist/esm/*.d.ts",
+ "build": "yarn lint && tsc && webpack && tsc dist/esm/**/*.d.ts",
"lint": "yarn tslint --project . --fix --config tslint.json",
"test": "TS_NODE_PROJECT=tsconfig.test.json mocha **/*.test.ts",
"test-ci": "TS_NODE_PROJECT=tsconfig.test.json nyc mocha **/*.test.ts"
@@ -46,13 +46,12 @@
"devDependencies": {
"@types/assert": "^0.0.31",
"@types/chai": "^4.1.4",
+ "@types/jquery": "^3.3.29",
"@types/luxon": "^1.2.2",
"@types/mocha": "^5.2.5",
"@types/mockdate": "^2.0.0",
"@types/node": "^10.5.4",
"chai": "^4.1.2",
- "coffee-loader": "^0.9.0",
- "coffeescript": "^2.3.1",
"copy-webpack-plugin": "^4.5.2",
"coverage": "^0.0.0",
"html-webpack-plugin": "^3.2.0",
@@ -61,7 +60,7 @@
"mocha": "^5.2.0",
"mockdate": "^2.0.2",
"nyc": "^12.0.2",
- "source-map-loader": "^0.2.3",
+ "source-map-loader": "^0.2.4",
"source-map-support": "^0.5.8",
"ts-loader": "^4.4.2",
"ts-node": "^7.0.0",
diff --git a/src/iter.ts b/src/iter.ts
deleted file mode 100644
index 0bfeddf6..00000000
--- a/src/iter.ts
+++ /dev/null
@@ -1,243 +0,0 @@
-import IterResult from './iterresult'
-import { ParsedOptions, freqIsDailyOrGreater, QueryMethodTypes } from './types'
-import dateutil from './dateutil'
-import Iterinfo from './iterinfo/index'
-import RRule from './rrule'
-import { buildTimeset } from './parseoptions'
-import { notEmpty, includes, pymod, isPresent } from './helpers'
-import { DateWithZone } from './datewithzone'
-import { Time, DateTime as DTime } from './datetime'
-
-export function iter (iterResult: IterResult, options: ParsedOptions) {
- const {
- dtstart,
- freq,
- until,
- bysetpos
- } = options
-
- let counterDate = DTime.fromDate(dtstart)
-
- const ii = new Iterinfo(options)
- ii.rebuild(counterDate.year, counterDate.month)
-
- let timeset = makeTimeset(ii, counterDate, options)
-
- let count = options.count
-
- while (true) {
- let [dayset, start, end] = ii.getdayset(freq)(
- counterDate.year,
- counterDate.month,
- counterDate.day
- )
-
- let filtered = removeFilteredDays(dayset, start, end, ii, options)
-
- if (notEmpty(bysetpos)) {
- const poslist = buildPoslist(bysetpos, timeset!, start, end, ii, dayset)
-
- for (let j = 0; j < poslist.length; j++) {
- const res = poslist[j]
- if (until && res > until) {
- return emitResult(iterResult)
- }
-
- if (res >= dtstart) {
- const rezonedDate = rezoneIfNeeded(res, options)
- if (!iterResult.accept(rezonedDate)) {
- return emitResult(iterResult)
- }
-
- if (count) {
- --count
- if (!count) {
- return emitResult(iterResult)
- }
- }
- }
- }
- } else {
- for (let j = start; j < end; j++) {
- const currentDay = dayset[j]
- if (!isPresent(currentDay)) {
- continue
- }
-
- const date = dateutil.fromOrdinal(ii.yearordinal + currentDay)
- for (let k = 0; k < timeset!.length; k++) {
- const time = timeset![k]
- const res = dateutil.combine(date, time)
- if (until && res > until) {
- return emitResult(iterResult)
- }
-
- if (res >= dtstart) {
- const rezonedDate = rezoneIfNeeded(res, options)
- if (!iterResult.accept(rezonedDate)) {
- return emitResult(iterResult)
- }
-
- if (count) {
- --count
- if (!count) {
- return emitResult(iterResult)
- }
- }
- }
- }
- }
- }
- if (options.interval === 0) {
- return emitResult(iterResult)
- }
-
- // Handle frequency and interval
- counterDate.add(options, filtered)
-
- if (counterDate.year > dateutil.MAXYEAR) {
- return emitResult(iterResult)
- }
-
- if (!freqIsDailyOrGreater(freq)) {
- timeset = ii.gettimeset(freq)(counterDate.hour, counterDate.minute, counterDate.second, 0)
- }
-
- ii.rebuild(counterDate.year, counterDate.month)
- }
-}
-
-function isFiltered (
- ii: Iterinfo,
- currentDay: number,
- options: ParsedOptions
-): boolean {
- const {
- bymonth,
- byweekno,
- byweekday,
- byeaster,
- bymonthday,
- bynmonthday,
- byyearday
- } = options
-
- return (
- (notEmpty(bymonth) && !includes(bymonth, ii.mmask[currentDay])) ||
- (notEmpty(byweekno) && !ii.wnomask![currentDay]) ||
- (notEmpty(byweekday) && !includes(byweekday, ii.wdaymask[currentDay])) ||
- (notEmpty(ii.nwdaymask) && !ii.nwdaymask[currentDay]) ||
- (byeaster !== null && !includes(ii.eastermask!, currentDay)) ||
- ((notEmpty(bymonthday) || notEmpty(bynmonthday)) &&
- !includes(bymonthday, ii.mdaymask[currentDay]) &&
- !includes(bynmonthday, ii.nmdaymask[currentDay])) ||
- (notEmpty(byyearday) &&
- ((currentDay < ii.yearlen &&
- !includes(byyearday, currentDay + 1) &&
- !includes(byyearday, -ii.yearlen + currentDay)) ||
- (currentDay >= ii.yearlen &&
- !includes(byyearday, currentDay + 1 - ii.yearlen) &&
- !includes(byyearday, -ii.nextyearlen + currentDay - ii.yearlen))))
- )
-}
-
-function rezoneIfNeeded (date: Date, options: ParsedOptions) {
- return new DateWithZone(date, options.tzid).rezonedDate()
-}
-
-function emitResult (iterResult: IterResult) {
- return iterResult.getValue()
-}
-
-function removeFilteredDays (dayset: (number | null)[], start: number, end: number, ii: Iterinfo, options: ParsedOptions) {
- let filtered = false
- for (let dayCounter = start; dayCounter < end; dayCounter++) {
- let currentDay = dayset[dayCounter] as number
-
- filtered = isFiltered(
- ii,
- currentDay,
- options
- )
-
- if (filtered) dayset[currentDay] = null
- }
-
- return filtered
-}
-
-function makeTimeset (ii: Iterinfo, counterDate: DTime, options: ParsedOptions): Time[] | null {
- const {
- freq,
- byhour,
- byminute,
- bysecond
- } = options
-
- if (freqIsDailyOrGreater(freq)) {
- return buildTimeset(options)
- }
-
- if (
- (freq >= RRule.HOURLY &&
- notEmpty(byhour) &&
- !includes(byhour, counterDate.hour)) ||
- (freq >= RRule.MINUTELY &&
- notEmpty(byminute) &&
- !includes(byminute, counterDate.minute)) ||
- (freq >= RRule.SECONDLY &&
- notEmpty(bysecond) &&
- !includes(bysecond, counterDate.second))
- ) {
- return []
- }
-
- return ii.gettimeset(freq)(
- counterDate.hour,
- counterDate.minute,
- counterDate.second,
- counterDate.millisecond
- )
-}
-
-function buildPoslist (bysetpos: number[], timeset: Time[], start: number, end: number, ii: Iterinfo, dayset: (number | null)[]) {
- const poslist: Date[] = []
-
- for (let j = 0; j < bysetpos.length; j++) {
- let daypos: number
- let timepos: number
- const pos = bysetpos[j]
-
- if (pos < 0) {
- daypos = Math.floor(pos / timeset.length)
- timepos = pymod(pos, timeset.length)
- } else {
- daypos = Math.floor((pos - 1) / timeset.length)
- timepos = pymod(pos - 1, timeset.length)
- }
-
- const tmp = []
- for (let k = start; k < end; k++) {
- const val = dayset[k]
- if (!isPresent(val)) continue
- tmp.push(val)
- }
- let i: number
- if (daypos < 0) {
- i = tmp.slice(daypos)[0]
- } else {
- i = tmp[daypos]
- }
-
- const time = timeset[timepos]
- const date = dateutil.fromOrdinal(ii.yearordinal + i)
- const res = dateutil.combine(date, time)
- // XXX: can this ever be in the array?
- // - compare the actual date instead?
- if (!includes(poslist, res)) poslist.push(res)
- }
-
- dateutil.sort(poslist)
-
- return poslist
-}
diff --git a/src/iter/index.ts b/src/iter/index.ts
index 506b026b..fef6562b 100644
--- a/src/iter/index.ts
+++ b/src/iter/index.ts
@@ -13,10 +13,16 @@ export function iter (iterResult: IterResult, op
const {
dtstart,
freq,
+ interval,
until,
bysetpos
} = options
+ let count = options.count
+ if (count === 0 || interval === 0) {
+ return emitResult(iterResult)
+ }
+
let counterDate = DateTime.fromDate(dtstart)
const ii = new Iterinfo(options)
@@ -24,8 +30,6 @@ export function iter (iterResult: IterResult, op
let timeset = makeTimeset(ii, counterDate, options)
- let count = options.count
-
while (true) {
let [dayset, start, end] = ii.getdayset(freq)(
counterDate.year,
diff --git a/tsconfig.json b/tsconfig.json
index 836a7127..d0d3cb0c 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -2,6 +2,7 @@
"compilerOptions": {
"outDir": "./dist/esm",
"declaration": true,
+ "declarationMap": true,
"noImplicitAny": true,
"sourceMap": true,
"module": "es2015",
@@ -9,8 +10,8 @@
"target": "es5",
"jsx": "react",
"strictNullChecks": true,
- "rootDirs": ["./src/", "./test/"]
+ "rootDirs": ["./src/", "./test/", "./demo/"]
},
- "include": ["./src/**/*"],
+ "include": ["./src/**/*", "./demo/**/*"],
"exclude": ["node_modules", "./test/**/*"]
}
diff --git a/webpack.config.js b/webpack.config.js
index c59a46d7..42e04419 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -6,31 +6,43 @@ const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const paths = {
demo: {
- styles: path.resolve(__dirname, "demo/demo.css"),
- template: path.resolve(__dirname, "demo/index.html")
+ source: path.resolve(__dirname, 'demo'),
+ styles: path.resolve(__dirname, "demo", "demo.css"),
+ template: path.resolve(__dirname, "demo", "index.html")
},
- demoDist: path.resolve(__dirname, "dist"),
+ source: path.resolve(__dirname, 'src'),
+ demoDist: path.resolve(__dirname, "dist", "esm", "demo"),
es5: path.resolve(__dirname, "dist", "es5"),
esm: path.resolve(__dirname, "dist", "esm")
};
const commonConfig = {
output: {
- filename: "[name].js",
+ filename: '[name].js',
path: paths.es5,
- library: "rrule",
- libraryTarget: "umd",
+ library: 'rrule',
+ libraryTarget: 'umd',
globalObject: "typeof self !== 'undefined' ? self : this"
},
- devtool: "source-map",
- mode: "production",
+ devtool: 'source-map',
+ mode: 'production',
resolve: {
- extensions: [".js"]
+ extensions: ['.js', '.ts']
+ },
+ module: {
+ rules: [
+ {
+ exclude: /node_modules/,
+ loader: "ts-loader",
+ test: /\.ts$/
+ }
+ ]
},
optimization: {
minimize: true,
minimizer: [
new UglifyJsPlugin({
+ exclude: /\.ts$/,
include: /\.min\.js$/
})
]
@@ -39,8 +51,8 @@ const commonConfig = {
const rruleConfig = Object.assign({
entry: {
- rrule: path.join(paths.esm, "index.js"),
- 'rrule.min': path.join(paths.esm, "index.js")
+ rrule: path.join(paths.source, "index.ts"),
+ 'rrule.min': path.join(paths.source, "index.ts")
},
externals: {
luxon: 'luxon'
@@ -49,21 +61,26 @@ const rruleConfig = Object.assign({
const rruleWithLuxonConfig = Object.assign({
entry: {
- 'rrule-tz': path.join(paths.esm, "index.js"),
- 'rrule-tz.min': path.join(paths.esm, "index.js")
+ 'rrule-tz': path.join(paths.source, "index.ts"),
+ 'rrule-tz.min': path.join(paths.source, "index.ts")
},
}, commonConfig);
const demoConfig = {
entry: {
- demo: "./demo/demo.coffee"
+ demo: path.join(paths.demo.source, "demo.ts"),
},
module: {
rules: [
+ {
+ test: /\.js$/,
+ use: ["source-map-loader"],
+ enforce: "pre"
+ },
{
exclude: /node_modules/,
- loader: "coffee-loader",
- test: /\.coffee$/
+ loader: "ts-loader",
+ test: /\.ts$/
}
]
},
@@ -71,6 +88,9 @@ const demoConfig = {
filename: "demo.js",
path: paths.demoDist
},
+ resolve: {
+ extensions: [".js", ".ts"]
+ },
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
diff --git a/yarn.lock b/yarn.lock
index e3e58ded..1ab66d90 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -90,6 +90,12 @@
version "4.1.4"
resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.1.4.tgz#5ca073b330d90b4066d6ce18f60d57f2084ce8ca"
+"@types/jquery@^3.3.29":
+ version "3.3.29"
+ resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.3.29.tgz#680a2219ce3c9250483722fccf5570d1e2d08abd"
+ dependencies:
+ "@types/sizzle" "*"
+
"@types/luxon@^1.2.2":
version "1.2.2"
resolved "https://registry.yarnpkg.com/@types/luxon/-/luxon-1.2.2.tgz#3b402da20bd8ca357123851e062d2142cdbdd9bc"
@@ -106,6 +112,10 @@
version "10.5.4"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.5.4.tgz#6eccc158504357d1da91434d75e86acde94bb10b"
+"@types/sizzle@*":
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.2.tgz#a811b8c18e2babab7d542b3365887ae2e4d9de47"
+
"@webassemblyjs/ast@1.5.13":
version "1.5.13"
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.5.13.tgz#81155a570bd5803a30ec31436bc2c9c0ede38f25"
@@ -750,16 +760,6 @@ code-point-at@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
-coffee-loader@^0.9.0:
- version "0.9.0"
- resolved "https://registry.yarnpkg.com/coffee-loader/-/coffee-loader-0.9.0.tgz#6deabd336062ddc6d773da4dfd16367fc7107bd6"
- dependencies:
- loader-utils "^1.0.2"
-
-coffeescript@^2.3.1:
- version "2.3.1"
- resolved "https://registry.yarnpkg.com/coffeescript/-/coffeescript-2.3.1.tgz#a25f69c251d25805c9842e57fc94bfc453ef6aed"
-
collection-visit@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0"
@@ -2044,7 +2044,7 @@ loader-runner@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2"
-loader-utils@^0.2.16, loader-utils@~0.2.2:
+loader-utils@^0.2.16:
version "0.2.17"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348"
dependencies:
@@ -3147,13 +3147,12 @@ source-list-map@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085"
-source-map-loader@^0.2.3:
- version "0.2.3"
- resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-0.2.3.tgz#d4b0c8cd47d54edce3e6bfa0f523f452b5b0e521"
+source-map-loader@^0.2.4:
+ version "0.2.4"
+ resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-0.2.4.tgz#c18b0dc6e23bf66f6792437557c569a11e072271"
dependencies:
async "^2.5.0"
- loader-utils "~0.2.2"
- source-map "~0.6.1"
+ loader-utils "^1.1.0"
source-map-resolve@^0.5.0:
version "0.5.2"