@zentered/issue-forms-body-parser 1.1.1 → 1.1.4
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/.github/ISSUE_TEMPLATE/bug_report.yml +36 -0
- package/.github/ISSUE_TEMPLATE/config.yml +1 -0
- package/.github/ISSUE_TEMPLATE/feature_request.yml +38 -0
- package/README.md +20 -0
- package/dist/index.js +48 -24
- package/package.json +7 -7
- package/src/parse.js +9 -6
- package/test/parse-issue.test.js +13 -1
- package/test/test-issue-2.md +10 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -24
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -19
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Create a report to help us improve
|
|
3
|
+
title: Bug report
|
|
4
|
+
labels: ['bug']
|
|
5
|
+
body:
|
|
6
|
+
- type: textarea
|
|
7
|
+
id: description
|
|
8
|
+
attributes:
|
|
9
|
+
label: Describe the bug
|
|
10
|
+
description: A clear and concise description of what the bug is.
|
|
11
|
+
validations:
|
|
12
|
+
required: true
|
|
13
|
+
- type: textarea
|
|
14
|
+
id: reproduction
|
|
15
|
+
attributes:
|
|
16
|
+
label: To reproduce
|
|
17
|
+
description: Steps to reproduce the behavior
|
|
18
|
+
placeholder: >
|
|
19
|
+
1. Go to ...\n 2. Click on ...\n 3. Scroll down to ...\n 4. See error
|
|
20
|
+
validations:
|
|
21
|
+
required: false
|
|
22
|
+
- type: textarea
|
|
23
|
+
id: expectation
|
|
24
|
+
attributes:
|
|
25
|
+
label: Expected behaviour
|
|
26
|
+
description:
|
|
27
|
+
A clear and concise description of what you expected to happen.
|
|
28
|
+
validations:
|
|
29
|
+
required: false
|
|
30
|
+
- type: textarea
|
|
31
|
+
id: additional
|
|
32
|
+
attributes:
|
|
33
|
+
label: Additional context
|
|
34
|
+
description: Add any other context about the problem here.
|
|
35
|
+
validations:
|
|
36
|
+
required: false
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
blank_issues_enabled: false
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Suggest an idea for this project
|
|
3
|
+
title: Feature request
|
|
4
|
+
labels: ['enhancement']
|
|
5
|
+
body:
|
|
6
|
+
- type: textarea
|
|
7
|
+
id: description
|
|
8
|
+
attributes:
|
|
9
|
+
label: Is your feature request related to a problem? Please describe.
|
|
10
|
+
description:
|
|
11
|
+
A clear and concise description of what the problem is. Ex. Im always
|
|
12
|
+
frustrated when [...]
|
|
13
|
+
validations:
|
|
14
|
+
required: true
|
|
15
|
+
- type: textarea
|
|
16
|
+
id: solution
|
|
17
|
+
attributes:
|
|
18
|
+
label: Describe the solution you would like
|
|
19
|
+
description: A clear and concise description of what you want to happen.
|
|
20
|
+
validations:
|
|
21
|
+
required: false
|
|
22
|
+
- type: textarea
|
|
23
|
+
id: alternatives
|
|
24
|
+
attributes:
|
|
25
|
+
label: Describe alternatives you have considered
|
|
26
|
+
description:
|
|
27
|
+
A clear and concise description of any alternative solutions or features
|
|
28
|
+
you have considered.
|
|
29
|
+
validations:
|
|
30
|
+
required: false
|
|
31
|
+
- type: textarea
|
|
32
|
+
id: additional
|
|
33
|
+
attributes:
|
|
34
|
+
label: Additional context
|
|
35
|
+
description:
|
|
36
|
+
Add any other context or screenshots about the feature request here.
|
|
37
|
+
validations:
|
|
38
|
+
required: false
|
package/README.md
CHANGED
|
@@ -27,6 +27,8 @@ with valuable feedback from [Steffen](https://gist.github.com/steffen)\_
|
|
|
27
27
|
|
|
28
28
|
## Features
|
|
29
29
|
|
|
30
|
+
- :white_check_mark: npm version available
|
|
31
|
+
`npm i @zentered/issue-forms-body-parser`
|
|
30
32
|
- :white_check_mark: parse question/answer format into title/text as JSON
|
|
31
33
|
- :white_check_mark: parse line items and "tasks" with separate `checked`
|
|
32
34
|
attributes
|
|
@@ -86,6 +88,8 @@ See more examples in [md test cases](./test/test-issue-1.md) and
|
|
|
86
88
|
|
|
87
89
|
## Installation & Usage
|
|
88
90
|
|
|
91
|
+
### GitHub Actions
|
|
92
|
+
|
|
89
93
|
```yml
|
|
90
94
|
name: Issue Forms Body Parser
|
|
91
95
|
|
|
@@ -101,6 +105,22 @@ jobs:
|
|
|
101
105
|
- run: echo "${{ JSON.stringify(steps.parse.outputs.data) }}"
|
|
102
106
|
```
|
|
103
107
|
|
|
108
|
+
### NPM
|
|
109
|
+
|
|
110
|
+
The parser is available as a standalone library:
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
npm i @zentered/issue-forms-body-parser
|
|
114
|
+
# OR yarn add @zentered/issue-forms-body-parser
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Usage:
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
import bodyParser from '@zentered/issue-forms-body-parser'
|
|
121
|
+
const issueData = await bodyParser(issue.body)
|
|
122
|
+
```
|
|
123
|
+
|
|
104
124
|
## Development & Testing
|
|
105
125
|
|
|
106
126
|
You can use [act](https://github.com/nektos/act) to test this Action locally.
|
package/dist/index.js
CHANGED
|
@@ -51888,9 +51888,25 @@ function getDateTimeFormat(timeZone) {
|
|
|
51888
51888
|
return dtfCache[timeZone]
|
|
51889
51889
|
}
|
|
51890
51890
|
|
|
51891
|
+
;// CONCATENATED MODULE: ./node_modules/date-fns-tz/esm/_lib/newDateUTC/index.js
|
|
51892
|
+
/**
|
|
51893
|
+
* Use instead of `new Date(Date.UTC(...))` to support years below 100 which doesn't work
|
|
51894
|
+
* otherwise due to the nature of the
|
|
51895
|
+
* [`Date` constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date#interpretation_of_two-digit_years.
|
|
51896
|
+
*
|
|
51897
|
+
* For `Date.UTC(...)`, use `newDateUTC(...).getTime()`.
|
|
51898
|
+
*/
|
|
51899
|
+
function newDateUTC(fullYear, month, day, hour, minute, second, millisecond) {
|
|
51900
|
+
var utcDate = new Date(0)
|
|
51901
|
+
utcDate.setUTCFullYear(fullYear, month, day)
|
|
51902
|
+
utcDate.setUTCHours(hour, minute, second, millisecond)
|
|
51903
|
+
return utcDate
|
|
51904
|
+
}
|
|
51905
|
+
|
|
51891
51906
|
;// CONCATENATED MODULE: ./node_modules/date-fns-tz/esm/_lib/tzParseTimezone/index.js
|
|
51892
51907
|
|
|
51893
51908
|
|
|
51909
|
+
|
|
51894
51910
|
var MILLISECONDS_IN_HOUR = 3600000
|
|
51895
51911
|
var MILLISECONDS_IN_MINUTE = 60000
|
|
51896
51912
|
|
|
@@ -51961,23 +51977,30 @@ function tzParseTimezone(timezoneString, date, isUtcDate) {
|
|
|
51961
51977
|
}
|
|
51962
51978
|
|
|
51963
51979
|
function toUtcDate(date) {
|
|
51964
|
-
return
|
|
51965
|
-
|
|
51966
|
-
|
|
51967
|
-
|
|
51968
|
-
|
|
51969
|
-
|
|
51970
|
-
|
|
51971
|
-
|
|
51972
|
-
date.getMilliseconds()
|
|
51973
|
-
)
|
|
51980
|
+
return newDateUTC(
|
|
51981
|
+
date.getFullYear(),
|
|
51982
|
+
date.getMonth(),
|
|
51983
|
+
date.getDate(),
|
|
51984
|
+
date.getHours(),
|
|
51985
|
+
date.getMinutes(),
|
|
51986
|
+
date.getSeconds(),
|
|
51987
|
+
date.getMilliseconds()
|
|
51974
51988
|
)
|
|
51975
51989
|
}
|
|
51976
51990
|
|
|
51977
51991
|
function calcOffset(date, timezoneString) {
|
|
51978
51992
|
var tokens = tzTokenizeDate(date, timezoneString)
|
|
51979
51993
|
|
|
51980
|
-
|
|
51994
|
+
// ms dropped because it's not provided by tzTokenizeDate
|
|
51995
|
+
var asUTC = newDateUTC(
|
|
51996
|
+
tokens[0],
|
|
51997
|
+
tokens[1] - 1,
|
|
51998
|
+
tokens[2],
|
|
51999
|
+
tokens[3] % 24,
|
|
52000
|
+
tokens[4],
|
|
52001
|
+
tokens[5],
|
|
52002
|
+
0
|
|
52003
|
+
).getTime()
|
|
51981
52004
|
|
|
51982
52005
|
var asTS = date.getTime()
|
|
51983
52006
|
var over = asTS % 1000
|
|
@@ -52013,10 +52036,7 @@ function fixOffset(date, offset, timezoneString) {
|
|
|
52013
52036
|
}
|
|
52014
52037
|
|
|
52015
52038
|
function validateTimezone(hours, minutes) {
|
|
52016
|
-
return (
|
|
52017
|
-
(hours === 12 && (minutes == null || minutes === 0)) ||
|
|
52018
|
-
(-11 <= hours && hours <= 11 && (minutes == null || (0 <= minutes && minutes < 59)))
|
|
52019
|
-
)
|
|
52039
|
+
return -23 <= hours && hours <= 23 && (minutes == null || (0 <= minutes && minutes <= 59))
|
|
52020
52040
|
}
|
|
52021
52041
|
|
|
52022
52042
|
var validIANATimezoneCache = {}
|
|
@@ -52497,6 +52517,7 @@ function validateTime(hours, minutes, seconds) {
|
|
|
52497
52517
|
|
|
52498
52518
|
|
|
52499
52519
|
|
|
52520
|
+
|
|
52500
52521
|
/**
|
|
52501
52522
|
* @name zonedTimeToUtc
|
|
52502
52523
|
* @category Time Zone Helpers
|
|
@@ -52530,7 +52551,7 @@ function zonedTimeToUtc(date, timeZone, options) {
|
|
|
52530
52551
|
|
|
52531
52552
|
var d = toDate(date, options)
|
|
52532
52553
|
|
|
52533
|
-
var utc =
|
|
52554
|
+
var utc = newDateUTC(
|
|
52534
52555
|
d.getFullYear(),
|
|
52535
52556
|
d.getMonth(),
|
|
52536
52557
|
d.getDate(),
|
|
@@ -52538,7 +52559,7 @@ function zonedTimeToUtc(date, timeZone, options) {
|
|
|
52538
52559
|
d.getMinutes(),
|
|
52539
52560
|
d.getSeconds(),
|
|
52540
52561
|
d.getMilliseconds()
|
|
52541
|
-
)
|
|
52562
|
+
).getTime()
|
|
52542
52563
|
|
|
52543
52564
|
var offsetMilliseconds = tzParseTimezone(timeZone, new Date(utc))
|
|
52544
52565
|
|
|
@@ -52705,7 +52726,7 @@ function formatTimezone(offset, dirtyDelimeter) {
|
|
|
52705
52726
|
var sign = offset > 0 ? '-' : '+'
|
|
52706
52727
|
var absOffset = Math.abs(offset)
|
|
52707
52728
|
var hours = addLeadingZeros(Math.floor(absOffset / 60), 2)
|
|
52708
|
-
var minutes = addLeadingZeros(absOffset % 60, 2)
|
|
52729
|
+
var minutes = addLeadingZeros(Math.floor(absOffset % 60), 2)
|
|
52709
52730
|
return sign + hours + delimeter + minutes
|
|
52710
52731
|
}
|
|
52711
52732
|
|
|
@@ -53180,17 +53201,18 @@ const commonDateFormats = [
|
|
|
53180
53201
|
'dd.MM.yy'
|
|
53181
53202
|
]
|
|
53182
53203
|
|
|
53183
|
-
const commonTimeFormats = ['HH:mm', 'hh:mm a', 'hh:mm A']
|
|
53204
|
+
const commonTimeFormats = ['HH:mm', 'HH.mm', 'hh:mm a', 'hh:mm A']
|
|
53184
53205
|
|
|
53185
53206
|
function parse_parseDate(text) {
|
|
53186
53207
|
const match = commonDateFormats.map((format) => {
|
|
53187
53208
|
return (0,date_fns.isMatch)(text, format)
|
|
53188
53209
|
})
|
|
53189
53210
|
if (match.indexOf(true) > -1) {
|
|
53190
|
-
|
|
53211
|
+
const date = zonedTimeToUtc(
|
|
53191
53212
|
(0,date_fns.parse)(text, commonDateFormats[match.indexOf(true)], new Date()),
|
|
53192
53213
|
loc
|
|
53193
53214
|
).toJSON()
|
|
53215
|
+
return date.split('T')[0]
|
|
53194
53216
|
} else {
|
|
53195
53217
|
return null
|
|
53196
53218
|
}
|
|
@@ -53252,10 +53274,12 @@ async function parseMD(body) {
|
|
|
53252
53274
|
const current = tokens.children[idx]
|
|
53253
53275
|
const hasNext = idx + 1 < tokens.children.length
|
|
53254
53276
|
|
|
53255
|
-
const obj = {}
|
|
53256
53277
|
if (current.type === 'heading') {
|
|
53257
|
-
|
|
53258
|
-
obj
|
|
53278
|
+
// issue-form answers start with a h3 heading, ignore everything else
|
|
53279
|
+
const obj = {
|
|
53280
|
+
id: slugify(current.children[0].value),
|
|
53281
|
+
title: current.children[0].value
|
|
53282
|
+
}
|
|
53259
53283
|
if (hasNext) {
|
|
53260
53284
|
const next = tokens.children[idx + 1]
|
|
53261
53285
|
if (next.type === 'list') {
|
|
@@ -53274,8 +53298,8 @@ async function parseMD(body) {
|
|
|
53274
53298
|
obj.time = time
|
|
53275
53299
|
}
|
|
53276
53300
|
}
|
|
53301
|
+
r.push(obj)
|
|
53277
53302
|
}
|
|
53278
|
-
r.push(obj)
|
|
53279
53303
|
}
|
|
53280
53304
|
|
|
53281
53305
|
return r
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zentered/issue-forms-body-parser",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.4",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Parser for GitHub Issue Form body, also available as GitHub Action",
|
|
6
6
|
"keywords": [
|
|
@@ -49,16 +49,16 @@
|
|
|
49
49
|
"*.{js,json,md}": [
|
|
50
50
|
"prettier --write"
|
|
51
51
|
],
|
|
52
|
-
"*.
|
|
52
|
+
"*.js": [
|
|
53
53
|
"eslint --cache --fix"
|
|
54
54
|
]
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
57
|
"@actions/core": "^1.6.0",
|
|
58
|
-
"@actions/github": "^5.0.
|
|
58
|
+
"@actions/github": "^5.0.1",
|
|
59
59
|
"@sindresorhus/slugify": "^2.1.0",
|
|
60
60
|
"date-fns": "^2.28.0",
|
|
61
|
-
"date-fns-tz": "^1.3.
|
|
61
|
+
"date-fns-tz": "^1.3.3",
|
|
62
62
|
"remark-gfm": "^3.0.1",
|
|
63
63
|
"remark-parse": "^10.0.1",
|
|
64
64
|
"remark-stringify": "^10.0.2",
|
|
@@ -68,15 +68,15 @@
|
|
|
68
68
|
"@commitlint/config-conventional": "^16.2.1",
|
|
69
69
|
"@vercel/ncc": "^0.33.3",
|
|
70
70
|
"commitlint": "^16.2.3",
|
|
71
|
-
"eslint": "^8.
|
|
71
|
+
"eslint": "^8.12.0",
|
|
72
72
|
"eslint-plugin-json": "^3.1.0",
|
|
73
73
|
"eslint-plugin-node": "^11.1.0",
|
|
74
74
|
"husky": "^7.0.4",
|
|
75
75
|
"license-checker": "^25.0.1",
|
|
76
76
|
"npm-run-all": "^4.1.5",
|
|
77
77
|
"pinst": "^3.0.0",
|
|
78
|
-
"prettier": "^2.6.
|
|
79
|
-
"tap": "^16.0.
|
|
78
|
+
"prettier": "^2.6.2",
|
|
79
|
+
"tap": "^16.0.1"
|
|
80
80
|
},
|
|
81
81
|
"release": {
|
|
82
82
|
"branches": [
|
package/src/parse.js
CHANGED
|
@@ -20,17 +20,18 @@ const commonDateFormats = [
|
|
|
20
20
|
'dd.MM.yy'
|
|
21
21
|
]
|
|
22
22
|
|
|
23
|
-
const commonTimeFormats = ['HH:mm', 'hh:mm a', 'hh:mm A']
|
|
23
|
+
const commonTimeFormats = ['HH:mm', 'HH.mm', 'hh:mm a', 'hh:mm A']
|
|
24
24
|
|
|
25
25
|
function parseDate(text) {
|
|
26
26
|
const match = commonDateFormats.map((format) => {
|
|
27
27
|
return isMatch(text, format)
|
|
28
28
|
})
|
|
29
29
|
if (match.indexOf(true) > -1) {
|
|
30
|
-
|
|
30
|
+
const date = zonedTimeToUtc(
|
|
31
31
|
parse(text, commonDateFormats[match.indexOf(true)], new Date()),
|
|
32
32
|
loc
|
|
33
33
|
).toJSON()
|
|
34
|
+
return date.split('T')[0]
|
|
34
35
|
} else {
|
|
35
36
|
return null
|
|
36
37
|
}
|
|
@@ -92,10 +93,12 @@ export default async function parseMD(body) {
|
|
|
92
93
|
const current = tokens.children[idx]
|
|
93
94
|
const hasNext = idx + 1 < tokens.children.length
|
|
94
95
|
|
|
95
|
-
const obj = {}
|
|
96
96
|
if (current.type === 'heading') {
|
|
97
|
-
|
|
98
|
-
obj
|
|
97
|
+
// issue-form answers start with a h3 heading, ignore everything else
|
|
98
|
+
const obj = {
|
|
99
|
+
id: slugify(current.children[0].value),
|
|
100
|
+
title: current.children[0].value
|
|
101
|
+
}
|
|
99
102
|
if (hasNext) {
|
|
100
103
|
const next = tokens.children[idx + 1]
|
|
101
104
|
if (next.type === 'list') {
|
|
@@ -114,8 +117,8 @@ export default async function parseMD(body) {
|
|
|
114
117
|
obj.time = time
|
|
115
118
|
}
|
|
116
119
|
}
|
|
120
|
+
r.push(obj)
|
|
117
121
|
}
|
|
118
|
-
r.push(obj)
|
|
119
122
|
}
|
|
120
123
|
|
|
121
124
|
return r
|
package/test/parse-issue.test.js
CHANGED
|
@@ -23,7 +23,7 @@ test('parse(md) should parse GitHub Issue Form data into useful, structured data
|
|
|
23
23
|
id: 'date',
|
|
24
24
|
title: 'Date',
|
|
25
25
|
text: '11.03.2022\n',
|
|
26
|
-
date: '2022-03-
|
|
26
|
+
date: '2022-03-11'
|
|
27
27
|
},
|
|
28
28
|
{ id: 'time', title: 'Time', text: '16:00\n', time: '16:00' },
|
|
29
29
|
{ id: 'duration', title: 'Duration', text: '2h\n' },
|
|
@@ -90,3 +90,15 @@ test('parse(md) should parse GitHub Issue Form data into useful, structured data
|
|
|
90
90
|
// console.log(JSON.stringify(actual, null, 0))
|
|
91
91
|
t.deepEqual(actual, expected)
|
|
92
92
|
})
|
|
93
|
+
|
|
94
|
+
test('parse(md) return nothing', async (t) => {
|
|
95
|
+
const expected = []
|
|
96
|
+
|
|
97
|
+
const md = await readFile(
|
|
98
|
+
join(process.cwd(), 'test', 'test-issue-2.md'),
|
|
99
|
+
'utf8'
|
|
100
|
+
)
|
|
101
|
+
const actual = await fn(md)
|
|
102
|
+
// console.log(JSON.stringify(actual, null, 0))
|
|
103
|
+
t.deepEqual(actual, expected)
|
|
104
|
+
})
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: Bug report
|
|
3
|
-
about: Create a report to help us improve
|
|
4
|
-
title: ''
|
|
5
|
-
labels: ''
|
|
6
|
-
assignees: ''
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
**Describe the bug**
|
|
10
|
-
A clear and concise description of what the bug is.
|
|
11
|
-
|
|
12
|
-
**To Reproduce**
|
|
13
|
-
Steps to reproduce the behavior:
|
|
14
|
-
|
|
15
|
-
1. Go to '...'
|
|
16
|
-
2. Click on '....'
|
|
17
|
-
3. Scroll down to '....'
|
|
18
|
-
4. See error
|
|
19
|
-
|
|
20
|
-
**Expected behavior**
|
|
21
|
-
A clear and concise description of what you expected to happen.
|
|
22
|
-
|
|
23
|
-
**Additional context**
|
|
24
|
-
Add any other context about the problem here.
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: Feature request
|
|
3
|
-
about: Suggest an idea for this project
|
|
4
|
-
title: ''
|
|
5
|
-
labels: ''
|
|
6
|
-
assignees: ''
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
**Is your feature request related to a problem? Please describe.**
|
|
10
|
-
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
|
11
|
-
|
|
12
|
-
**Describe the solution you'd like**
|
|
13
|
-
A clear and concise description of what you want to happen.
|
|
14
|
-
|
|
15
|
-
**Describe alternatives you've considered**
|
|
16
|
-
A clear and concise description of any alternative solutions or features you've considered.
|
|
17
|
-
|
|
18
|
-
**Additional context**
|
|
19
|
-
Add any other context or screenshots about the feature request here.
|