@dytsou/calendar-build 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,98 @@
1
+ # Calendar App
2
+
3
+ A simple calendar application that displays multiple Google Calendars in a single view.
4
+
5
+ ## Setup
6
+
7
+ 1. Copy `.env.example` to `.env`:
8
+ ```bash
9
+ cp .env.example .env
10
+ ```
11
+
12
+ 2. Edit `.env` and add your calendar sources (comma-separated):
13
+ ```
14
+ CALENDAR_SOURCES=calendar1,calendar2,calendar3
15
+ ```
16
+
17
+ 3. Build the HTML file:
18
+ ```bash
19
+ # Option 1: Using npm/pnpm (after installing)
20
+ pnpm install
21
+ pnpm run build
22
+ # or use the global command if installed globally
23
+ calendar-build
24
+
25
+ # Option 2: Direct execution
26
+ node build.js
27
+ ```
28
+
29
+ 4. Open `index.html` in your browser.
30
+
31
+ ## Install Package
32
+
33
+ This package is published to **both registries**:
34
+
35
+ - **npmjs.com**: https://www.npmjs.com/package/@dytsou/calendar-build
36
+ - **GitHub Packages**: https://github.com/dytsou/cal/packages
37
+
38
+ ### Installation from npmjs (Default - Recommended)
39
+
40
+ **Global installation:**
41
+ ```bash
42
+ npm install -g @dytsou/calendar-build
43
+ # or
44
+ pnpm install -g @dytsou/calendar-build
45
+ ```
46
+
47
+ Then use anywhere:
48
+ ```bash
49
+ calendar-build
50
+ ```
51
+
52
+ **Local installation:**
53
+ ```bash
54
+ npm install @dytsou/calendar-build
55
+ # or
56
+ pnpm install @dytsou/calendar-build
57
+ ```
58
+
59
+ Then use:
60
+ ```bash
61
+ npx calendar-build
62
+ # or
63
+ pnpm run build
64
+ ```
65
+
66
+ ### Installation from GitHub Packages
67
+
68
+ If you prefer to install from GitHub Packages:
69
+
70
+ **1. Setup GitHub Packages Authentication**
71
+
72
+ Create or edit `.npmrc` file in your home directory:
73
+
74
+ ```ini
75
+ @dytsou:registry=https://npm.pkg.github.com
76
+ //npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKEN
77
+ ```
78
+
79
+ **2. Get your GitHub token:**
80
+ 1. Go to https://github.com/settings/tokens
81
+ 2. Click "Generate new token" → "Generate new token (classic)"
82
+ 3. Select `read:packages` permission
83
+ 4. Copy the token and replace `YOUR_GITHUB_TOKEN` in `.npmrc`
84
+
85
+ **3. Install:**
86
+ ```bash
87
+ npm install -g @dytsou/calendar-build
88
+ # or
89
+ pnpm install -g @dytsou/calendar-build
90
+ ```
91
+
92
+ ## Development
93
+
94
+ - `index.html.template` - Template file with placeholder for calendar sources
95
+ - `build.js` - Build script that injects calendar sources from `.env`
96
+ - `.env` - Local environment file (not committed to git)
97
+ - `.env.example` - Example environment file template
98
+
package/build.js ADDED
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+
6
+ // Read .env file
7
+ const envPath = path.join(__dirname, '.env');
8
+ if (!fs.existsSync(envPath)) {
9
+ console.error('Error: .env file not found');
10
+ process.exit(1);
11
+ }
12
+
13
+ const envContent = fs.readFileSync(envPath, 'utf-8');
14
+ const envLines = envContent.split('\n');
15
+
16
+ // Parse CALENDAR_SOURCES from .env
17
+ let calendarSources = [];
18
+ for (const line of envLines) {
19
+ if (line.startsWith('CALENDAR_SOURCES=')) {
20
+ const value = line.substring('CALENDAR_SOURCES='.length).trim();
21
+ calendarSources = value.split(',').map(s => s.trim()).filter(s => s);
22
+ break;
23
+ }
24
+ }
25
+
26
+ if (calendarSources.length === 0) {
27
+ console.error('Error: No calendar sources found in .env file');
28
+ process.exit(1);
29
+ }
30
+
31
+ // Read template HTML
32
+ const templatePath = path.join(__dirname, 'index.html.template');
33
+ if (!fs.existsSync(templatePath)) {
34
+ console.error('Error: index.html.template not found');
35
+ process.exit(1);
36
+ }
37
+
38
+ let html = fs.readFileSync(templatePath, 'utf-8');
39
+
40
+ // Generate calendar array as JavaScript code
41
+ const calendarArrayCode = '[\n' + calendarSources
42
+ .map(cal => ` "${cal}"`)
43
+ .join(',\n') + '\n ]';
44
+
45
+ // Replace placeholder
46
+ html = html.replace('{{CALENDAR_SOURCES}}', calendarArrayCode);
47
+
48
+ // Write built HTML
49
+ const outputPath = path.join(__dirname, 'index.html');
50
+ fs.writeFileSync(outputPath, html, 'utf-8');
51
+
52
+ console.log(`✓ Built index.html with ${calendarSources.length} calendar source(s)`);
53
+
@@ -0,0 +1,96 @@
1
+ <!DOCTYPE html>
2
+ <html lang="zh-TW">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>My Calendar</title>
8
+ <link rel="icon" type="image/png" href="asset/favicon.png">
9
+
10
+ <style>
11
+ body {
12
+ transition: opacity ease-in 0.2s;
13
+ }
14
+
15
+ body[unresolved] {
16
+ opacity: 0;
17
+ display: block;
18
+ overflow: hidden;
19
+ position: relative;
20
+ }
21
+
22
+ iframe {
23
+ border: solid 1px #777;
24
+ width: 100%;
25
+ height: 100vh;
26
+ }
27
+ </style>
28
+ </head>
29
+
30
+ <body unresolved>
31
+
32
+ <iframe id="calendarFrame" frameborder="0" scrolling="no"></iframe>
33
+
34
+ <script>
35
+ const calendarBaseURL = "https://calendar.google.com/calendar/embed?";
36
+ const searchParams = new URLSearchParams(window.location.search);
37
+ const calendarParams = new URLSearchParams({
38
+ height: 600,
39
+ wkst: 1,
40
+ ctz: "Asia/Taipei",
41
+ showPrint: 0,
42
+ showTitle: 0,
43
+ showDate: 0,
44
+ showNav: 0,
45
+ showCalendars: 0,
46
+ showTabs: 0,
47
+ mode: "WEEK"
48
+ });
49
+
50
+ const calendars = {{CALENDAR_SOURCES}};
51
+
52
+ const defaultColor = "%23A1B3FF";
53
+
54
+ const parseDatesRange = (value) => {
55
+ if (!value) return null;
56
+ const match = /^(\d{8})\/(\d{8})$/.exec(value);
57
+ if (!match) return null;
58
+ const [, start, end] = match;
59
+
60
+ // Basic validation to ensure chronological order.
61
+ if (start > end) return null;
62
+
63
+ return `${start}/${end}`;
64
+ };
65
+
66
+ const datesFromQuery = parseDatesRange(searchParams.get("dates"));
67
+ if (datesFromQuery) {
68
+ calendarParams.set("dates", datesFromQuery);
69
+ }
70
+
71
+ const defaultMode = "WEEK";
72
+ const allowedModes = new Set(["MONTH", "WEEK", "AGENDA"]);
73
+ const requestedMode = searchParams.get("mode");
74
+ if (requestedMode) {
75
+ const normalizedMode = requestedMode.toUpperCase();
76
+ if (allowedModes.has(normalizedMode)) {
77
+ calendarParams.set("mode", normalizedMode);
78
+ } else {
79
+ calendarParams.set("mode", defaultMode);
80
+ }
81
+ }
82
+
83
+ calendars.forEach(calendar => {
84
+ calendarParams.append("src", calendar);
85
+ calendarParams.append("color", defaultColor);
86
+ });
87
+
88
+ document.getElementById("calendarFrame").src = calendarBaseURL + calendarParams.toString();
89
+
90
+ window.onload = () => document.body.removeAttribute('unresolved');
91
+ </script>
92
+
93
+ </body>
94
+
95
+ </html>
96
+
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@dytsou/calendar-build",
3
+ "version": "1.1.1",
4
+ "description": "Build script for calendar HTML from template and environment variables",
5
+ "main": "build.js",
6
+ "bin": {
7
+ "calendar-build": "build.js"
8
+ },
9
+ "files": [
10
+ "build.js",
11
+ "index.html.template",
12
+ "README.md"
13
+ ],
14
+ "scripts": {
15
+ "build": "node build.js"
16
+ },
17
+ "keywords": [
18
+ "calendar",
19
+ "build",
20
+ "template"
21
+ ],
22
+ "author": "dytsou",
23
+ "license": "MIT",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/dytsou/cal.git"
27
+ },
28
+ "bugs": {
29
+ "url": "https://github.com/dytsou/cal/issues"
30
+ },
31
+ "homepage": "https://github.com/dytsou/cal#readme",
32
+ "engines": {
33
+ "node": ">=12.0.0"
34
+ }
35
+ }