@programinglive/commiter 1.2.8 → 1.2.12

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.
@@ -1,182 +1,182 @@
1
- #!/usr/bin/env node
2
-
3
- const fs = require('fs');
4
- const path = require('path');
5
-
6
- function updateReleaseNotes({
7
- rootDir = process.cwd(),
8
- releaseNotesRelativePath = path.join('docs', 'release-notes', 'RELEASE_NOTES.md'),
9
- changelogRelativePath = 'CHANGELOG.md',
10
- packageJsonRelativePath = 'package.json',
11
- now = () => new Date()
12
- } = {}) {
13
- const releaseNotesPath = path.join(rootDir, releaseNotesRelativePath);
14
- if (!fs.existsSync(releaseNotesPath)) {
15
- console.log(`ℹ️ Release notes file not found at ${releaseNotesPath}; skipping update.`);
16
- return false;
17
- }
18
-
19
- const packageJsonPath = path.join(rootDir, packageJsonRelativePath);
20
- if (!fs.existsSync(packageJsonPath)) {
21
- console.log(`ℹ️ package.json not found at ${packageJsonPath}; skipping release notes update.`);
22
- return false;
23
- }
24
-
25
- const changelogPath = path.join(rootDir, changelogRelativePath);
26
- if (!fs.existsSync(changelogPath)) {
27
- console.log(`ℹ️ CHANGELOG not found at ${changelogPath}; skipping release notes update.`);
28
- return false;
29
- }
30
-
31
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
32
- const version = packageJson.version;
33
- if (!version) {
34
- console.log('ℹ️ package.json version is missing; skipping release notes update.');
35
- return false;
36
- }
37
-
38
- const releaseNotesContent = fs.readFileSync(releaseNotesPath, 'utf8');
39
- if (releaseNotesContent.includes(`| ${version} `) || releaseNotesContent.includes(`## ${version}`)) {
40
- console.log(`ℹ️ Release notes already contain version ${version}; skipping.`);
41
- return false;
42
- }
43
-
44
- const changelogContent = fs.readFileSync(changelogPath, 'utf8');
45
- const changelogInfo = extractChangelogInfo({ changelogContent, version });
46
-
47
- const releaseDate = changelogInfo.date || formatDate(now());
48
- const highlight = changelogInfo.highlight || changelogInfo.heading || 'See CHANGELOG for details.';
49
- const sectionHeading = changelogInfo.heading || '';
50
- const detailBullets = Array.isArray(changelogInfo.bullets) && changelogInfo.bullets.length > 0
51
- ? changelogInfo.bullets
52
- : [highlight];
53
-
54
- const updatedContent = insertReleaseNotesEntry({
55
- content: releaseNotesContent,
56
- version,
57
- releaseDate,
58
- highlight,
59
- sectionHeading,
60
- detailBullets
61
- });
62
-
63
- fs.writeFileSync(releaseNotesPath, updatedContent);
64
- console.log(`✅ Added release notes entry for version ${version}.`);
65
- return true;
66
- }
67
-
68
- function insertReleaseNotesEntry({ content, version, releaseDate, highlight, sectionHeading, detailBullets }) {
69
- const lines = content.split('\n');
70
- const headerSeparatorIndex = lines.findIndex((line) => line.trim().startsWith('|---------'));
71
- if (headerSeparatorIndex === -1) {
72
- throw new Error('Unable to locate release notes table header.');
73
- }
74
-
75
- const newRow = `| ${version} | ${releaseDate} | ${escapePipes(highlight)} |`;
76
- lines.splice(headerSeparatorIndex + 1, 0, newRow);
77
-
78
- const sectionLines = [];
79
- sectionLines.push('');
80
- const trimmedHeading = typeof sectionHeading === 'string' ? sectionHeading.trim() : '';
81
- const headingSuffix = trimmedHeading ? ` – ${trimmedHeading}` : '';
82
- sectionLines.push(`## ${version}${headingSuffix}`);
83
- sectionLines.push('');
84
- sectionLines.push(`Released on **${releaseDate}**.`);
85
- sectionLines.push('');
86
- for (const bullet of detailBullets) {
87
- sectionLines.push(`- ${bullet}`);
88
- }
89
- sectionLines.push('');
90
-
91
- const firstSectionIndex = lines.findIndex((line, idx) => idx > headerSeparatorIndex && line.startsWith('## '));
92
- if (firstSectionIndex === -1) {
93
- lines.push(...sectionLines);
94
- } else {
95
- lines.splice(firstSectionIndex, 0, ...sectionLines);
96
- }
97
-
98
- return lines.join('\n');
99
- }
100
-
101
- function extractChangelogInfo({ changelogContent, version }) {
102
- const versionHeadingRegex = new RegExp(`^### \\[${escapeRegExp(version)}\\][^\n]*`, 'm');
103
- const match = changelogContent.match(versionHeadingRegex);
104
- if (!match) {
105
- return {};
106
- }
107
-
108
- const headingIndex = match.index;
109
- const rest = changelogContent.slice(headingIndex + match[0].length);
110
- const nextVersionRegex = /^### \[[^\n]*\]/m;
111
- const nextVersionMatch = nextVersionRegex.exec(rest);
112
- const section = nextVersionMatch ? rest.slice(0, nextVersionMatch.index) : rest;
113
-
114
- const dateMatch = match[0].match(/\((\d{4}-\d{2}-\d{2})\)/);
115
- const date = dateMatch ? dateMatch[1] : undefined;
116
-
117
- const categoryRegex = /^###\s+([^\n]+)$/m;
118
- const categoryMatch = section.match(categoryRegex);
119
- let heading;
120
- if (categoryMatch) {
121
- heading = sanitizeText(categoryMatch[1]);
122
- }
123
-
124
- const bullets = [];
125
- const bulletRegex = /^\*\s+([^\n]+)$/gm;
126
- let bulletMatch;
127
- while ((bulletMatch = bulletRegex.exec(section)) !== null) {
128
- const sanitized = sanitizeText(bulletMatch[1]);
129
- if (!bullets.includes(sanitized)) {
130
- bullets.push(sanitized);
131
- }
132
- }
133
-
134
- const highlight = bullets.length > 0 ? bullets[0] : undefined;
135
-
136
- return {
137
- date,
138
- highlight,
139
- heading,
140
- bullets
141
- };
142
- }
143
-
144
- function sanitizeText(text) {
145
- return text
146
- .replace(/\[([^\]]+)\]\([^\)]+\)/g, '$1')
147
- .replace(/\s+/g, ' ')
148
- .trim();
149
- }
150
-
151
- function escapeRegExp(string) {
152
- return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
153
- }
154
-
155
- function escapePipes(text) {
156
- return text.replace(/\|/g, '\\|');
157
- }
158
-
159
- function formatDate(date) {
160
- const year = date.getFullYear();
161
- const month = String(date.getMonth() + 1).padStart(2, '0');
162
- const day = String(date.getDate()).padStart(2, '0');
163
- return `${year}-${month}-${day}`;
164
- }
165
-
166
- module.exports = {
167
- updateReleaseNotes,
168
- insertReleaseNotesEntry,
169
- extractChangelogInfo,
170
- sanitizeText,
171
- escapePipes,
172
- formatDate
173
- };
174
-
175
- if (require.main === module) {
176
- try {
177
- updateReleaseNotes();
178
- } catch (error) {
179
- console.error(`❌ Failed to update release notes: ${error.message}`);
180
- process.exit(1);
181
- }
182
- }
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+
6
+ function updateReleaseNotes({
7
+ rootDir = process.cwd(),
8
+ releaseNotesRelativePath = path.join('docs', 'release-notes', 'RELEASE_NOTES.md'),
9
+ changelogRelativePath = 'CHANGELOG.md',
10
+ packageJsonRelativePath = 'package.json',
11
+ now = () => new Date()
12
+ } = {}) {
13
+ const releaseNotesPath = path.join(rootDir, releaseNotesRelativePath);
14
+ if (!fs.existsSync(releaseNotesPath)) {
15
+ console.log(`ℹ️ Release notes file not found at ${releaseNotesPath}; skipping update.`);
16
+ return false;
17
+ }
18
+
19
+ const packageJsonPath = path.join(rootDir, packageJsonRelativePath);
20
+ if (!fs.existsSync(packageJsonPath)) {
21
+ console.log(`ℹ️ package.json not found at ${packageJsonPath}; skipping release notes update.`);
22
+ return false;
23
+ }
24
+
25
+ const changelogPath = path.join(rootDir, changelogRelativePath);
26
+ if (!fs.existsSync(changelogPath)) {
27
+ console.log(`ℹ️ CHANGELOG not found at ${changelogPath}; skipping release notes update.`);
28
+ return false;
29
+ }
30
+
31
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
32
+ const version = packageJson.version;
33
+ if (!version) {
34
+ console.log('ℹ️ package.json version is missing; skipping release notes update.');
35
+ return false;
36
+ }
37
+
38
+ const releaseNotesContent = fs.readFileSync(releaseNotesPath, 'utf8');
39
+ if (releaseNotesContent.includes(`| ${version} `) || releaseNotesContent.includes(`## ${version}`)) {
40
+ console.log(`ℹ️ Release notes already contain version ${version}; skipping.`);
41
+ return false;
42
+ }
43
+
44
+ const changelogContent = fs.readFileSync(changelogPath, 'utf8');
45
+ const changelogInfo = extractChangelogInfo({ changelogContent, version });
46
+
47
+ const releaseDate = changelogInfo.date || formatDate(now());
48
+ const highlight = changelogInfo.highlight || changelogInfo.heading || 'See CHANGELOG for details.';
49
+ const sectionHeading = changelogInfo.heading || '';
50
+ const detailBullets = Array.isArray(changelogInfo.bullets) && changelogInfo.bullets.length > 0
51
+ ? changelogInfo.bullets
52
+ : [highlight];
53
+
54
+ const updatedContent = insertReleaseNotesEntry({
55
+ content: releaseNotesContent,
56
+ version,
57
+ releaseDate,
58
+ highlight,
59
+ sectionHeading,
60
+ detailBullets
61
+ });
62
+
63
+ fs.writeFileSync(releaseNotesPath, updatedContent);
64
+ console.log(`✅ Added release notes entry for version ${version}.`);
65
+ return true;
66
+ }
67
+
68
+ function insertReleaseNotesEntry({ content, version, releaseDate, highlight, sectionHeading, detailBullets }) {
69
+ const lines = content.split('\n');
70
+ const headerSeparatorIndex = lines.findIndex((line) => line.trim().startsWith('|---------'));
71
+ if (headerSeparatorIndex === -1) {
72
+ throw new Error('Unable to locate release notes table header.');
73
+ }
74
+
75
+ const newRow = `| ${version} | ${releaseDate} | ${escapePipes(highlight)} |`;
76
+ lines.splice(headerSeparatorIndex + 1, 0, newRow);
77
+
78
+ const sectionLines = [];
79
+ sectionLines.push('');
80
+ const trimmedHeading = typeof sectionHeading === 'string' ? sectionHeading.trim() : '';
81
+ const headingSuffix = trimmedHeading ? ` – ${trimmedHeading}` : '';
82
+ sectionLines.push(`## ${version}${headingSuffix}`);
83
+ sectionLines.push('');
84
+ sectionLines.push(`Released on **${releaseDate}**.`);
85
+ sectionLines.push('');
86
+ for (const bullet of detailBullets) {
87
+ sectionLines.push(`- ${bullet}`);
88
+ }
89
+ sectionLines.push('');
90
+
91
+ const firstSectionIndex = lines.findIndex((line, idx) => idx > headerSeparatorIndex && line.startsWith('## '));
92
+ if (firstSectionIndex === -1) {
93
+ lines.push(...sectionLines);
94
+ } else {
95
+ lines.splice(firstSectionIndex, 0, ...sectionLines);
96
+ }
97
+
98
+ return lines.join('\n');
99
+ }
100
+
101
+ function extractChangelogInfo({ changelogContent, version }) {
102
+ const versionHeadingRegex = new RegExp(`^### \\[${escapeRegExp(version)}\\][^\n]*`, 'm');
103
+ const match = changelogContent.match(versionHeadingRegex);
104
+ if (!match) {
105
+ return {};
106
+ }
107
+
108
+ const headingIndex = match.index;
109
+ const rest = changelogContent.slice(headingIndex + match[0].length);
110
+ const nextVersionRegex = /^### \[[^\n]*\]/m;
111
+ const nextVersionMatch = nextVersionRegex.exec(rest);
112
+ const section = nextVersionMatch ? rest.slice(0, nextVersionMatch.index) : rest;
113
+
114
+ const dateMatch = match[0].match(/\((\d{4}-\d{2}-\d{2})\)/);
115
+ const date = dateMatch ? dateMatch[1] : undefined;
116
+
117
+ const categoryRegex = /^###\s+([^\n]+)$/m;
118
+ const categoryMatch = section.match(categoryRegex);
119
+ let heading;
120
+ if (categoryMatch) {
121
+ heading = sanitizeText(categoryMatch[1]);
122
+ }
123
+
124
+ const bullets = [];
125
+ const bulletRegex = /^\*\s+([^\n]+)$/gm;
126
+ let bulletMatch;
127
+ while ((bulletMatch = bulletRegex.exec(section)) !== null) {
128
+ const sanitized = sanitizeText(bulletMatch[1]);
129
+ if (!bullets.includes(sanitized)) {
130
+ bullets.push(sanitized);
131
+ }
132
+ }
133
+
134
+ const highlight = bullets.length > 0 ? bullets[0] : undefined;
135
+
136
+ return {
137
+ date,
138
+ highlight,
139
+ heading,
140
+ bullets
141
+ };
142
+ }
143
+
144
+ function sanitizeText(text) {
145
+ return text
146
+ .replace(/\[([^\]]+)\]\([^\)]+\)/g, '$1')
147
+ .replace(/\s+/g, ' ')
148
+ .trim();
149
+ }
150
+
151
+ function escapeRegExp(string) {
152
+ return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
153
+ }
154
+
155
+ function escapePipes(text) {
156
+ return text.replace(/\|/g, '\\|');
157
+ }
158
+
159
+ function formatDate(date) {
160
+ const year = date.getFullYear();
161
+ const month = String(date.getMonth() + 1).padStart(2, '0');
162
+ const day = String(date.getDate()).padStart(2, '0');
163
+ return `${year}-${month}-${day}`;
164
+ }
165
+
166
+ module.exports = {
167
+ updateReleaseNotes,
168
+ insertReleaseNotesEntry,
169
+ extractChangelogInfo,
170
+ sanitizeText,
171
+ escapePipes,
172
+ formatDate
173
+ };
174
+
175
+ if (require.main === module) {
176
+ try {
177
+ updateReleaseNotes();
178
+ } catch (error) {
179
+ console.error(`❌ Failed to update release notes: ${error.message}`);
180
+ process.exit(1);
181
+ }
182
+ }
package/web/README.md CHANGED
@@ -1,79 +1,79 @@
1
- # Commiter Website
2
-
3
- This is the static website for the Commiter project. It can be deployed to any web server or hosting platform.
4
-
5
- ## 📁 Structure
6
-
7
- ```
8
- web/
9
- ├── index.html # Main landing page
10
- ├── css/
11
- │ └── style.css # Styles with modern dark theme
12
- ├── js/
13
- │ └── script.js # Interactive features
14
- └── README.md # This file
15
- ```
16
-
17
- ## 🚀 Deployment Options
18
-
19
- ### Option 1: Plesk / cPanel
20
- 1. Compress the `web` folder contents into a ZIP file
21
- 2. Upload to your Plesk/cPanel file manager
22
- 3. Extract in your public_html or desired directory
23
- 4. Access via your domain
24
-
25
- ### Option 2: Static Hosting (Netlify, Vercel, GitHub Pages)
26
- 1. Push the `web` folder to a Git repository
27
- 2. Connect to your hosting platform
28
- 3. Set the build directory to `web`
29
- 4. Deploy
30
-
31
- ### Option 3: Simple HTTP Server (Testing)
32
- ```bash
33
- # Navigate to the web directory
34
- cd web
35
-
36
- # Python 3
37
- python -m http.server 8000
38
-
39
- # Node.js (if you have http-server installed)
40
- npx http-server -p 8000
41
-
42
- # PHP
43
- php -S localhost:8000
44
- ```
45
-
46
- Then open http://localhost:8000 in your browser.
47
-
48
- ## 🎨 Features
49
-
50
- - **Modern Design**: Dark theme with glassmorphism effects
51
- - **Fully Responsive**: Works on desktop, tablet, and mobile
52
- - **Smooth Animations**: Scroll animations and transitions
53
- - **Interactive Elements**: Copy-to-clipboard, smooth scrolling
54
- - **SEO Optimized**: Meta tags and semantic HTML
55
- - **Fast Loading**: Optimized CSS and JavaScript
56
-
57
- ## 🛠️ Customization
58
-
59
- ### Colors
60
- Edit CSS variables in `css/style.css`:
61
- ```css
62
- :root {
63
- --primary: #6366f1;
64
- --secondary: #8b5cf6;
65
- --accent: #ec4899;
66
- /* ... more variables */
67
- }
68
- ```
69
-
70
- ### Content
71
- Edit `index.html` to update:
72
- - Version numbers
73
- - Release information
74
- - Links and URLs
75
- - Text content
76
-
77
- ## 📝 License
78
-
79
- This website is part of the Commiter project and is released under the MIT License.
1
+ # Commiter Website
2
+
3
+ This is the static website for the Commiter project. It can be deployed to any web server or hosting platform.
4
+
5
+ ## 📁 Structure
6
+
7
+ ```
8
+ web/
9
+ ├── index.html # Main landing page
10
+ ├── css/
11
+ │ └── style.css # Styles with modern dark theme
12
+ ├── js/
13
+ │ └── script.js # Interactive features
14
+ └── README.md # This file
15
+ ```
16
+
17
+ ## 🚀 Deployment Options
18
+
19
+ ### Option 1: Plesk / cPanel
20
+ 1. Compress the `web` folder contents into a ZIP file
21
+ 2. Upload to your Plesk/cPanel file manager
22
+ 3. Extract in your public_html or desired directory
23
+ 4. Access via your domain
24
+
25
+ ### Option 2: Static Hosting (Netlify, Vercel, GitHub Pages)
26
+ 1. Push the `web` folder to a Git repository
27
+ 2. Connect to your hosting platform
28
+ 3. Set the build directory to `web`
29
+ 4. Deploy
30
+
31
+ ### Option 3: Simple HTTP Server (Testing)
32
+ ```bash
33
+ # Navigate to the web directory
34
+ cd web
35
+
36
+ # Python 3
37
+ python -m http.server 8000
38
+
39
+ # Node.js (if you have http-server installed)
40
+ npx http-server -p 8000
41
+
42
+ # PHP
43
+ php -S localhost:8000
44
+ ```
45
+
46
+ Then open http://localhost:8000 in your browser.
47
+
48
+ ## 🎨 Features
49
+
50
+ - **Modern Design**: Dark theme with glassmorphism effects
51
+ - **Fully Responsive**: Works on desktop, tablet, and mobile
52
+ - **Smooth Animations**: Scroll animations and transitions
53
+ - **Interactive Elements**: Copy-to-clipboard, smooth scrolling
54
+ - **SEO Optimized**: Meta tags and semantic HTML
55
+ - **Fast Loading**: Optimized CSS and JavaScript
56
+
57
+ ## 🛠️ Customization
58
+
59
+ ### Colors
60
+ Edit CSS variables in `css/style.css`:
61
+ ```css
62
+ :root {
63
+ --primary: #6366f1;
64
+ --secondary: #8b5cf6;
65
+ --accent: #ec4899;
66
+ /* ... more variables */
67
+ }
68
+ ```
69
+
70
+ ### Content
71
+ Edit `index.html` to update:
72
+ - Version numbers
73
+ - Release information
74
+ - Links and URLs
75
+ - Text content
76
+
77
+ ## 📝 License
78
+
79
+ This website is part of the Commiter project and is released under the MIT License.