Skip to content

Commit eedfdc6

Browse files
authored
Merge pull request #8 from commenthol/chore-maintenance
chore: bump dependencies; commit cjs
2 parents 2fe92f8 + 6b025ba commit eedfdc6

File tree

9 files changed

+266
-38
lines changed

9 files changed

+266
-38
lines changed

.github/workflows/ci.yml

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node
2-
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
2+
# For more information see: https://github.com/marketplace/actions/setup-node-js-environment
33

44
name: CI
55

@@ -9,22 +9,22 @@ on:
99
pull_request:
1010
branches: [ master ]
1111

12+
env:
13+
CI: "true"
14+
1215
jobs:
1316
build:
14-
1517
runs-on: ubuntu-latest
16-
1718
strategy:
1819
matrix:
19-
node-version: [14.x, 16.x, 17.x]
20-
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
21-
20+
node: [ 20, 22 ]
21+
name: Node ${{ matrix.node }}
2222
steps:
23-
- uses: actions/checkout@v2
24-
- name: Use Node.js ${{ matrix.node-version }}
25-
uses: actions/setup-node@v2
26-
with:
27-
node-version: ${{ matrix.node-version }}
28-
# cache: 'npm'
29-
- run: npm install --ignore-scripts
30-
- run: npm run ci
23+
- uses: actions/checkout@v4
24+
- name: Setup Node ${{ matrix.node }}
25+
uses: actions/setup-node@v4
26+
with:
27+
node-version: ${{ matrix.node }}
28+
- run: npm install --ignore-scripts
29+
- run: npm run ci
30+

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,5 @@ node_modules/
22
coverage/
33
doc/
44
tmp/
5-
lib/
65
*.log
76
*.tgz

README.md

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
> Generate ical (.ics) files from date-holidays data
44
55
[![NPM version](https://badge.fury.io/js/date-holidays-ical.svg)](https://www.npmjs.com/package/date-holidays-ical/)
6-
[![Build Status](https://github.com/commenthol/date-holidays-ical/workflows/CI/badge.svg?branch=master&event=push)](https://github.com/commenthol/date-holidays-ical/actions/workflows/ci.yml?query=branch%3Amaster)
7-
6+
[![Build Status](https://github.com/commenthol/date-holidays-ical/actions/workflows/ci.yml/badge.svg)](https://github.com/commenthol/date-holidays-ical/actions/workflows/ci.yml)
87

98
This tool exports data from [date-holidays][] into iCal format.
109

@@ -15,14 +14,16 @@ This tool exports data from [date-holidays][] into iCal format.
1514
1615
Options:
1716
18-
-h, --help output usage information
19-
-V, --version output the version number
20-
-o, --out <file> write to file
21-
-y, --year <year> year
22-
-f, --fullday ical events are per full day
23-
-s, --showcode show country code in each ical summary
24-
-n, --name <name> instead of country code add your own name to each ical summary
25-
-q, --query query for available countries, states, regions by shortcode
17+
-h, --help this help
18+
-v, --version display version
19+
-o, --out file write to file
20+
-y, --year year year or year range
21+
-f, --fullday ical events are per full day
22+
-s, --showcode show country code in each ical summary
23+
-t, --transp ical events are all transparent
24+
-n, --name name instead of country code add your own name to each ical summary
25+
-q, --query query for available countries, states, regions by shortcode
26+
-l, --language language set language
2627
2728
Examples:
2829
@@ -34,6 +35,9 @@ This tool exports data from [date-holidays][] into iCal format.
3435
3536
Calender for 2017 New Zealand, Auckland Province:
3637
$ holiday-ical -f -y 2017 NZ.au
38+
39+
Calender for 2017 - 2019 New Zealand Auckland Province:
40+
$ holiday-ical -f -y 2017-2019 NZ.au
3741
```
3842

3943
Import the generated file into your calendar tool of choice.

lib/index.cjs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
'use strict';
2+
3+
var vcalendar = require('./vcalendar.cjs');
4+
var Holidays = require('date-holidays');
5+
6+
/**
7+
* @type { import('date-holidays').HolidaysTypes } HolidayTypes
8+
*/
9+
10+
function ical (opts) {
11+
const hd = new Holidays();
12+
13+
const self = {
14+
/**
15+
* Query for available countries, states
16+
* @param {String} [country]
17+
* @param {String} [state]
18+
* @param {string} [language]
19+
* @return {Object} shortcode, name pairs
20+
*/
21+
query: function (country, state, language) {
22+
return hd.query(country, state, language)
23+
},
24+
25+
/**
26+
* Initialite date-holidays
27+
* @param {String} country
28+
* @param {String} [state]
29+
* @param {String} [region]
30+
* @param {HolidayTypes.Options} [opts]
31+
* @return {Boolean} true if data could be initialized
32+
*/
33+
init: function (country, state, region, opts) {
34+
return hd.init(country, state, region, opts)
35+
},
36+
37+
/**
38+
* Convert to iCal Calendar
39+
* @param {String} [year]
40+
* @param {Object} [opts]
41+
* @return {String} iCal formatted Calendar
42+
*/
43+
calendar: function (year, opts) {
44+
let dates = [];
45+
if (year.includes('-')) {
46+
const [start, end] = year.split('-').map(Number);
47+
for (let tmp = start; tmp <= end; tmp++) {
48+
dates = dates.concat(hd.getHolidays(tmp));
49+
}
50+
} else {
51+
dates = hd.getHolidays(year);
52+
}
53+
54+
if (dates) {
55+
if (opts.name || opts.showcode) {
56+
let sc = [];
57+
if (opts.name) {
58+
sc = opts.name + ' ';
59+
} else if (opts.showcode) {
60+
'country,state,region'.split(',').forEach((p) => {
61+
let tmp;
62+
if ((tmp = hd.__conf[p])) {
63+
sc.push(tmp);
64+
}
65+
});
66+
sc = '(' + sc.join('.') + ') ';
67+
}
68+
dates.forEach(date => {
69+
date.name = sc + date.name;
70+
});
71+
}
72+
return vcalendar.vcalendar(dates, opts)
73+
}
74+
}
75+
};
76+
77+
return self
78+
}
79+
ical.vcalendar = vcalendar.vcalendar;
80+
81+
module.exports = ical;

lib/templates.cjs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
'use strict';
2+
3+
const tVcalendar = (vevents) => `BEGIN:VCALENDAR
4+
VERSION:2.0
5+
PRODID:-//date/holidays//NONSGML v1.0//EN
6+
METHOD:PUBLISH
7+
${vevents.join('')}END:VCALENDAR
8+
`;
9+
10+
const tVevent = (event) => `BEGIN:VEVENT
11+
CREATED:${event.created}
12+
LAST-MODIFIED:${event.created}
13+
DTSTAMP:${event.created}
14+
SUMMARY:${event.summary}
15+
DTSTART;VALUE=DATE:${event.dtstart}
16+
DTEND;VALUE=DATE:${event.dtend}${event.description ? `\nDESCRIPTION:${event.description}` : '\n'}
17+
TRANSP:${event.busy ? 'OPAQUE' : 'TRANSPARENT'}
18+
UID:${event.uid}
19+
END:VEVENT
20+
`;
21+
22+
exports.tVcalendar = tVcalendar;
23+
exports.tVevent = tVevent;

lib/vcalendar.cjs

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
'use strict';
2+
3+
var templates = require('./templates.cjs');
4+
5+
const random = () => Math.random().toString(16).substr(2);
6+
7+
/**
8+
* generate a simple uid
9+
* @private
10+
* @return {String} uid
11+
*/
12+
function uid (len = 16) {
13+
let str = '';
14+
while (str.length < len) str += random();
15+
return `${str.substr(0, len)}@date-holidays`
16+
}
17+
18+
/**
19+
* prefill a number with `len` zeroes
20+
* @private
21+
* @param {Number} num
22+
* @param {Number} [len]
23+
* @return {String} prefixed number
24+
*/
25+
function zero (num, len = 2) {
26+
const str = Array(len).join('0') + '' + num;
27+
return str.substring(str.length - len)
28+
}
29+
30+
/**
31+
* convert an Iso Date or String to Vcalendar Date
32+
* @param {Date|String} date
33+
* @return {String}
34+
* @example
35+
* ```
36+
* toIso('2016-01-02T11:29:54.925Z')
37+
* //> '20160102T112954Z'
38+
* ```
39+
*/
40+
function toISO (date) {
41+
if (typeof date === 'object') {
42+
date = date.toISOString();
43+
}
44+
return date
45+
.replace(/[:-]/g, '')
46+
.replace(/\.\d{3}/g, '')
47+
}
48+
49+
/**
50+
* convert a date string using offset days to a string
51+
* @private
52+
* @param {String} str
53+
* @param {Number} [offset] - offset to date described by str in milliseconds
54+
* @return {String} date string `YYYYMMDD`
55+
* @example
56+
* ```
57+
* toDay('2016-01-02 05:00:01')
58+
* //> '2016012'
59+
* ```
60+
*/
61+
function toDay (str, offset = 0) {
62+
// offset only full days
63+
offset = Math.ceil(offset / 86400000) * 86400000;
64+
65+
const ticks = +(new Date(str)) + (offset);
66+
const date = new Date(ticks);
67+
const s = zero(date.getFullYear(), 4) +
68+
zero(date.getMonth() + 1) +
69+
zero(date.getDate());
70+
return s
71+
}
72+
73+
/**
74+
* apply template on date object from `date-holidays`
75+
* @private
76+
* @param {Object} date
77+
* @param {Object} [opts]
78+
* @param {Boolean} [opts.fullday] - if `true` then event is treated to be on complete day
79+
* @param {Boolean} [opts.transp] - if `true` then event is treated to be always transparent
80+
* @return {String} a single vCalendar vevent
81+
*/
82+
function vevent (date, opts = {}) {
83+
if (!date) {
84+
return '\n'
85+
}
86+
87+
const now = (new Date());
88+
let dtstart = toISO(date.start);
89+
let dtend = toISO(date.end);
90+
const note = date.note || '';
91+
const type = date.type || '';
92+
93+
if (opts.fullday) {
94+
dtend = toDay(date.date, +date.end - +date.start);
95+
dtstart = toDay(date.date);
96+
}
97+
98+
const event = {
99+
created: toISO(now),
100+
summary: date.name,
101+
dtstart,
102+
dtend,
103+
description: type + (type && note ? ' - ' : '') + note,
104+
busy: !opts.transp && type === 'public',
105+
uid: uid()
106+
};
107+
108+
return templates.tVevent(event)
109+
}
110+
111+
/**
112+
* get vCalendar
113+
* @param {Object} date
114+
* @param {Object} [opts]
115+
* @return {String} vCalendar
116+
*/
117+
function vcalendar (dates, opts) {
118+
const vevents = dates.map(date => vevent(date, opts));
119+
return templates.tVcalendar(vevents)
120+
}
121+
122+
exports.vcalendar = vcalendar;

package.json

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,20 +51,20 @@
5151
"test": "mocha"
5252
},
5353
"dependencies": {
54-
"date-holidays": "^3.14.1"
54+
"date-holidays": "^3.23.17"
5555
},
5656
"devDependencies": {
57-
"c8": "^7.11.0",
58-
"eslint": "^7.32.0",
59-
"eslint-config-standard": "^16.0.3",
60-
"eslint-plugin-import": "^2.25.4",
57+
"c8": "^10.1.3",
58+
"eslint": "^8.57.1",
59+
"eslint-config-standard": "^17.1.0",
60+
"eslint-plugin-import": "^2.31.0",
6161
"eslint-plugin-node": "^11.1.0",
62-
"eslint-plugin-promise": "^5.2.0",
62+
"eslint-plugin-promise": "^6.6.0",
6363
"eslint-plugin-standard": "^5.0.0",
64-
"mocha": "^9.1.3",
65-
"npm-run-all": "^4.1.5",
66-
"rimraf": "^3.0.2",
67-
"rollup": "^2.63.0"
64+
"mocha": "^11.1.0",
65+
"npm-run-all2": "^7.0.2",
66+
"rimraf": "^6.0.1",
67+
"rollup": "^4.29.1"
6868
},
6969
"engines": {
7070
"node": ">=12.0.0"

src/index.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
import { vcalendar } from './vcalendar.js'
32
import Holidays from 'date-holidays'
43

src/vcalendar.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,8 @@ function vevent (date, opts = {}) {
9696
const event = {
9797
created: toISO(now),
9898
summary: date.name,
99-
dtstart: dtstart,
100-
dtend: dtend,
99+
dtstart,
100+
dtend,
101101
description: type + (type && note ? ' - ' : '') + note,
102102
busy: !opts.transp && type === 'public',
103103
uid: uid()

0 commit comments

Comments
 (0)