Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: bump dependencies; commit cjs #8

Merged
merged 2 commits into from
Jan 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# 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
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
# For more information see: https://github.com/marketplace/actions/setup-node-js-environment

name: CI

Expand All @@ -9,22 +9,22 @@ on:
pull_request:
branches: [ master ]

env:
CI: "true"

jobs:
build:

runs-on: ubuntu-latest

strategy:
matrix:
node-version: [14.x, 16.x, 17.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/

node: [ 20, 22 ]
name: Node ${{ matrix.node }}
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
# cache: 'npm'
- run: npm install --ignore-scripts
- run: npm run ci
- uses: actions/checkout@v4
- name: Setup Node ${{ matrix.node }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: npm install --ignore-scripts
- run: npm run ci

1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@ node_modules/
coverage/
doc/
tmp/
lib/
*.log
*.tgz
24 changes: 14 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
> Generate ical (.ics) files from date-holidays data

[![NPM version](https://badge.fury.io/js/date-holidays-ical.svg)](https://www.npmjs.com/package/date-holidays-ical/)
[![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)

[![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)

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

Expand All @@ -15,14 +14,16 @@ This tool exports data from [date-holidays][] into iCal format.

Options:

-h, --help output usage information
-V, --version output the version number
-o, --out <file> write to file
-y, --year <year> year
-f, --fullday ical events are per full day
-s, --showcode show country code in each ical summary
-n, --name <name> instead of country code add your own name to each ical summary
-q, --query query for available countries, states, regions by shortcode
-h, --help this help
-v, --version display version
-o, --out file write to file
-y, --year year year or year range
-f, --fullday ical events are per full day
-s, --showcode show country code in each ical summary
-t, --transp ical events are all transparent
-n, --name name instead of country code add your own name to each ical summary
-q, --query query for available countries, states, regions by shortcode
-l, --language language set language

Examples:

Expand All @@ -34,6 +35,9 @@ This tool exports data from [date-holidays][] into iCal format.

Calender for 2017 New Zealand, Auckland Province:
$ holiday-ical -f -y 2017 NZ.au

Calender for 2017 - 2019 New Zealand Auckland Province:
$ holiday-ical -f -y 2017-2019 NZ.au
```

Import the generated file into your calendar tool of choice.
Expand Down
81 changes: 81 additions & 0 deletions lib/index.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
'use strict';

var vcalendar = require('./vcalendar.cjs');
var Holidays = require('date-holidays');

/**
* @type { import('date-holidays').HolidaysTypes } HolidayTypes
*/

function ical (opts) {
const hd = new Holidays();

const self = {
/**
* Query for available countries, states
* @param {String} [country]
* @param {String} [state]
* @param {string} [language]
* @return {Object} shortcode, name pairs
*/
query: function (country, state, language) {
return hd.query(country, state, language)
},

/**
* Initialite date-holidays
* @param {String} country
* @param {String} [state]
* @param {String} [region]
* @param {HolidayTypes.Options} [opts]
* @return {Boolean} true if data could be initialized
*/
init: function (country, state, region, opts) {
return hd.init(country, state, region, opts)
},

/**
* Convert to iCal Calendar
* @param {String} [year]
* @param {Object} [opts]
* @return {String} iCal formatted Calendar
*/
calendar: function (year, opts) {
let dates = [];
if (year.includes('-')) {
const [start, end] = year.split('-').map(Number);
for (let tmp = start; tmp <= end; tmp++) {
dates = dates.concat(hd.getHolidays(tmp));
}
} else {
dates = hd.getHolidays(year);
}

if (dates) {
if (opts.name || opts.showcode) {
let sc = [];
if (opts.name) {
sc = opts.name + ' ';
} else if (opts.showcode) {
'country,state,region'.split(',').forEach((p) => {
let tmp;
if ((tmp = hd.__conf[p])) {
sc.push(tmp);
}
});
sc = '(' + sc.join('.') + ') ';
}
dates.forEach(date => {
date.name = sc + date.name;
});
}
return vcalendar.vcalendar(dates, opts)
}
}
};

return self
}
ical.vcalendar = vcalendar.vcalendar;

module.exports = ical;
23 changes: 23 additions & 0 deletions lib/templates.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use strict';

const tVcalendar = (vevents) => `BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//date/holidays//NONSGML v1.0//EN
METHOD:PUBLISH
${vevents.join('')}END:VCALENDAR
`;

const tVevent = (event) => `BEGIN:VEVENT
CREATED:${event.created}
LAST-MODIFIED:${event.created}
DTSTAMP:${event.created}
SUMMARY:${event.summary}
DTSTART;VALUE=DATE:${event.dtstart}
DTEND;VALUE=DATE:${event.dtend}${event.description ? `\nDESCRIPTION:${event.description}` : '\n'}
TRANSP:${event.busy ? 'OPAQUE' : 'TRANSPARENT'}
UID:${event.uid}
END:VEVENT
`;

exports.tVcalendar = tVcalendar;
exports.tVevent = tVevent;
122 changes: 122 additions & 0 deletions lib/vcalendar.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
'use strict';

var templates = require('./templates.cjs');

const random = () => Math.random().toString(16).substr(2);

/**
* generate a simple uid
* @private
* @return {String} uid
*/
function uid (len = 16) {
let str = '';
while (str.length < len) str += random();
return `${str.substr(0, len)}@date-holidays`
}

/**
* prefill a number with `len` zeroes
* @private
* @param {Number} num
* @param {Number} [len]
* @return {String} prefixed number
*/
function zero (num, len = 2) {
const str = Array(len).join('0') + '' + num;
return str.substring(str.length - len)
}

/**
* convert an Iso Date or String to Vcalendar Date
* @param {Date|String} date
* @return {String}
* @example
* ```
* toIso('2016-01-02T11:29:54.925Z')
* //> '20160102T112954Z'
* ```
*/
function toISO (date) {
if (typeof date === 'object') {
date = date.toISOString();
}
return date
.replace(/[:-]/g, '')
.replace(/\.\d{3}/g, '')
}

/**
* convert a date string using offset days to a string
* @private
* @param {String} str
* @param {Number} [offset] - offset to date described by str in milliseconds
* @return {String} date string `YYYYMMDD`
* @example
* ```
* toDay('2016-01-02 05:00:01')
* //> '2016012'
* ```
*/
function toDay (str, offset = 0) {
// offset only full days
offset = Math.ceil(offset / 86400000) * 86400000;

const ticks = +(new Date(str)) + (offset);
const date = new Date(ticks);
const s = zero(date.getFullYear(), 4) +
zero(date.getMonth() + 1) +
zero(date.getDate());
return s
}

/**
* apply template on date object from `date-holidays`
* @private
* @param {Object} date
* @param {Object} [opts]
* @param {Boolean} [opts.fullday] - if `true` then event is treated to be on complete day
* @param {Boolean} [opts.transp] - if `true` then event is treated to be always transparent
* @return {String} a single vCalendar vevent
*/
function vevent (date, opts = {}) {
if (!date) {
return '\n'
}

const now = (new Date());
let dtstart = toISO(date.start);
let dtend = toISO(date.end);
const note = date.note || '';
const type = date.type || '';

if (opts.fullday) {
dtend = toDay(date.date, +date.end - +date.start);
dtstart = toDay(date.date);
}

const event = {
created: toISO(now),
summary: date.name,
dtstart,
dtend,
description: type + (type && note ? ' - ' : '') + note,
busy: !opts.transp && type === 'public',
uid: uid()
};

return templates.tVevent(event)
}

/**
* get vCalendar
* @param {Object} date
* @param {Object} [opts]
* @return {String} vCalendar
*/
function vcalendar (dates, opts) {
const vevents = dates.map(date => vevent(date, opts));
return templates.tVcalendar(vevents)
}

exports.vcalendar = vcalendar;
20 changes: 10 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,20 +51,20 @@
"test": "mocha"
},
"dependencies": {
"date-holidays": "^3.14.1"
"date-holidays": "^3.23.17"
},
"devDependencies": {
"c8": "^7.11.0",
"eslint": "^7.32.0",
"eslint-config-standard": "^16.0.3",
"eslint-plugin-import": "^2.25.4",
"c8": "^10.1.3",
"eslint": "^8.57.1",
"eslint-config-standard": "^17.1.0",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.2.0",
"eslint-plugin-promise": "^6.6.0",
"eslint-plugin-standard": "^5.0.0",
"mocha": "^9.1.3",
"npm-run-all": "^4.1.5",
"rimraf": "^3.0.2",
"rollup": "^2.63.0"
"mocha": "^11.1.0",
"npm-run-all2": "^7.0.2",
"rimraf": "^6.0.1",
"rollup": "^4.29.1"
},
"engines": {
"node": ">=12.0.0"
Expand Down
1 change: 0 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import { vcalendar } from './vcalendar.js'
import Holidays from 'date-holidays'

Expand Down
4 changes: 2 additions & 2 deletions src/vcalendar.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ function vevent (date, opts = {}) {
const event = {
created: toISO(now),
summary: date.name,
dtstart: dtstart,
dtend: dtend,
dtstart,
dtend,
description: type + (type && note ? ' - ' : '') + note,
busy: !opts.transp && type === 'public',
uid: uid()
Expand Down
Loading