Skip to content

Commit 50a2dbd

Browse files
authored
fix(properties): allow quote-less props (#185)
* fix(properties): allow quote-less props * fixup! * fixup!
1 parent 093d35f commit 50a2dbd

File tree

5 files changed

+20
-175
lines changed

5 files changed

+20
-175
lines changed

package-lock.json

Lines changed: 14 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
"@googleapis/calendar": "^11.0.1",
1515
"@hackmd/api": "^2.5.0",
1616
"@octokit/rest": "^22.0.0",
17-
"dedent": "^1.6.0"
17+
"dedent": "^1.6.0",
18+
"dotenv": "^17.2.2"
1819
},
1920
"devDependencies": {
2021
"@eslint/js": "^9.33.0",

src/meeting.mjs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { readFile } from 'node:fs/promises';
22
import { join } from 'node:path';
33

4+
import { parse } from 'dotenv';
5+
46
import { DEFAULT_CONFIG } from './constants.mjs';
57
import * as dates from './utils/dates.mjs';
68
import * as templates from './utils/templates.mjs';
@@ -32,7 +34,7 @@ export const readMeetingConfig = async config => {
3234
invited,
3335
observers,
3436
baseMeetingInfo,
35-
properties: templates.parseMeetingProperties(baseMeetingInfo),
37+
properties: parse(baseMeetingInfo),
3638
};
3739
};
3840

src/utils/templates.mjs

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,26 +21,3 @@ export const parseVariables = (template, variables) => {
2121

2222
return processed;
2323
};
24-
25-
/**
26-
* Simple parser for template properties (KEY="value" format)
27-
* @param {string} content - Template content
28-
* @returns {Record<string, string>} Parsed properties
29-
*/
30-
export const parseMeetingProperties = content => {
31-
const properties = {};
32-
33-
// Handle multiline properties first with a generic regex
34-
// Matches: KEY="multiline content" where content can span multiple lines
35-
const multilineMatches = content.matchAll(
36-
/^([A-Z_][A-Z0-9_]*)="([\s\S]*?)"$/gm
37-
);
38-
39-
for (const match of multilineMatches) {
40-
const [, key, value] = match;
41-
42-
properties[key] = value;
43-
}
44-
45-
return properties;
46-
};

test/utils/templates.test.mjs

Lines changed: 1 addition & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
import assert from 'node:assert';
22
import { describe, it } from 'node:test';
33

4-
import {
5-
parseVariables,
6-
parseMeetingProperties,
7-
} from '../../src/utils/templates.mjs';
4+
import { parseVariables } from '../../src/utils/templates.mjs';
85

96
describe('Utils - Templates', () => {
107
describe('parseVariables', () => {
@@ -118,149 +115,4 @@ Line 3: Hello again`
118115
);
119116
});
120117
});
121-
122-
describe('parseMeetingProperties', () => {
123-
it('should parse simple property', () => {
124-
const content = 'NAME="John Doe"';
125-
126-
const result = parseMeetingProperties(content);
127-
128-
assert.deepStrictEqual(result, { NAME: 'John Doe' });
129-
});
130-
131-
it('should parse multiple properties', () => {
132-
const content = `NAME="John Doe"
133-
EMAIL="john@example.com"
134-
ROLE="Developer"`;
135-
136-
const result = parseMeetingProperties(content);
137-
138-
assert.deepStrictEqual(result, {
139-
NAME: 'John Doe',
140-
EMAIL: 'john@example.com',
141-
ROLE: 'Developer',
142-
});
143-
});
144-
145-
it('should parse multiline property values', () => {
146-
const content = `DESCRIPTION="This is a
147-
multiline description
148-
with several lines"`;
149-
150-
const result = parseMeetingProperties(content);
151-
152-
assert.deepStrictEqual(result, {
153-
DESCRIPTION: 'This is a\nmultiline description\nwith several lines',
154-
});
155-
});
156-
157-
it('should parse properties with underscores and numbers', () => {
158-
const content = `VAR_1="value1"
159-
VAR_2_TEST="value2"
160-
VAR3="value3"`;
161-
162-
const result = parseMeetingProperties(content);
163-
164-
assert.deepStrictEqual(result, {
165-
VAR_1: 'value1',
166-
VAR_2_TEST: 'value2',
167-
VAR3: 'value3',
168-
});
169-
});
170-
171-
it('should handle empty property values', () => {
172-
const content = 'EMPTY=""';
173-
174-
const result = parseMeetingProperties(content);
175-
176-
assert.deepStrictEqual(result, { EMPTY: '' });
177-
});
178-
179-
it('should handle properties with special characters in values', () => {
180-
const content = 'SPECIAL="Value with $pecial ch@rs & symbols!"';
181-
182-
const result = parseMeetingProperties(content);
183-
184-
assert.deepStrictEqual(result, {
185-
SPECIAL: 'Value with $pecial ch@rs & symbols!',
186-
});
187-
});
188-
189-
it('should handle properties with quotes in values', () => {
190-
const content = `QUOTED="He said \\"Hello\\" to me"`;
191-
192-
const result = parseMeetingProperties(content);
193-
194-
assert.deepStrictEqual(result, {
195-
QUOTED: 'He said \\"Hello\\" to me',
196-
});
197-
});
198-
199-
it('should handle content with no properties', () => {
200-
const content = 'Just some text without properties';
201-
202-
const result = parseMeetingProperties(content);
203-
204-
assert.deepStrictEqual(result, {});
205-
});
206-
207-
it('should handle empty content', () => {
208-
const content = '';
209-
210-
const result = parseMeetingProperties(content);
211-
212-
assert.deepStrictEqual(result, {});
213-
});
214-
215-
it('should handle mixed content with properties and other text', () => {
216-
const content = `Some random text
217-
NAME="John Doe"
218-
More text here
219-
EMAIL="john@example.com"
220-
Final text`;
221-
222-
const result = parseMeetingProperties(content);
223-
224-
assert.deepStrictEqual(result, {
225-
NAME: 'John Doe',
226-
EMAIL: 'john@example.com',
227-
});
228-
});
229-
230-
it('should handle properties with markdown-like content', () => {
231-
const content = `DESCRIPTION="# Meeting Notes
232-
233-
## Agenda
234-
- Item 1
235-
- Item 2
236-
237-
**Important**: Don't forget!"`;
238-
239-
const result = parseMeetingProperties(content);
240-
241-
assert.deepStrictEqual(result, {
242-
DESCRIPTION: `# Meeting Notes
243-
244-
## Agenda
245-
- Item 1
246-
- Item 2
247-
248-
**Important**: Don't forget!`,
249-
});
250-
});
251-
252-
it('should handle properties with URLs and special formatting', () => {
253-
const content = `LINK="https://example.com/path?param=value&other=123"
254-
INSTRUCTIONS="Join at: https://zoom.us/j/123456789
255-
Passcode: 123456"`;
256-
257-
const result = parseMeetingProperties(content);
258-
259-
assert.deepStrictEqual(result, {
260-
LINK: 'https://example.com/path?param=value&other=123',
261-
INSTRUCTIONS: `Join at: https://zoom.us/j/123456789
262-
Passcode: 123456`,
263-
});
264-
});
265-
});
266118
});

0 commit comments

Comments
 (0)