@zentered/issue-forms-body-parser 2.1.5 → 3.0.0

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 CHANGED
@@ -118,9 +118,23 @@ jobs:
118
118
  - name: Issue Forms Body Parser
119
119
  id: parse
120
120
  uses: zentered/issue-forms-body-parser@v2.0.0
121
- - run: echo ${{ toJSON(steps.parse.outputs.data) }}
121
+ - name: Print parsed data
122
+ env:
123
+ DATA: ${{ steps.parse.outputs.data }}
124
+ run: echo "$DATA"
122
125
  ```
123
126
 
127
+ > **⚠️ Security:** The parsed `data` output is derived entirely from the issue
128
+ > body, which is **untrusted user input** - on `issues`-triggered workflows
129
+ > anyone who can open an issue controls it. Never interpolate it directly into a
130
+ > `run:` script (e.g. `run: echo ${{ steps.parse.outputs.data }}`): `toJSON()`
131
+ > escapes JSON, not shell metacharacters, so a value containing `$(...)` or
132
+ > backticks executes as a shell command. Always pass it through an `env:`
133
+ > variable and reference `"$DATA"` as shown above, and treat any field
134
+ > (including `links`/`images` URLs) as untrusted before using it in `ref:`, API
135
+ > calls, or other sinks. See [SECURITY.md](./SECURITY.md) for the full threat
136
+ > model.
137
+
124
138
  You can also provide a custom `body` input:
125
139
 
126
140
  ```yml
@@ -141,17 +155,27 @@ jobs:
141
155
  steps:
142
156
  - name: Fetch the issue
143
157
  id: read_issue_body
144
- run:
145
- echo "body=$(gh issue view ${{ inputs.issue_number }} --repo ${{
146
- github.repo }} --json body --jq '.body')" >> $GITHUB_OUTPUT
158
+ env:
159
+ ISSUE_NUMBER: ${{ inputs.issue_number }}
160
+ REPO: ${{ github.repository }}
161
+ run: |
162
+ delimiter="$(openssl rand -hex 8)"
163
+ {
164
+ echo "body<<$delimiter"
165
+ gh issue view "$ISSUE_NUMBER" --repo "$REPO" --json body --jq '.body'
166
+ echo "$delimiter"
167
+ } >> "$GITHUB_OUTPUT"
147
168
 
148
169
  - name: Issue Forms Body Parser
149
170
  id: parse
150
171
  uses: zentered/issue-forms-body-parser@v2.0.0
151
172
  with:
152
- body: ${{ steps.read_issue_body.output.body }}
173
+ body: ${{ steps.read_issue_body.outputs.body }}
153
174
 
154
- - run: echo ${{ toJSON(steps.parse.outputs.data) }}
175
+ - name: Print parsed data
176
+ env:
177
+ DATA: ${{ steps.parse.outputs.data }}
178
+ run: echo "$DATA"
155
179
  ```
156
180
 
157
181
  ### NPM
package/SECURITY.md ADDED
@@ -0,0 +1,80 @@
1
+ # Security Policy
2
+
3
+ ## Reporting a Vulnerability
4
+
5
+ Please report security vulnerabilities privately through GitHub's
6
+ [private vulnerability reporting](https://github.com/zentered/issue-forms-body-parser/security/advisories/new)
7
+ rather than opening a public issue. We will acknowledge receipt and work with
8
+ you on a fix and coordinated disclosure.
9
+
10
+ ## Threat Model
11
+
12
+ This action and the `@zentered/issue-forms-body-parser` package parse a GitHub
13
+ issue body into structured data. The issue body is **untrusted input**: on
14
+ `issues`-triggered workflows, anyone who can open an issue in your repository
15
+ controls its full content.
16
+
17
+ The parser itself does not execute, evaluate, or shell out to anything in the
18
+ issue body - it only walks a Markdown AST and returns a plain object. The
19
+ security boundary therefore sits in **how a consuming workflow uses the parsed
20
+ output**, not in the action's runtime.
21
+
22
+ ### What the action guarantees
23
+
24
+ - It never runs `eval`, a shell, or a subprocess on issue content.
25
+ - It emits its result through `@actions/core` `setOutput`, which uses a
26
+ random-delimiter guard. An attacker cannot break out of the `data` value to
27
+ inject additional step outputs or workflow commands.
28
+
29
+ ### What the action cannot guarantee
30
+
31
+ - The **content** of `data` is the user's parsed text by design (an event
32
+ description may legitimately contain `$`, backticks, or quotes). It is not and
33
+ cannot be sanitized into a "safe" string without corrupting the data.
34
+ - What your workflow does with that output is outside the action's control.
35
+
36
+ ## Using the output safely
37
+
38
+ Treat every field of `outputs.data` (including `links`/`images` URLs) as
39
+ attacker-controlled.
40
+
41
+ **Never** interpolate the output directly into a `run:` script. GitHub Actions
42
+ expands `${{ }}` into the script text _before_ the shell runs, and `toJSON()`
43
+ escapes JSON metacharacters but **not** shell metacharacters - so a value
44
+ containing `$(...)` or backticks executes as a command:
45
+
46
+ ```yml
47
+ # UNSAFE - command injection
48
+ - run: echo ${{ toJSON(steps.parse.outputs.data) }}
49
+ ```
50
+
51
+ **Always** pass the output through an `env:` variable and reference it with a
52
+ quoted shell variable. Values set via `env:` are passed to the runner as literal
53
+ environment variables and are not re-interpolated into the script:
54
+
55
+ ```yml
56
+ # SAFE
57
+ - name: Print parsed data
58
+ env:
59
+ DATA: ${{ steps.parse.outputs.data }}
60
+ run: echo "$DATA"
61
+ ```
62
+
63
+ The same applies to any other sink. Do not place parsed values into a `ref:`
64
+ parameter, a `gh`/API call, a database query, or HTML without validating or
65
+ encoding them for that context first.
66
+
67
+ ## Token permissions
68
+
69
+ Workflows that run this action on `issues` execute in the trusted base-repo
70
+ context. Apply least privilege so a mistake cannot be leveraged into a
71
+ supply-chain foothold:
72
+
73
+ ```yml
74
+ permissions:
75
+ contents: read
76
+ ```
77
+
78
+ If the job does not push or create releases, keep the default `GITHUB_TOKEN`
79
+ read-only and set `persist-credentials: false` on `actions/checkout` so the
80
+ token is not written to `.git/config`.
@@ -0,0 +1,92 @@
1
+ # Design: Return `null` for empty ("No response") fields
2
+
3
+ Related issue:
4
+ [#40](https://github.com/zentered/issue-forms-body-parser/issues/40)
5
+
6
+ ## Problem
7
+
8
+ GitHub Issue Forms render an optional field that was left blank as the literal
9
+ markdown `_No response_`. By the time `parse.js` re-stringifies the paragraph
10
+ with `remark-stringify`'s default emphasis marker, `_No response_` is normalized
11
+ to `*No response*`. The parser currently treats this like any other paragraph,
12
+ producing:
13
+
14
+ ```json
15
+ "field": {
16
+ "title": "field",
17
+ "heading": 3,
18
+ "content": ["*No response*"],
19
+ "text": "*No response*"
20
+ }
21
+ ```
22
+
23
+ This leaks an internal markdown placeholder into the structured output, forcing
24
+ consumers to special-case the string `*No response*`.
25
+
26
+ ## Solution
27
+
28
+ In `src/parse.js`, inside the `paragraph` branch, after computing `cleanText`:
29
+
30
+ 1. If the trimmed `cleanText` is `*No response*` or `_No response_`, treat the
31
+ field as empty:
32
+ - Matching both forms covers `remark-stringify`'s default asterisk emphasis
33
+ (the normal case for the GitHub Issue Forms placeholder) as well as the
34
+ underscore form, which can occur if `cleanText` contains escaped
35
+ underscores that get unescaped back to `_No response_` by the `\\_` cleanup
36
+ step earlier in the loop.
37
+ - Do not run date/time/duration/links/images parsing on it.
38
+ - Do not push it into `obj.content`.
39
+ - Set `obj.text = null` directly.
40
+ 2. Otherwise, process the paragraph as today.
41
+
42
+ ### Why this is sufficient
43
+
44
+ The closing loop in `parse.js` (the `for (const key in structuredResponse)`
45
+ block) only overwrites `token.text` when `content.length > 0`. Since the "No
46
+ response" placeholder paragraph is never pushed to `content`, `content` stays
47
+ `[]`, and the explicit `obj.text = null` set above is preserved.
48
+
49
+ ### Resulting shape
50
+
51
+ ```json
52
+ "field": {
53
+ "title": "field",
54
+ "heading": 3,
55
+ "content": [],
56
+ "text": null
57
+ }
58
+ ```
59
+
60
+ ## Edge cases
61
+
62
+ - **Checkbox / task lists**: GitHub always renders a checked/unchecked state for
63
+ these, never `_No response_`. No change needed in the `list` branch.
64
+ - **Code-block fields** (e.g. fields with a code-language hint): an empty
65
+ textarea renders as a `_No response_` paragraph, not an empty code block.
66
+ Already covered by the paragraph branch.
67
+ - **Multiple paragraphs under one heading where only one is `*No response*`**
68
+ (unlikely in practice, since GitHub Issue Forms map one field to one
69
+ paragraph): only the `*No response*` paragraph is skipped; remaining
70
+ paragraphs are joined normally.
71
+
72
+ ## Testing
73
+
74
+ Update `test/parse-issue.test.js` expectations for:
75
+
76
+ - `repository-description` (currently
77
+ `content: ['*No response*'], text: '*No response*'`)
78
+ - `repository-justification` (same)
79
+
80
+ Both become `content: [], text: null`.
81
+
82
+ Add a fixture field whose raw markdown contains escaped underscores
83
+ (`\_No response\_`), which `parse.js` unescapes back to `_No response_` before
84
+ the placeholder check. This covers the underscore branch of the check added
85
+ above, expecting `content: [], text: null`.
86
+
87
+ ## Versioning
88
+
89
+ This changes the type of `.text` for previously-empty fields from `string` to
90
+ `null`. Consumers calling string methods on `.text` for an empty field would
91
+ break. Commit as `fix!:` with a `BREAKING CHANGE:` footer, triggering a major
92
+ version bump per semantic-release.
@@ -0,0 +1,42 @@
1
+ import js from '@eslint/js'
2
+ import n from 'eslint-plugin-n'
3
+ import json from '@eslint/json'
4
+ import globals from 'globals'
5
+
6
+ export default [
7
+ {
8
+ ignores: [
9
+ 'dist/**',
10
+ 'action/**',
11
+ 'pkg/**',
12
+ 'coverage/**',
13
+ 'test/**',
14
+ 'package-lock.json',
15
+ 'eslint.config.js'
16
+ ]
17
+ },
18
+ {
19
+ files: ['**/*.js'],
20
+ plugins: {
21
+ ...n.configs['flat/recommended'].plugins
22
+ },
23
+ languageOptions: {
24
+ ecmaVersion: 2021,
25
+ sourceType: 'module',
26
+ globals: {
27
+ ...globals.node,
28
+ ...globals.es2021
29
+ }
30
+ },
31
+ rules: {
32
+ ...js.configs.recommended.rules,
33
+ ...n.configs['flat/recommended'].rules
34
+ }
35
+ },
36
+ {
37
+ files: ['**/*.json'],
38
+ plugins: { json },
39
+ language: 'json/json',
40
+ rules: json.configs.recommended.rules
41
+ }
42
+ ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zentered/issue-forms-body-parser",
3
- "version": "2.1.5",
3
+ "version": "3.0.0",
4
4
  "private": false,
5
5
  "description": "Parser for GitHub Issue Form body, also available as GitHub Action",
6
6
  "keywords": [
@@ -68,34 +68,39 @@
68
68
  ]
69
69
  },
70
70
  "dependencies": {
71
- "@actions/core": "^1.10.1",
72
- "@actions/github": "^6.0.0",
73
- "@sindresorhus/slugify": "^2.2.1",
74
- "date-fns": "^2.30.0",
75
- "date-fns-tz": "^2.0.0",
76
- "debug": "^4.3.4",
77
- "is-ci": "^3.0.1",
78
- "remark-gfm": "^4.0.0",
71
+ "@actions/core": "^3.0.1",
72
+ "@actions/github": "^9.1.1",
73
+ "@sindresorhus/slugify": "^3.0.0",
74
+ "date-fns": "^4.4.0",
75
+ "date-fns-tz": "^3.2.0",
76
+ "debug": "^4.4.3",
77
+ "is-ci": "^4.1.0",
78
+ "remark-gfm": "^4.0.1",
79
79
  "remark-parse": "^11.0.0",
80
80
  "remark-stringify": "^11.0.0",
81
- "strip-final-newline": "^3.0.0",
82
- "unified": "^11.0.4"
81
+ "strip-final-newline": "^4.0.0",
82
+ "unified": "^11.0.5"
83
83
  },
84
84
  "devDependencies": {
85
- "@commitlint/config-conventional": "^18.1.0",
86
- "@vercel/ncc": "^0.38.1",
87
- "commitlint": "^18.2.0",
88
- "eslint": "^8.53.0",
89
- "eslint-plugin-json": "^3.1.0",
90
- "eslint-plugin-node": "^11.1.0",
91
- "husky": "^8.0.3",
85
+ "@commitlint/config-conventional": "^21.0.2",
86
+ "@eslint/js": "^10.0.1",
87
+ "@eslint/json": "^2.0.0",
88
+ "@vercel/ncc": "^0.44.0",
89
+ "commitlint": "^21.0.2",
90
+ "eslint": "^10.4.1",
91
+ "eslint-plugin-n": "^18.1.0",
92
+ "globals": "^17.6.0",
93
+ "husky": "^9.1.7",
92
94
  "license-checker": "^25.0.1",
93
95
  "microbundle": "^0.15.1",
94
96
  "npm-run-all": "^4.1.5",
95
- "prettier": "^3.0.3"
97
+ "prettier": "^3.8.4"
96
98
  },
97
99
  "engines": {
98
100
  "node": ">=18"
99
101
  },
102
+ "overrides": {
103
+ "serialize-javascript": "7.0.5"
104
+ },
100
105
  "src": "src/parse.js"
101
106
  }
package/pkg/parse.cjs CHANGED
@@ -1,2 +1,2 @@
1
- var e=require("unified"),n=require("remark-parse"),t=require("remark-gfm"),r=require("@sindresorhus/slugify"),i=require("remark-stringify"),u=require("strip-final-newline"),a=require("debug"),o=require("date-fns"),f=require("date-fns-tz");function l(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var d=/*#__PURE__*/l(n),h=/*#__PURE__*/l(t),c=/*#__PURE__*/l(r),s=/*#__PURE__*/l(i),v=/*#__PURE__*/l(u),y=/*#__PURE__*/l(a);function m(e,n){(null==n||n>e.length)&&(n=e.length);for(var t=0,r=new Array(n);t<n;t++)r[t]=e[t];return r}var p=["yyyy-MM-dd","dd/MM/yyyy","dd/MM/yy","dd-MM-yyyy","dd-MM-yy","dd.MM.yyyy","dd.MM.yy"],g=["HH:mm","HH.mm","hh:mm aaa","hh:mm a..aa","hh:mm aaaa"],b=function e(n){return n.children.map(function(t){var r={};return"list"===t.type?e(n):"listItem"===t.type?(r.checked=t.checked,t.children.map(function(e){if("paragraph"===e.type)return r.text=e.children.map(function(e){return"link"===e.type?(r.link=e.url,"["+e.children[0].value+"]("+e.url+")"):e.value}).filter(function(e){return!!e}).join(""),r}).filter(function(e){return!!e})):void 0}).filter(function(e){return!!e})};function M(e,n,t){if(!e.s){if(t instanceof x){if(!t.s)return void(t.o=M.bind(null,e,n));1&n&&(n=t.s),t=t.v}if(t&&t.then)return void t.then(M.bind(null,e,n),M.bind(null,e,2));e.s=n,e.v=t;var r=e.o;r&&r(e)}}var x=/*#__PURE__*/function(){function e(){}return e.prototype.then=function(n,t){var r=new e,i=this.s;if(i){var u=1&i?n:t;if(u){try{M(r,1,u(this.v))}catch(e){M(r,2,e)}return r}return this}return this.o=function(e){try{var i=e.v;1&e.s?M(r,1,n?n(i):i):t?M(r,1,t(i)):M(r,2,i)}catch(e){M(r,2,e)}},r},e}();function k(e){return e instanceof x&&1&e.s}var w=y.default("body-parser");module.exports=function(n){try{var t,r,i,u,a,l,y,T,q,I,O,j,A;return w("parseMD()"),Promise.resolve(e.unified().use(d.default).use(h.default).parse(n)).then(function(n){function d(){for(O in H)(A=(j=H[O]).content.filter(Boolean))&&A.length>0&&(1===A.length&&(j.text=A[0]),j.text=A.join("\n\n")),j.content=A;return H}if(!n)return[];var H={},S=null;t=function(e,n){var t="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(t)return(t=t.call(e)).next.bind(t);if(Array.isArray(e)||(t=function(e,n){if(e){if("string"==typeof e)return m(e,n);var t=Object.prototype.toString.call(e).slice(8,-1);return"Object"===t&&e.constructor&&(t=e.constructor.name),"Map"===t||"Set"===t?Array.from(e):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?m(e,n):void 0}}(e))){t&&(e=t);var r=0;return function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(n.children);var U=function(e,n,t){for(var r;;){var i=e();if(k(i)&&(i=i.v),!i)return u;if(i.then){r=0;break}var u=t();if(u&&u.then){if(!k(u)){r=1;break}u=u.s}if(n){var a=n();if(a&&a.then&&!k(a)){r=2;break}}}var o=new x,f=M.bind(null,o,2);return(0===r?i.then(d):1===r?u.then(l):a.then(h)).then(void 0,f),o;function l(r){u=r;do{if(n&&(a=n())&&a.then&&!k(a))return void a.then(h).then(void 0,f);if(!(i=e())||k(i)&&!i.v)return void M(o,1,u);if(i.then)return void i.then(d).then(void 0,f);k(u=t())&&(u=u.v)}while(!u||!u.then);u.then(l).then(void 0,f)}function d(e){e?(u=t())&&u.then?u.then(l).then(void 0,f):l(u):M(o,1,u)}function h(){(i=e())?i.then?i.then(d).then(void 0,f):d(i):M(o,1,u)}}(function(){return!(r=t()).done},void 0,function(){return i=r.value,Promise.resolve(e.unified().use(h.default).use(s.default).stringify(i)).then(function(e){var n,t;(u=v.default(e)).indexOf("\\_")>-1&&(u=u.replace(/\\_/g,"_")),"heading"===i.type?(S=c.default(i.children[0].value),H[S]={title:i.children[0].value,heading:i.depth,content:[]}):"paragraph"===i.type&&S?(a=H[S],n=u,t=p.map(function(e){return o.isMatch(n,e)}),l=t.indexOf(!0)>-1?f.zonedTimeToUtc(o.parse(n,p[t.indexOf(!0)],new Date),"UTC").toJSON().split("T")[0]:null,y=function(e){var n=g.map(function(n){return o.isMatch(e,n)});if(n.indexOf(!0)>-1){var t=f.zonedTimeToUtc(o.parse(e,g[n.indexOf(!0)],new Date),"UTC");return f.formatInTimeZone(t,"UTC","HH:mm")}return null}(u),T=function(e){var n=!1,t={hours:0,minutes:0},r=new RegExp(/([0-9]+)h([0-9]+)m/),i=new RegExp(/([0-9]+)h/);if(e.match(r)){n=!0;var u=e.match(r),a=u[2];t.hours=parseInt(u[1]),t.minutes=parseInt(a)}else if(e.match(i)){n=!0;var o=e.match(i);t.hours=parseInt(o[1]),t.minutes=0}return n?t:null}(u),l&&(a.date=l),y&&(a.time=y),T&&(a.duration=T),a.content.push(u)):"list"===i.type?((q=H[S]).text=u,q.list=b(i).flat()):"html"===i.type?H[S].content.push(i.html):"code"===i.type?((I=H[S]).lang=i.lang,I.text=u):(w("unhandled token type"),w(i))})});return U&&U.then?U.then(d):d()})}catch(e){return Promise.reject(e)}};
1
+ var e=require("unified"),n=require("remark-parse"),t=require("remark-gfm"),r=require("@sindresorhus/slugify"),i=require("remark-stringify"),u=require("strip-final-newline"),a=require("debug"),o=require("date-fns"),f=require("date-fns-tz");function l(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var d=/*#__PURE__*/l(n),h=/*#__PURE__*/l(t),c=/*#__PURE__*/l(r),s=/*#__PURE__*/l(i),v=/*#__PURE__*/l(u),m=/*#__PURE__*/l(a);function y(e,n){(null==n||n>e.length)&&(n=e.length);for(var t=0,r=Array(n);t<n;t++)r[t]=e[t];return r}var p=["yyyy-MM-dd","dd/MM/yyyy","dd/MM/yy","dd-MM-yyyy","dd-MM-yy","dd.MM.yyyy","dd.MM.yy"],g=["HH:mm","HH.mm","hh:mm aaa","hh:mm a..aa","hh:mm aaaa"],b=function e(n){return n.children.map(function(t){var r={};return"list"===t.type?e(n):"listItem"===t.type?(r.checked=t.checked,t.children.map(function(e){if("paragraph"===e.type)return r.text=e.children.map(function(e){return"link"===e.type?(r.link=e.url,"["+e.children[0].value+"]("+e.url+")"):e.value}).filter(function(e){return!!e}).join(""),r}).filter(function(e){return!!e})):void 0}).filter(function(e){return!!e})};function M(e,n,t){if(!e.s){if(t instanceof x){if(!t.s)return void(t.o=M.bind(null,e,n));1&n&&(n=t.s),t=t.v}if(t&&t.then)return void t.then(M.bind(null,e,n),M.bind(null,e,2));e.s=n,e.v=t;var r=e.o;r&&r(e)}}var x=/*#__PURE__*/function(){function e(){}return e.prototype.then=function(n,t){var r=new e,i=this.s;if(i){var u=1&i?n:t;if(u){try{M(r,1,u(this.v))}catch(e){M(r,2,e)}return r}return this}return this.o=function(e){try{var i=e.v;1&e.s?M(r,1,n?n(i):i):t?M(r,1,t(i)):M(r,2,i)}catch(e){M(r,2,e)}},r},e}();function k(e){return e instanceof x&&1&e.s}var w=m.default("body-parser");module.exports=function(n){try{var t,r,i,u,a,l,m,q,I,T,O,j,A,H,S,_;return w("parseMD()"),Promise.resolve(e.unified().use(d.default).use(h.default).parse(n)).then(function(n){function d(){for(H in C)(_=(S=C[H]).content.filter(Boolean))&&_.length>0&&(1===_.length&&(S.text=_[0]),S.text=_.join("\n\n")),S.content=_;return C}if(!n)return[];var C={},U=null;t=function(e,n){var t="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(t)return(t=t.call(e)).next.bind(t);if(Array.isArray(e)||(t=function(e,n){if(e){if("string"==typeof e)return y(e,n);var t={}.toString.call(e).slice(8,-1);return"Object"===t&&e.constructor&&(t=e.constructor.name),"Map"===t||"Set"===t?Array.from(e):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?y(e,n):void 0}}(e))){t&&(e=t);var r=0;return function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(n.children);var D=function(e,n,t){for(var r;;){var i=e();if(k(i)&&(i=i.v),!i)return u;if(i.then){r=0;break}var u=t();if(u&&u.then){if(!k(u)){r=1;break}u=u.s}if(n){var a=n();if(a&&a.then&&!k(a)){r=2;break}}}var o=new x,f=M.bind(null,o,2);return(0===r?i.then(d):1===r?u.then(l):a.then(h)).then(void 0,f),o;function l(r){u=r;do{if(n&&(a=n())&&a.then&&!k(a))return void a.then(h).then(void 0,f);if(!(i=e())||k(i)&&!i.v)return void M(o,1,u);if(i.then)return void i.then(d).then(void 0,f);k(u=t())&&(u=u.v)}while(!u||!u.then);u.then(l).then(void 0,f)}function d(e){e?(u=t())&&u.then?u.then(l).then(void 0,f):l(u):M(o,1,u)}function h(){(i=e())?i.then?i.then(d).then(void 0,f):d(i):M(o,1,u)}}(function(){return!(r=t()).done},void 0,function(){return i=r.value,Promise.resolve(e.unified().use(h.default).use(s.default).stringify(i)).then(function(e){if((u=v.default(e)).indexOf("\\_")>-1&&(u=u.replace(/\\_/g,"_")),"heading"===i.type)U=c.default(i.children[0].value),C[U]={title:i.children[0].value,heading:i.depth,content:[]};else if("paragraph"===i.type&&U){if(a=C[U],"*No response*"===(l=u.trim())||"_No response_"===l)return void(a.text=null);n=u,t=p.map(function(e){return o.isMatch(n,e)}),m=t.indexOf(!0)>-1?f.fromZonedTime(o.parse(n,p[t.indexOf(!0)],new Date),"UTC").toJSON().split("T")[0]:null,q=i.children.filter(function(e){return"image"===e.type}).map(function(e){return{src:e.url,alt:e.alt}}),I=i.children.filter(function(e){return"link"===e.type}).map(function(e){return{src:e.url,alt:e.children[0].value}}),T=function(e){var n=g.map(function(n){return o.isMatch(e,n)});if(n.indexOf(!0)>-1){var t=f.fromZonedTime(o.parse(e,g[n.indexOf(!0)],new Date),"UTC");return f.formatInTimeZone(t,"UTC","HH:mm")}return null}(u),O=function(e){var n=!1,t={hours:0,minutes:0},r=new RegExp(/([0-9]+)h([0-9]+)m/),i=new RegExp(/([0-9]+)h/);if(e.match(r)){n=!0;var u=e.match(r),a=u[2];t.hours=parseInt(u[1]),t.minutes=parseInt(a)}else if(e.match(i)){n=!0;var o=e.match(i);t.hours=parseInt(o[1]),t.minutes=0}return n?t:null}(u),m&&(a.date=m),T&&(a.time=T),O&&(a.duration=O),I&&I.length>0&&(a.links=I),q&&q.length>0&&(a.images=q),a.content.push(u)}else"list"===i.type?((j=C[U]).text=u,j.list=b(i).flat()):"html"===i.type?C[U].content.push(i.html):"code"===i.type?((A=C[U]).lang=i.lang,A.text=u):(w("unhandled token type"),w(i));var n,t})});return D&&D.then?D.then(d):d()})}catch(e){return Promise.reject(e)}};
2
2
  //# sourceMappingURL=parse.cjs.map
package/pkg/parse.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"parse.cjs","sources":["../src/parsers/date.js","../src/parsers/time.js","../src/parsers/index.js","../src/parsers/list.js","../src/parse.js","../src/parsers/duration.js"],"sourcesContent":["'use strict'\n\nimport { parse, isMatch } from 'date-fns'\nimport { zonedTimeToUtc } from 'date-fns-tz'\n\nconst loc = 'UTC'\nconst commonDateFormats = [\n 'yyyy-MM-dd',\n 'dd/MM/yyyy',\n 'dd/MM/yy',\n 'dd-MM-yyyy',\n 'dd-MM-yy',\n 'dd.MM.yyyy',\n 'dd.MM.yy'\n]\n\nexport default function parseDate(text) {\n const match = commonDateFormats.map((format) => {\n return isMatch(text, format)\n })\n if (match.indexOf(true) > -1) {\n const date = zonedTimeToUtc(\n parse(text, commonDateFormats[match.indexOf(true)], new Date()),\n loc\n ).toJSON()\n return date.split('T')[0]\n } else {\n return null\n }\n}\n","'use strict'\n\nimport { parse, isMatch } from 'date-fns'\nimport { zonedTimeToUtc, formatInTimeZone } from 'date-fns-tz'\n\nconst loc = 'UTC'\nconst commonTimeFormats = [\n 'HH:mm',\n 'HH.mm',\n 'hh:mm aaa',\n 'hh:mm a..aa',\n 'hh:mm aaaa'\n]\n\nexport default function parseTime(text) {\n const match = commonTimeFormats.map((format) => {\n return isMatch(text, format)\n })\n if (match.indexOf(true) > -1) {\n const time = zonedTimeToUtc(\n parse(text, commonTimeFormats[match.indexOf(true)], new Date()),\n loc\n )\n return formatInTimeZone(time, loc, 'HH:mm')\n } else {\n return null\n }\n}\n","'use strict'\n\nimport date from './date.js'\nimport time from './time.js'\nimport duration from './duration.js'\nimport list from './list.js'\n\nexport const parseDate = date\nexport const parseTime = time\nexport const parseDuration = duration\nexport const parseList = list\n","'use strict'\n\nexport default function parseList(list) {\n return list.children\n .map((item) => {\n const listItem = {}\n if (item.type === 'list') {\n return parseList(list)\n } else if (item.type === 'listItem') {\n listItem.checked = item.checked\n return item.children\n .map((child) => {\n if (child.type === 'paragraph') {\n listItem.text = child.children\n .map((c) => {\n if (c.type === 'link') {\n listItem.link = c.url\n return `[${c.children[0].value}](${c.url})`\n } else {\n return c.value\n }\n })\n .filter((x) => !!x)\n .join('')\n return listItem\n }\n })\n .filter((x) => !!x)\n }\n })\n .filter((x) => !!x)\n}\n","'use strict'\n\nimport { unified } from 'unified'\nimport remarkParse from 'remark-parse'\nimport remarkGfm from 'remark-gfm'\nimport slugify from '@sindresorhus/slugify'\nimport remarkStringify from 'remark-stringify'\nimport stripFinalNewline from 'strip-final-newline'\nimport createDebug from 'debug'\nconst debug = createDebug('body-parser')\n\nimport {\n parseDate,\n parseTime,\n parseDuration,\n parseList\n} from './parsers/index.js'\n\nexport default async function parseMD(body) {\n debug('parseMD()')\n const tokens = await unified().use(remarkParse).use(remarkGfm).parse(body)\n if (!tokens) {\n return []\n }\n\n const structuredResponse = {}\n let currentHeading = null\n for (const token of tokens.children) {\n const text = await unified()\n .use(remarkGfm)\n .use(remarkStringify)\n .stringify(token)\n let cleanText = stripFinalNewline(text)\n\n // remove `\\\\_`\n if (cleanText.indexOf('\\\\_') > -1) {\n cleanText = cleanText.replace(/\\\\_/g, '_')\n }\n\n // issue forms uses h3 as a heading\n if (token.type === 'heading') {\n currentHeading = slugify(token.children[0].value)\n structuredResponse[currentHeading] = {\n title: token.children[0].value,\n heading: token.depth,\n content: []\n }\n } else if (token.type === 'paragraph' && currentHeading) {\n const obj = structuredResponse[currentHeading]\n\n const date = parseDate(cleanText)\n const time = parseTime(cleanText)\n const duration = parseDuration(cleanText)\n\n if (date) {\n obj.date = date\n }\n\n if (time) {\n obj.time = time\n }\n\n if (duration) {\n obj.duration = duration\n }\n\n obj.content.push(cleanText)\n } else if (token.type === 'list') {\n const obj = structuredResponse[currentHeading]\n obj.text = cleanText\n obj.list = parseList(token).flat()\n } else if (token.type === 'html') {\n const obj = structuredResponse[currentHeading]\n obj.content.push(token.html)\n } else if (token.type === 'code') {\n const obj = structuredResponse[currentHeading]\n obj.lang = token.lang\n obj.text = cleanText\n } else {\n debug('unhandled token type')\n debug(token)\n }\n }\n\n for (const key in structuredResponse) {\n const token = structuredResponse[key]\n const content = token.content.filter(Boolean)\n if (content && content.length > 0) {\n if (content.length === 1) {\n token.text = content[0]\n }\n token.text = content.join('\\n\\n')\n }\n token.content = content\n }\n\n return structuredResponse\n}\n","'use strict'\n\nexport default function parseDuration(text) {\n let matched = false\n const duration = {\n hours: 0,\n minutes: 0\n }\n\n const hoursAndMinutes = new RegExp(/([0-9]+)h([0-9]+)m/)\n const hours = new RegExp(/([0-9]+)h/)\n\n if (text.match(hoursAndMinutes)) {\n matched = true\n const [, h, m] = text.match(hoursAndMinutes)\n duration.hours = parseInt(h)\n duration.minutes = parseInt(m)\n } else if (text.match(hours)) {\n matched = true\n const [, h] = text.match(hours)\n duration.hours = parseInt(h)\n duration.minutes = 0\n }\n\n if (matched) {\n return duration\n } else {\n return null\n }\n}\n"],"names":["commonDateFormats","commonTimeFormats","parseList","list","children","map","item","listItem","type","checked","child","text","c","link","url","value","filter","x","join","_settle","pact","state","s","_Pact","o","bind","v","then","observer","prototype","onFulfilled","onRejected","result","this","callback","e","_this","_isSettledPact","thenable","debug","createDebug","body","_iterator","_step","token","cleanText","obj","date","time","duration","key","content","Promise","resolve","unified","use","remarkParse","remarkGfm","parse","tokens","_temp2","structuredResponse","Boolean","length","currentHeading","_createForOfIteratorHelperLoose","_temp","test","update","stage","shouldContinue","updateValue","reject","_resumeAfterTest","_resumeAfterBody","_resumeAfterUpdate","_for","done","remarkStringify","stringify","_unified$use$use$stri","match","stripFinalNewline","indexOf","replace","slugify","title","heading","depth","format","isMatch","zonedTimeToUtc","Date","toJSON","split","formatInTimeZone","parseTime","matched","hours","minutes","hoursAndMinutes","RegExp","_text$match","m","parseInt","_text$match2","parseDuration","push","flat","html","lang"],"mappings":"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"}
1
+ {"version":3,"file":"parse.cjs","sources":["../src/parsers/date.js","../src/parsers/time.js","../src/parsers/index.js","../src/parsers/list.js","../src/parse.js","../src/parsers/images.js","../src/parsers/links.js","../src/parsers/duration.js"],"sourcesContent":["'use strict'\n\nimport { parse, isMatch } from 'date-fns'\nimport { fromZonedTime } from 'date-fns-tz'\n\nconst loc = 'UTC'\nconst commonDateFormats = [\n 'yyyy-MM-dd',\n 'dd/MM/yyyy',\n 'dd/MM/yy',\n 'dd-MM-yyyy',\n 'dd-MM-yy',\n 'dd.MM.yyyy',\n 'dd.MM.yy'\n]\n\nexport default function parseDate(text) {\n const match = commonDateFormats.map((format) => {\n return isMatch(text, format)\n })\n if (match.indexOf(true) > -1) {\n const date = fromZonedTime(\n parse(text, commonDateFormats[match.indexOf(true)], new Date()),\n loc\n ).toJSON()\n return date.split('T')[0]\n } else {\n return null\n }\n}\n","'use strict'\n\nimport { parse, isMatch } from 'date-fns'\nimport { fromZonedTime, formatInTimeZone } from 'date-fns-tz'\n\nconst loc = 'UTC'\nconst commonTimeFormats = [\n 'HH:mm',\n 'HH.mm',\n 'hh:mm aaa',\n 'hh:mm a..aa',\n 'hh:mm aaaa'\n]\n\nexport default function parseTime(text) {\n const match = commonTimeFormats.map((format) => {\n return isMatch(text, format)\n })\n if (match.indexOf(true) > -1) {\n const time = fromZonedTime(\n parse(text, commonTimeFormats[match.indexOf(true)], new Date()),\n loc\n )\n return formatInTimeZone(time, loc, 'HH:mm')\n } else {\n return null\n }\n}\n","'use strict'\n\nimport date from './date.js'\nimport time from './time.js'\nimport duration from './duration.js'\nimport list from './list.js'\nimport images from './images.js'\nimport links from './links.js'\n\nexport const parseDate = date\nexport const parseTime = time\nexport const parseDuration = duration\nexport const parseList = list\nexport const parseImages = images\nexport const parseLinks = links\n","'use strict'\n\nexport default function parseList(list) {\n return list.children\n .map((item) => {\n const listItem = {}\n if (item.type === 'list') {\n return parseList(list)\n } else if (item.type === 'listItem') {\n listItem.checked = item.checked\n return item.children\n .map((child) => {\n if (child.type === 'paragraph') {\n listItem.text = child.children\n .map((c) => {\n if (c.type === 'link') {\n listItem.link = c.url\n return `[${c.children[0].value}](${c.url})`\n } else {\n return c.value\n }\n })\n .filter((x) => !!x)\n .join('')\n return listItem\n }\n })\n .filter((x) => !!x)\n }\n })\n .filter((x) => !!x)\n}\n","'use strict'\n\nimport { unified } from 'unified'\nimport remarkParse from 'remark-parse'\nimport remarkGfm from 'remark-gfm'\nimport slugify from '@sindresorhus/slugify'\nimport remarkStringify from 'remark-stringify'\nimport stripFinalNewline from 'strip-final-newline'\nimport createDebug from 'debug'\nconst debug = createDebug('body-parser')\n\nimport {\n parseDate,\n parseTime,\n parseDuration,\n parseList,\n parseImages,\n parseLinks\n} from './parsers/index.js'\n\nexport default async function parseMD(body) {\n debug('parseMD()')\n const tokens = await unified().use(remarkParse).use(remarkGfm).parse(body)\n if (!tokens) {\n return []\n }\n\n const structuredResponse = {}\n let currentHeading = null\n\n for (const token of tokens.children) {\n const text = await unified()\n .use(remarkGfm)\n .use(remarkStringify)\n .stringify(token)\n let cleanText = stripFinalNewline(text)\n\n // remove `\\\\_`\n if (cleanText.indexOf('\\\\_') > -1) {\n cleanText = cleanText.replace(/\\\\_/g, '_')\n }\n\n // issue forms uses h3 as a heading\n if (token.type === 'heading') {\n currentHeading = slugify(token.children[0].value)\n structuredResponse[currentHeading] = {\n title: token.children[0].value,\n heading: token.depth,\n content: []\n }\n } else if (token.type === 'paragraph' && currentHeading) {\n const obj = structuredResponse[currentHeading]\n\n const trimmedText = cleanText.trim()\n if (trimmedText === '*No response*' || trimmedText === '_No response_') {\n obj.text = null\n continue\n }\n\n const date = parseDate(cleanText)\n const images = parseImages(token.children)\n const links = parseLinks(token.children)\n const time = parseTime(cleanText)\n const duration = parseDuration(cleanText)\n\n if (date) {\n obj.date = date\n }\n\n if (time) {\n obj.time = time\n }\n\n if (duration) {\n obj.duration = duration\n }\n\n if (links && links.length > 0) {\n obj.links = links\n }\n\n if (images && images.length > 0) {\n obj.images = images\n }\n\n obj.content.push(cleanText)\n } else if (token.type === 'list') {\n const obj = structuredResponse[currentHeading]\n obj.text = cleanText\n obj.list = parseList(token).flat()\n } else if (token.type === 'html') {\n const obj = structuredResponse[currentHeading]\n obj.content.push(token.html)\n } else if (token.type === 'code') {\n const obj = structuredResponse[currentHeading]\n obj.lang = token.lang\n obj.text = cleanText\n } else {\n debug('unhandled token type')\n debug(token)\n }\n }\n\n for (const key in structuredResponse) {\n const token = structuredResponse[key]\n const content = token.content.filter(Boolean)\n if (content && content.length > 0) {\n if (content.length === 1) {\n token.text = content[0]\n }\n token.text = content.join('\\n\\n')\n }\n token.content = content\n }\n\n return structuredResponse\n}\n","'use strict'\n\nexport default function parseImage(props) {\n return props\n .filter((p) => p.type === 'image')\n .map((p) => {\n return {\n src: p.url,\n alt: p.alt\n }\n })\n}\n","'use strict'\n\nexport default function parseLinks(props) {\n return props\n .filter((p) => p.type === 'link')\n .map((p) => {\n return {\n src: p.url,\n alt: p.children[0].value\n }\n })\n}\n","'use strict'\n\nexport default function parseDuration(text) {\n let matched = false\n const duration = {\n hours: 0,\n minutes: 0\n }\n\n const hoursAndMinutes = new RegExp(/([0-9]+)h([0-9]+)m/)\n const hours = new RegExp(/([0-9]+)h/)\n\n if (text.match(hoursAndMinutes)) {\n matched = true\n const [, h, m] = text.match(hoursAndMinutes)\n duration.hours = parseInt(h)\n duration.minutes = parseInt(m)\n } else if (text.match(hours)) {\n matched = true\n const [, h] = text.match(hours)\n duration.hours = parseInt(h)\n duration.minutes = 0\n }\n\n if (matched) {\n return duration\n } else {\n return null\n }\n}\n"],"names":["commonDateFormats","commonTimeFormats","parseList","list","children","map","item","listItem","type","checked","child","text","c","link","url","value","filter","x","join","_settle","pact","state","s","_Pact","o","bind","v","then","observer","prototype","onFulfilled","onRejected","result","this","callback","e","_this","_isSettledPact","thenable","debug","createDebug","body","_iterator","_step","token","cleanText","obj","trimmedText","date","images","links","time","duration","key","content","Promise","resolve","unified","use","remarkParse","remarkGfm","parse","tokens","_temp2","structuredResponse","Boolean","length","currentHeading","_createForOfIteratorHelperLoose","_temp","test","update","stage","shouldContinue","updateValue","reject","_resumeAfterTest","_resumeAfterBody","_resumeAfterUpdate","_for","done","remarkStringify","stringify","_unified$use$use$stri","stripFinalNewline","indexOf","replace","slugify","title","heading","depth","trim","match","format","isMatch","fromZonedTime","Date","toJSON","split","p","src","alt","formatInTimeZone","parseTime","matched","hours","minutes","hoursAndMinutes","RegExp","_text$match","m","parseInt","_text$match2","parseDuration","push","flat","html","lang"],"mappings":"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"}
package/pkg/parse.js CHANGED
@@ -1,2 +1,2 @@
1
- import{unified as t}from"unified";import n from"remark-parse";import e from"remark-gfm";import r from"@sindresorhus/slugify";import i from"remark-stringify";import o from"strip-final-newline";import a from"debug";import{isMatch as u,parse as f}from"date-fns";import{zonedTimeToUtc as h,formatInTimeZone as l}from"date-fns-tz";function c(t,n){(null==n||n>t.length)&&(n=t.length);for(var e=0,r=new Array(n);e<n;e++)r[e]=t[e];return r}var d=["yyyy-MM-dd","dd/MM/yyyy","dd/MM/yy","dd-MM-yyyy","dd-MM-yy","dd.MM.yyyy","dd.MM.yy"],m=["HH:mm","HH.mm","hh:mm aaa","hh:mm a..aa","hh:mm aaaa"],s=function t(n){return n.children.map(function(e){var r={};return"list"===e.type?t(n):"listItem"===e.type?(r.checked=e.checked,e.children.map(function(t){if("paragraph"===t.type)return r.text=t.children.map(function(t){return"link"===t.type?(r.link=t.url,"["+t.children[0].value+"]("+t.url+")"):t.value}).filter(function(t){return!!t}).join(""),r}).filter(function(t){return!!t})):void 0}).filter(function(t){return!!t})};function v(t,n,e){if(!t.s){if(e instanceof y){if(!e.s)return void(e.o=v.bind(null,t,n));1&n&&(n=e.s),e=e.v}if(e&&e.then)return void e.then(v.bind(null,t,n),v.bind(null,t,2));t.s=n,t.v=e;var r=t.o;r&&r(t)}}var p=function(a){try{var p,M,x,k,w,O,I,j,A,H,S,T,C;return b("parseMD()"),Promise.resolve(t().use(n).use(e).parse(a)).then(function(n){function a(){for(S in U)(C=(T=U[S]).content.filter(Boolean))&&C.length>0&&(1===C.length&&(T.text=C[0]),T.text=C.join("\n\n")),T.content=C;return U}if(!n)return[];var U={},D=null;p=function(t,n){var e="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(e)return(e=e.call(t)).next.bind(e);if(Array.isArray(t)||(e=function(t,n){if(t){if("string"==typeof t)return c(t,n);var e=Object.prototype.toString.call(t).slice(8,-1);return"Object"===e&&t.constructor&&(e=t.constructor.name),"Map"===e||"Set"===e?Array.from(t):"Arguments"===e||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e)?c(t,n):void 0}}(t))){e&&(t=e);var r=0;return function(){return r>=t.length?{done:!0}:{done:!1,value:t[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(n.children);var E=function(t,n,e){for(var r;;){var i=t();if(g(i)&&(i=i.v),!i)return o;if(i.then){r=0;break}var o=e();if(o&&o.then){if(!g(o)){r=1;break}o=o.s}if(n){var a=n();if(a&&a.then&&!g(a)){r=2;break}}}var u=new y,f=v.bind(null,u,2);return(0===r?i.then(l):1===r?o.then(h):a.then(c)).then(void 0,f),u;function h(r){o=r;do{if(n&&(a=n())&&a.then&&!g(a))return void a.then(c).then(void 0,f);if(!(i=t())||g(i)&&!i.v)return void v(u,1,o);if(i.then)return void i.then(l).then(void 0,f);g(o=e())&&(o=o.v)}while(!o||!o.then);o.then(h).then(void 0,f)}function l(t){t?(o=e())&&o.then?o.then(h).then(void 0,f):h(o):v(u,1,o)}function c(){(i=t())?i.then?i.then(l).then(void 0,f):l(i):v(u,1,o)}}(function(){return!(M=p()).done},void 0,function(){return x=M.value,Promise.resolve(t().use(e).use(i).stringify(x)).then(function(t){var n,e;(k=o(t)).indexOf("\\_")>-1&&(k=k.replace(/\\_/g,"_")),"heading"===x.type?(D=r(x.children[0].value),U[D]={title:x.children[0].value,heading:x.depth,content:[]}):"paragraph"===x.type&&D?(w=U[D],n=k,e=d.map(function(t){return u(n,t)}),O=e.indexOf(!0)>-1?h(f(n,d[e.indexOf(!0)],new Date),"UTC").toJSON().split("T")[0]:null,I=function(t){var n=m.map(function(n){return u(t,n)});if(n.indexOf(!0)>-1){var e=h(f(t,m[n.indexOf(!0)],new Date),"UTC");return l(e,"UTC","HH:mm")}return null}(k),j=function(t){var n=!1,e={hours:0,minutes:0},r=new RegExp(/([0-9]+)h([0-9]+)m/),i=new RegExp(/([0-9]+)h/);if(t.match(r)){n=!0;var o=t.match(r),a=o[2];e.hours=parseInt(o[1]),e.minutes=parseInt(a)}else if(t.match(i)){n=!0;var u=t.match(i);e.hours=parseInt(u[1]),e.minutes=0}return n?e:null}(k),O&&(w.date=O),I&&(w.time=I),j&&(w.duration=j),w.content.push(k)):"list"===x.type?((A=U[D]).text=k,A.list=s(x).flat()):"html"===x.type?U[D].content.push(x.html):"code"===x.type?((H=U[D]).lang=x.lang,H.text=k):(b("unhandled token type"),b(x))})});return E&&E.then?E.then(a):a()})}catch(t){return Promise.reject(t)}},y=/*#__PURE__*/function(){function t(){}return t.prototype.then=function(n,e){var r=new t,i=this.s;if(i){var o=1&i?n:e;if(o){try{v(r,1,o(this.v))}catch(t){v(r,2,t)}return r}return this}return this.o=function(t){try{var i=t.v;1&t.s?v(r,1,n?n(i):i):e?v(r,1,e(i)):v(r,2,i)}catch(t){v(r,2,t)}},r},t}();function g(t){return t instanceof y&&1&t.s}var b=a("body-parser");export{p as default};
1
+ import{unified as n}from"unified";import t from"remark-parse";import e from"remark-gfm";import r from"@sindresorhus/slugify";import i from"remark-stringify";import o from"strip-final-newline";import a from"debug";import{isMatch as u,parse as f}from"date-fns";import{fromZonedTime as l,formatInTimeZone as h}from"date-fns-tz";function c(n,t){(null==t||t>n.length)&&(t=n.length);for(var e=0,r=Array(t);e<t;e++)r[e]=n[e];return r}var d=["yyyy-MM-dd","dd/MM/yyyy","dd/MM/yy","dd-MM-yyyy","dd-MM-yy","dd.MM.yyyy","dd.MM.yy"],s=["HH:mm","HH.mm","hh:mm aaa","hh:mm a..aa","hh:mm aaaa"],m=function n(t){return t.children.map(function(e){var r={};return"list"===e.type?n(t):"listItem"===e.type?(r.checked=e.checked,e.children.map(function(n){if("paragraph"===n.type)return r.text=n.children.map(function(n){return"link"===n.type?(r.link=n.url,"["+n.children[0].value+"]("+n.url+")"):n.value}).filter(function(n){return!!n}).join(""),r}).filter(function(n){return!!n})):void 0}).filter(function(n){return!!n})};function v(n,t,e){if(!n.s){if(e instanceof y){if(!e.s)return void(e.o=v.bind(null,n,t));1&t&&(t=e.s),e=e.v}if(e&&e.then)return void e.then(v.bind(null,n,t),v.bind(null,n,2));n.s=t,n.v=e;var r=n.o;r&&r(n)}}var p=function(a){try{var p,M,x,k,w,I,O,A,H,S,j,T,_,C,U,D;return b("parseMD()"),Promise.resolve(n().use(t).use(e).parse(a)).then(function(t){function a(){for(C in E)(D=(U=E[C]).content.filter(Boolean))&&D.length>0&&(1===D.length&&(U.text=D[0]),U.text=D.join("\n\n")),U.content=D;return E}if(!t)return[];var E={},N=null;p=function(n,t){var e="undefined"!=typeof Symbol&&n[Symbol.iterator]||n["@@iterator"];if(e)return(e=e.call(n)).next.bind(e);if(Array.isArray(n)||(e=function(n,t){if(n){if("string"==typeof n)return c(n,t);var e={}.toString.call(n).slice(8,-1);return"Object"===e&&n.constructor&&(e=n.constructor.name),"Map"===e||"Set"===e?Array.from(n):"Arguments"===e||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e)?c(n,t):void 0}}(n))){e&&(n=e);var r=0;return function(){return r>=n.length?{done:!0}:{done:!1,value:n[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(t.children);var P=function(n,t,e){for(var r;;){var i=n();if(g(i)&&(i=i.v),!i)return o;if(i.then){r=0;break}var o=e();if(o&&o.then){if(!g(o)){r=1;break}o=o.s}if(t){var a=t();if(a&&a.then&&!g(a)){r=2;break}}}var u=new y,f=v.bind(null,u,2);return(0===r?i.then(h):1===r?o.then(l):a.then(c)).then(void 0,f),u;function l(r){o=r;do{if(t&&(a=t())&&a.then&&!g(a))return void a.then(c).then(void 0,f);if(!(i=n())||g(i)&&!i.v)return void v(u,1,o);if(i.then)return void i.then(h).then(void 0,f);g(o=e())&&(o=o.v)}while(!o||!o.then);o.then(l).then(void 0,f)}function h(n){n?(o=e())&&o.then?o.then(l).then(void 0,f):l(o):v(u,1,o)}function c(){(i=n())?i.then?i.then(h).then(void 0,f):h(i):v(u,1,o)}}(function(){return!(M=p()).done},void 0,function(){return x=M.value,Promise.resolve(n().use(e).use(i).stringify(x)).then(function(n){if((k=o(n)).indexOf("\\_")>-1&&(k=k.replace(/\\_/g,"_")),"heading"===x.type)N=r(x.children[0].value),E[N]={title:x.children[0].value,heading:x.depth,content:[]};else if("paragraph"===x.type&&N){if(w=E[N],"*No response*"===(I=k.trim())||"_No response_"===I)return void(w.text=null);t=k,e=d.map(function(n){return u(t,n)}),O=e.indexOf(!0)>-1?l(f(t,d[e.indexOf(!0)],new Date),"UTC").toJSON().split("T")[0]:null,A=x.children.filter(function(n){return"image"===n.type}).map(function(n){return{src:n.url,alt:n.alt}}),H=x.children.filter(function(n){return"link"===n.type}).map(function(n){return{src:n.url,alt:n.children[0].value}}),S=function(n){var t=s.map(function(t){return u(n,t)});if(t.indexOf(!0)>-1){var e=l(f(n,s[t.indexOf(!0)],new Date),"UTC");return h(e,"UTC","HH:mm")}return null}(k),j=function(n){var t=!1,e={hours:0,minutes:0},r=new RegExp(/([0-9]+)h([0-9]+)m/),i=new RegExp(/([0-9]+)h/);if(n.match(r)){t=!0;var o=n.match(r),a=o[2];e.hours=parseInt(o[1]),e.minutes=parseInt(a)}else if(n.match(i)){t=!0;var u=n.match(i);e.hours=parseInt(u[1]),e.minutes=0}return t?e:null}(k),O&&(w.date=O),S&&(w.time=S),j&&(w.duration=j),H&&H.length>0&&(w.links=H),A&&A.length>0&&(w.images=A),w.content.push(k)}else"list"===x.type?((T=E[N]).text=k,T.list=m(x).flat()):"html"===x.type?E[N].content.push(x.html):"code"===x.type?((_=E[N]).lang=x.lang,_.text=k):(b("unhandled token type"),b(x));var t,e})});return P&&P.then?P.then(a):a()})}catch(n){return Promise.reject(n)}},y=/*#__PURE__*/function(){function n(){}return n.prototype.then=function(t,e){var r=new n,i=this.s;if(i){var o=1&i?t:e;if(o){try{v(r,1,o(this.v))}catch(n){v(r,2,n)}return r}return this}return this.o=function(n){try{var i=n.v;1&n.s?v(r,1,t?t(i):i):e?v(r,1,e(i)):v(r,2,i)}catch(n){v(r,2,n)}},r},n}();function g(n){return n instanceof y&&1&n.s}var b=a("body-parser");export{p as default};
2
2
  //# sourceMappingURL=parse.js.map
package/pkg/parse.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"parse.js","sources":["../src/parsers/date.js","../src/parsers/time.js","../src/parsers/index.js","../src/parsers/list.js","../src/parse.js","../src/parsers/duration.js"],"sourcesContent":["'use strict'\n\nimport { parse, isMatch } from 'date-fns'\nimport { zonedTimeToUtc } from 'date-fns-tz'\n\nconst loc = 'UTC'\nconst commonDateFormats = [\n 'yyyy-MM-dd',\n 'dd/MM/yyyy',\n 'dd/MM/yy',\n 'dd-MM-yyyy',\n 'dd-MM-yy',\n 'dd.MM.yyyy',\n 'dd.MM.yy'\n]\n\nexport default function parseDate(text) {\n const match = commonDateFormats.map((format) => {\n return isMatch(text, format)\n })\n if (match.indexOf(true) > -1) {\n const date = zonedTimeToUtc(\n parse(text, commonDateFormats[match.indexOf(true)], new Date()),\n loc\n ).toJSON()\n return date.split('T')[0]\n } else {\n return null\n }\n}\n","'use strict'\n\nimport { parse, isMatch } from 'date-fns'\nimport { zonedTimeToUtc, formatInTimeZone } from 'date-fns-tz'\n\nconst loc = 'UTC'\nconst commonTimeFormats = [\n 'HH:mm',\n 'HH.mm',\n 'hh:mm aaa',\n 'hh:mm a..aa',\n 'hh:mm aaaa'\n]\n\nexport default function parseTime(text) {\n const match = commonTimeFormats.map((format) => {\n return isMatch(text, format)\n })\n if (match.indexOf(true) > -1) {\n const time = zonedTimeToUtc(\n parse(text, commonTimeFormats[match.indexOf(true)], new Date()),\n loc\n )\n return formatInTimeZone(time, loc, 'HH:mm')\n } else {\n return null\n }\n}\n","'use strict'\n\nimport date from './date.js'\nimport time from './time.js'\nimport duration from './duration.js'\nimport list from './list.js'\n\nexport const parseDate = date\nexport const parseTime = time\nexport const parseDuration = duration\nexport const parseList = list\n","'use strict'\n\nexport default function parseList(list) {\n return list.children\n .map((item) => {\n const listItem = {}\n if (item.type === 'list') {\n return parseList(list)\n } else if (item.type === 'listItem') {\n listItem.checked = item.checked\n return item.children\n .map((child) => {\n if (child.type === 'paragraph') {\n listItem.text = child.children\n .map((c) => {\n if (c.type === 'link') {\n listItem.link = c.url\n return `[${c.children[0].value}](${c.url})`\n } else {\n return c.value\n }\n })\n .filter((x) => !!x)\n .join('')\n return listItem\n }\n })\n .filter((x) => !!x)\n }\n })\n .filter((x) => !!x)\n}\n","'use strict'\n\nimport { unified } from 'unified'\nimport remarkParse from 'remark-parse'\nimport remarkGfm from 'remark-gfm'\nimport slugify from '@sindresorhus/slugify'\nimport remarkStringify from 'remark-stringify'\nimport stripFinalNewline from 'strip-final-newline'\nimport createDebug from 'debug'\nconst debug = createDebug('body-parser')\n\nimport {\n parseDate,\n parseTime,\n parseDuration,\n parseList\n} from './parsers/index.js'\n\nexport default async function parseMD(body) {\n debug('parseMD()')\n const tokens = await unified().use(remarkParse).use(remarkGfm).parse(body)\n if (!tokens) {\n return []\n }\n\n const structuredResponse = {}\n let currentHeading = null\n for (const token of tokens.children) {\n const text = await unified()\n .use(remarkGfm)\n .use(remarkStringify)\n .stringify(token)\n let cleanText = stripFinalNewline(text)\n\n // remove `\\\\_`\n if (cleanText.indexOf('\\\\_') > -1) {\n cleanText = cleanText.replace(/\\\\_/g, '_')\n }\n\n // issue forms uses h3 as a heading\n if (token.type === 'heading') {\n currentHeading = slugify(token.children[0].value)\n structuredResponse[currentHeading] = {\n title: token.children[0].value,\n heading: token.depth,\n content: []\n }\n } else if (token.type === 'paragraph' && currentHeading) {\n const obj = structuredResponse[currentHeading]\n\n const date = parseDate(cleanText)\n const time = parseTime(cleanText)\n const duration = parseDuration(cleanText)\n\n if (date) {\n obj.date = date\n }\n\n if (time) {\n obj.time = time\n }\n\n if (duration) {\n obj.duration = duration\n }\n\n obj.content.push(cleanText)\n } else if (token.type === 'list') {\n const obj = structuredResponse[currentHeading]\n obj.text = cleanText\n obj.list = parseList(token).flat()\n } else if (token.type === 'html') {\n const obj = structuredResponse[currentHeading]\n obj.content.push(token.html)\n } else if (token.type === 'code') {\n const obj = structuredResponse[currentHeading]\n obj.lang = token.lang\n obj.text = cleanText\n } else {\n debug('unhandled token type')\n debug(token)\n }\n }\n\n for (const key in structuredResponse) {\n const token = structuredResponse[key]\n const content = token.content.filter(Boolean)\n if (content && content.length > 0) {\n if (content.length === 1) {\n token.text = content[0]\n }\n token.text = content.join('\\n\\n')\n }\n token.content = content\n }\n\n return structuredResponse\n}\n","'use strict'\n\nexport default function parseDuration(text) {\n let matched = false\n const duration = {\n hours: 0,\n minutes: 0\n }\n\n const hoursAndMinutes = new RegExp(/([0-9]+)h([0-9]+)m/)\n const hours = new RegExp(/([0-9]+)h/)\n\n if (text.match(hoursAndMinutes)) {\n matched = true\n const [, h, m] = text.match(hoursAndMinutes)\n duration.hours = parseInt(h)\n duration.minutes = parseInt(m)\n } else if (text.match(hours)) {\n matched = true\n const [, h] = text.match(hours)\n duration.hours = parseInt(h)\n duration.minutes = 0\n }\n\n if (matched) {\n return duration\n } else {\n return null\n }\n}\n"],"names":["commonDateFormats","commonTimeFormats","parseList","list","children","map","item","listItem","type","checked","child","text","c","link","url","value","filter","x","join","_settle","pact","state","s","_Pact","o","bind","v","then","observer","parseMD","body","_iterator","_step","token","cleanText","obj","date","time","duration","key","content","Promise","debug","resolve","unified","use","remarkParse","remarkGfm","parse","tokens","_temp2","structuredResponse","Boolean","length","currentHeading","_createForOfIteratorHelperLoose","_temp","test","update","stage","shouldContinue","_isSettledPact","result","updateValue","reject","_resumeAfterTest","_resumeAfterBody","_resumeAfterUpdate","_for","done","remarkStringify","stringify","_unified$use$use$stri","match","stripFinalNewline","indexOf","replace","slugify","title","heading","depth","format","isMatch","zonedTimeToUtc","Date","toJSON","split","formatInTimeZone","parseTime","matched","hours","minutes","hoursAndMinutes","RegExp","_text$match","m","parseInt","_text$match2","parseDuration","push","flat","html","lang","e","prototype","onFulfilled","onRejected","this","callback","_this","thenable","createDebug"],"mappings":"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"}
1
+ {"version":3,"file":"parse.js","sources":["../src/parsers/date.js","../src/parsers/time.js","../src/parsers/index.js","../src/parsers/list.js","../src/parse.js","../src/parsers/images.js","../src/parsers/links.js","../src/parsers/duration.js"],"sourcesContent":["'use strict'\n\nimport { parse, isMatch } from 'date-fns'\nimport { fromZonedTime } from 'date-fns-tz'\n\nconst loc = 'UTC'\nconst commonDateFormats = [\n 'yyyy-MM-dd',\n 'dd/MM/yyyy',\n 'dd/MM/yy',\n 'dd-MM-yyyy',\n 'dd-MM-yy',\n 'dd.MM.yyyy',\n 'dd.MM.yy'\n]\n\nexport default function parseDate(text) {\n const match = commonDateFormats.map((format) => {\n return isMatch(text, format)\n })\n if (match.indexOf(true) > -1) {\n const date = fromZonedTime(\n parse(text, commonDateFormats[match.indexOf(true)], new Date()),\n loc\n ).toJSON()\n return date.split('T')[0]\n } else {\n return null\n }\n}\n","'use strict'\n\nimport { parse, isMatch } from 'date-fns'\nimport { fromZonedTime, formatInTimeZone } from 'date-fns-tz'\n\nconst loc = 'UTC'\nconst commonTimeFormats = [\n 'HH:mm',\n 'HH.mm',\n 'hh:mm aaa',\n 'hh:mm a..aa',\n 'hh:mm aaaa'\n]\n\nexport default function parseTime(text) {\n const match = commonTimeFormats.map((format) => {\n return isMatch(text, format)\n })\n if (match.indexOf(true) > -1) {\n const time = fromZonedTime(\n parse(text, commonTimeFormats[match.indexOf(true)], new Date()),\n loc\n )\n return formatInTimeZone(time, loc, 'HH:mm')\n } else {\n return null\n }\n}\n","'use strict'\n\nimport date from './date.js'\nimport time from './time.js'\nimport duration from './duration.js'\nimport list from './list.js'\nimport images from './images.js'\nimport links from './links.js'\n\nexport const parseDate = date\nexport const parseTime = time\nexport const parseDuration = duration\nexport const parseList = list\nexport const parseImages = images\nexport const parseLinks = links\n","'use strict'\n\nexport default function parseList(list) {\n return list.children\n .map((item) => {\n const listItem = {}\n if (item.type === 'list') {\n return parseList(list)\n } else if (item.type === 'listItem') {\n listItem.checked = item.checked\n return item.children\n .map((child) => {\n if (child.type === 'paragraph') {\n listItem.text = child.children\n .map((c) => {\n if (c.type === 'link') {\n listItem.link = c.url\n return `[${c.children[0].value}](${c.url})`\n } else {\n return c.value\n }\n })\n .filter((x) => !!x)\n .join('')\n return listItem\n }\n })\n .filter((x) => !!x)\n }\n })\n .filter((x) => !!x)\n}\n","'use strict'\n\nimport { unified } from 'unified'\nimport remarkParse from 'remark-parse'\nimport remarkGfm from 'remark-gfm'\nimport slugify from '@sindresorhus/slugify'\nimport remarkStringify from 'remark-stringify'\nimport stripFinalNewline from 'strip-final-newline'\nimport createDebug from 'debug'\nconst debug = createDebug('body-parser')\n\nimport {\n parseDate,\n parseTime,\n parseDuration,\n parseList,\n parseImages,\n parseLinks\n} from './parsers/index.js'\n\nexport default async function parseMD(body) {\n debug('parseMD()')\n const tokens = await unified().use(remarkParse).use(remarkGfm).parse(body)\n if (!tokens) {\n return []\n }\n\n const structuredResponse = {}\n let currentHeading = null\n\n for (const token of tokens.children) {\n const text = await unified()\n .use(remarkGfm)\n .use(remarkStringify)\n .stringify(token)\n let cleanText = stripFinalNewline(text)\n\n // remove `\\\\_`\n if (cleanText.indexOf('\\\\_') > -1) {\n cleanText = cleanText.replace(/\\\\_/g, '_')\n }\n\n // issue forms uses h3 as a heading\n if (token.type === 'heading') {\n currentHeading = slugify(token.children[0].value)\n structuredResponse[currentHeading] = {\n title: token.children[0].value,\n heading: token.depth,\n content: []\n }\n } else if (token.type === 'paragraph' && currentHeading) {\n const obj = structuredResponse[currentHeading]\n\n const trimmedText = cleanText.trim()\n if (trimmedText === '*No response*' || trimmedText === '_No response_') {\n obj.text = null\n continue\n }\n\n const date = parseDate(cleanText)\n const images = parseImages(token.children)\n const links = parseLinks(token.children)\n const time = parseTime(cleanText)\n const duration = parseDuration(cleanText)\n\n if (date) {\n obj.date = date\n }\n\n if (time) {\n obj.time = time\n }\n\n if (duration) {\n obj.duration = duration\n }\n\n if (links && links.length > 0) {\n obj.links = links\n }\n\n if (images && images.length > 0) {\n obj.images = images\n }\n\n obj.content.push(cleanText)\n } else if (token.type === 'list') {\n const obj = structuredResponse[currentHeading]\n obj.text = cleanText\n obj.list = parseList(token).flat()\n } else if (token.type === 'html') {\n const obj = structuredResponse[currentHeading]\n obj.content.push(token.html)\n } else if (token.type === 'code') {\n const obj = structuredResponse[currentHeading]\n obj.lang = token.lang\n obj.text = cleanText\n } else {\n debug('unhandled token type')\n debug(token)\n }\n }\n\n for (const key in structuredResponse) {\n const token = structuredResponse[key]\n const content = token.content.filter(Boolean)\n if (content && content.length > 0) {\n if (content.length === 1) {\n token.text = content[0]\n }\n token.text = content.join('\\n\\n')\n }\n token.content = content\n }\n\n return structuredResponse\n}\n","'use strict'\n\nexport default function parseImage(props) {\n return props\n .filter((p) => p.type === 'image')\n .map((p) => {\n return {\n src: p.url,\n alt: p.alt\n }\n })\n}\n","'use strict'\n\nexport default function parseLinks(props) {\n return props\n .filter((p) => p.type === 'link')\n .map((p) => {\n return {\n src: p.url,\n alt: p.children[0].value\n }\n })\n}\n","'use strict'\n\nexport default function parseDuration(text) {\n let matched = false\n const duration = {\n hours: 0,\n minutes: 0\n }\n\n const hoursAndMinutes = new RegExp(/([0-9]+)h([0-9]+)m/)\n const hours = new RegExp(/([0-9]+)h/)\n\n if (text.match(hoursAndMinutes)) {\n matched = true\n const [, h, m] = text.match(hoursAndMinutes)\n duration.hours = parseInt(h)\n duration.minutes = parseInt(m)\n } else if (text.match(hours)) {\n matched = true\n const [, h] = text.match(hours)\n duration.hours = parseInt(h)\n duration.minutes = 0\n }\n\n if (matched) {\n return duration\n } else {\n return null\n }\n}\n"],"names":["commonDateFormats","commonTimeFormats","parseList","list","children","map","item","listItem","type","checked","child","text","c","link","url","value","filter","x","join","_settle","pact","state","s","_Pact","o","bind","v","then","observer","parseMD","body","_iterator","_step","token","cleanText","obj","trimmedText","date","images","links","time","duration","key","content","Promise","debug","resolve","unified","use","remarkParse","remarkGfm","parse","tokens","_temp2","structuredResponse","Boolean","length","currentHeading","_createForOfIteratorHelperLoose","_temp","test","update","stage","shouldContinue","_isSettledPact","result","updateValue","reject","_resumeAfterTest","_resumeAfterBody","_resumeAfterUpdate","_for","done","remarkStringify","stringify","_unified$use$use$stri","stripFinalNewline","indexOf","replace","slugify","title","heading","depth","trim","match","format","isMatch","fromZonedTime","Date","toJSON","split","p","src","alt","formatInTimeZone","parseTime","matched","hours","minutes","hoursAndMinutes","RegExp","_text$match","m","parseInt","_text$match2","parseDuration","push","flat","html","lang","e","prototype","onFulfilled","onRejected","this","callback","_this","thenable","createDebug"],"mappings":"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"}
package/pkg/parse.umd.js CHANGED
@@ -1,2 +1,2 @@
1
- !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n(require("unified"),require("remark-parse"),require("remark-gfm"),require("@sindresorhus/slugify"),require("remark-stringify"),require("strip-final-newline"),require("debug"),require("date-fns"),require("date-fns-tz")):"function"==typeof define&&define.amd?define(["unified","remark-parse","remark-gfm","@sindresorhus/slugify","remark-stringify","strip-final-newline","debug","date-fns","date-fns-tz"],n):(e||self).issueFormsBodyParser=n(e.unified,e.remarkParse,e.remarkGfm,e.slugify,e.remarkStringify,e.stripFinalNewline,e.debug,e.dateFns,e.dateFnsTz)}(this,function(e,n,t,r,i,a,u,o,f){function d(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var l=/*#__PURE__*/d(n),s=/*#__PURE__*/d(t),h=/*#__PURE__*/d(r),c=/*#__PURE__*/d(i),y=/*#__PURE__*/d(a),m=/*#__PURE__*/d(u);function v(e,n){(null==n||n>e.length)&&(n=e.length);for(var t=0,r=new Array(n);t<n;t++)r[t]=e[t];return r}var p=["yyyy-MM-dd","dd/MM/yyyy","dd/MM/yy","dd-MM-yyyy","dd-MM-yy","dd.MM.yyyy","dd.MM.yy"],g=["HH:mm","HH.mm","hh:mm aaa","hh:mm a..aa","hh:mm aaaa"],b=function e(n){return n.children.map(function(t){var r={};return"list"===t.type?e(n):"listItem"===t.type?(r.checked=t.checked,t.children.map(function(e){if("paragraph"===e.type)return r.text=e.children.map(function(e){return"link"===e.type?(r.link=e.url,"["+e.children[0].value+"]("+e.url+")"):e.value}).filter(function(e){return!!e}).join(""),r}).filter(function(e){return!!e})):void 0}).filter(function(e){return!!e})};function M(e,n,t){if(!e.s){if(t instanceof k){if(!t.s)return void(t.o=M.bind(null,e,n));1&n&&(n=t.s),t=t.v}if(t&&t.then)return void t.then(M.bind(null,e,n),M.bind(null,e,2));e.s=n,e.v=t;var r=e.o;r&&r(e)}}var k=/*#__PURE__*/function(){function e(){}return e.prototype.then=function(n,t){var r=new e,i=this.s;if(i){var a=1&i?n:t;if(a){try{M(r,1,a(this.v))}catch(e){M(r,2,e)}return r}return this}return this.o=function(e){try{var i=e.v;1&e.s?M(r,1,n?n(i):i):t?M(r,1,t(i)):M(r,2,i)}catch(e){M(r,2,e)}},r},e}();function x(e){return e instanceof k&&1&e.s}var w=m.default("body-parser");return function(n){try{var t,r,i,a,u,d,m,T,q,j,I,O,S;return w("parseMD()"),Promise.resolve(e.unified().use(l.default).use(s.default).parse(n)).then(function(n){function l(){for(I in A)(S=(O=A[I]).content.filter(Boolean))&&S.length>0&&(1===S.length&&(O.text=S[0]),O.text=S.join("\n\n")),O.content=S;return A}if(!n)return[];var A={},H=null;t=function(e,n){var t="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(t)return(t=t.call(e)).next.bind(t);if(Array.isArray(e)||(t=function(e,n){if(e){if("string"==typeof e)return v(e,n);var t=Object.prototype.toString.call(e).slice(8,-1);return"Object"===t&&e.constructor&&(t=e.constructor.name),"Map"===t||"Set"===t?Array.from(e):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?v(e,n):void 0}}(e))){t&&(e=t);var r=0;return function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(n.children);var U=function(e,n,t){for(var r;;){var i=e();if(x(i)&&(i=i.v),!i)return a;if(i.then){r=0;break}var a=t();if(a&&a.then){if(!x(a)){r=1;break}a=a.s}if(n){var u=n();if(u&&u.then&&!x(u)){r=2;break}}}var o=new k,f=M.bind(null,o,2);return(0===r?i.then(l):1===r?a.then(d):u.then(s)).then(void 0,f),o;function d(r){a=r;do{if(n&&(u=n())&&u.then&&!x(u))return void u.then(s).then(void 0,f);if(!(i=e())||x(i)&&!i.v)return void M(o,1,a);if(i.then)return void i.then(l).then(void 0,f);x(a=t())&&(a=a.v)}while(!a||!a.then);a.then(d).then(void 0,f)}function l(e){e?(a=t())&&a.then?a.then(d).then(void 0,f):d(a):M(o,1,a)}function s(){(i=e())?i.then?i.then(l).then(void 0,f):l(i):M(o,1,a)}}(function(){return!(r=t()).done},void 0,function(){return i=r.value,Promise.resolve(e.unified().use(s.default).use(c.default).stringify(i)).then(function(e){var n,t;(a=y.default(e)).indexOf("\\_")>-1&&(a=a.replace(/\\_/g,"_")),"heading"===i.type?(H=h.default(i.children[0].value),A[H]={title:i.children[0].value,heading:i.depth,content:[]}):"paragraph"===i.type&&H?(u=A[H],n=a,t=p.map(function(e){return o.isMatch(n,e)}),d=t.indexOf(!0)>-1?f.zonedTimeToUtc(o.parse(n,p[t.indexOf(!0)],new Date),"UTC").toJSON().split("T")[0]:null,m=function(e){var n=g.map(function(n){return o.isMatch(e,n)});if(n.indexOf(!0)>-1){var t=f.zonedTimeToUtc(o.parse(e,g[n.indexOf(!0)],new Date),"UTC");return f.formatInTimeZone(t,"UTC","HH:mm")}return null}(a),T=function(e){var n=!1,t={hours:0,minutes:0},r=new RegExp(/([0-9]+)h([0-9]+)m/),i=new RegExp(/([0-9]+)h/);if(e.match(r)){n=!0;var a=e.match(r),u=a[2];t.hours=parseInt(a[1]),t.minutes=parseInt(u)}else if(e.match(i)){n=!0;var o=e.match(i);t.hours=parseInt(o[1]),t.minutes=0}return n?t:null}(a),d&&(u.date=d),m&&(u.time=m),T&&(u.duration=T),u.content.push(a)):"list"===i.type?((q=A[H]).text=a,q.list=b(i).flat()):"html"===i.type?A[H].content.push(i.html):"code"===i.type?((j=A[H]).lang=i.lang,j.text=a):(w("unhandled token type"),w(i))})});return U&&U.then?U.then(l):l()})}catch(e){return Promise.reject(e)}}});
1
+ !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n(require("unified"),require("remark-parse"),require("remark-gfm"),require("@sindresorhus/slugify"),require("remark-stringify"),require("strip-final-newline"),require("debug"),require("date-fns"),require("date-fns-tz")):"function"==typeof define&&define.amd?define(["unified","remark-parse","remark-gfm","@sindresorhus/slugify","remark-stringify","strip-final-newline","debug","date-fns","date-fns-tz"],n):(e||self).issueFormsBodyParser=n(e.unified,e.remarkParse,e.remarkGfm,e.slugify,e.remarkStringify,e.stripFinalNewline,e.debug,e.dateFns,e.dateFnsTz)}(this,function(e,n,t,r,i,u,a,o,f){function l(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var d=/*#__PURE__*/l(n),s=/*#__PURE__*/l(t),h=/*#__PURE__*/l(r),c=/*#__PURE__*/l(i),m=/*#__PURE__*/l(u),y=/*#__PURE__*/l(a);function p(e,n){(null==n||n>e.length)&&(n=e.length);for(var t=0,r=Array(n);t<n;t++)r[t]=e[t];return r}var v=["yyyy-MM-dd","dd/MM/yyyy","dd/MM/yy","dd-MM-yyyy","dd-MM-yy","dd.MM.yyyy","dd.MM.yy"],g=["HH:mm","HH.mm","hh:mm aaa","hh:mm a..aa","hh:mm aaaa"],b=function e(n){return n.children.map(function(t){var r={};return"list"===t.type?e(n):"listItem"===t.type?(r.checked=t.checked,t.children.map(function(e){if("paragraph"===e.type)return r.text=e.children.map(function(e){return"link"===e.type?(r.link=e.url,"["+e.children[0].value+"]("+e.url+")"):e.value}).filter(function(e){return!!e}).join(""),r}).filter(function(e){return!!e})):void 0}).filter(function(e){return!!e})};function k(e,n,t){if(!e.s){if(t instanceof M){if(!t.s)return void(t.o=k.bind(null,e,n));1&n&&(n=t.s),t=t.v}if(t&&t.then)return void t.then(k.bind(null,e,n),k.bind(null,e,2));e.s=n,e.v=t;var r=e.o;r&&r(e)}}var M=/*#__PURE__*/function(){function e(){}return e.prototype.then=function(n,t){var r=new e,i=this.s;if(i){var u=1&i?n:t;if(u){try{k(r,1,u(this.v))}catch(e){k(r,2,e)}return r}return this}return this.o=function(e){try{var i=e.v;1&e.s?k(r,1,n?n(i):i):t?k(r,1,t(i)):k(r,2,i)}catch(e){k(r,2,e)}},r},e}();function x(e){return e instanceof M&&1&e.s}var w=y.default("body-parser");return function(n){try{var t,r,i,u,a,l,y,T,q,I,j,O,S,A,H,P;return w("parseMD()"),Promise.resolve(e.unified().use(d.default).use(s.default).parse(n)).then(function(n){function d(){for(A in _)(P=(H=_[A]).content.filter(Boolean))&&P.length>0&&(1===P.length&&(H.text=P[0]),H.text=P.join("\n\n")),H.content=P;return _}if(!n)return[];var _={},C=null;t=function(e,n){var t="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(t)return(t=t.call(e)).next.bind(t);if(Array.isArray(e)||(t=function(e,n){if(e){if("string"==typeof e)return p(e,n);var t={}.toString.call(e).slice(8,-1);return"Object"===t&&e.constructor&&(t=e.constructor.name),"Map"===t||"Set"===t?Array.from(e):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?p(e,n):void 0}}(e))){t&&(e=t);var r=0;return function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(n.children);var F=function(e,n,t){for(var r;;){var i=e();if(x(i)&&(i=i.v),!i)return u;if(i.then){r=0;break}var u=t();if(u&&u.then){if(!x(u)){r=1;break}u=u.s}if(n){var a=n();if(a&&a.then&&!x(a)){r=2;break}}}var o=new M,f=k.bind(null,o,2);return(0===r?i.then(d):1===r?u.then(l):a.then(s)).then(void 0,f),o;function l(r){u=r;do{if(n&&(a=n())&&a.then&&!x(a))return void a.then(s).then(void 0,f);if(!(i=e())||x(i)&&!i.v)return void k(o,1,u);if(i.then)return void i.then(d).then(void 0,f);x(u=t())&&(u=u.v)}while(!u||!u.then);u.then(l).then(void 0,f)}function d(e){e?(u=t())&&u.then?u.then(l).then(void 0,f):l(u):k(o,1,u)}function s(){(i=e())?i.then?i.then(d).then(void 0,f):d(i):k(o,1,u)}}(function(){return!(r=t()).done},void 0,function(){return i=r.value,Promise.resolve(e.unified().use(s.default).use(c.default).stringify(i)).then(function(e){if((u=m.default(e)).indexOf("\\_")>-1&&(u=u.replace(/\\_/g,"_")),"heading"===i.type)C=h.default(i.children[0].value),_[C]={title:i.children[0].value,heading:i.depth,content:[]};else if("paragraph"===i.type&&C){if(a=_[C],"*No response*"===(l=u.trim())||"_No response_"===l)return void(a.text=null);n=u,t=v.map(function(e){return o.isMatch(n,e)}),y=t.indexOf(!0)>-1?f.fromZonedTime(o.parse(n,v[t.indexOf(!0)],new Date),"UTC").toJSON().split("T")[0]:null,T=i.children.filter(function(e){return"image"===e.type}).map(function(e){return{src:e.url,alt:e.alt}}),q=i.children.filter(function(e){return"link"===e.type}).map(function(e){return{src:e.url,alt:e.children[0].value}}),I=function(e){var n=g.map(function(n){return o.isMatch(e,n)});if(n.indexOf(!0)>-1){var t=f.fromZonedTime(o.parse(e,g[n.indexOf(!0)],new Date),"UTC");return f.formatInTimeZone(t,"UTC","HH:mm")}return null}(u),j=function(e){var n=!1,t={hours:0,minutes:0},r=new RegExp(/([0-9]+)h([0-9]+)m/),i=new RegExp(/([0-9]+)h/);if(e.match(r)){n=!0;var u=e.match(r),a=u[2];t.hours=parseInt(u[1]),t.minutes=parseInt(a)}else if(e.match(i)){n=!0;var o=e.match(i);t.hours=parseInt(o[1]),t.minutes=0}return n?t:null}(u),y&&(a.date=y),I&&(a.time=I),j&&(a.duration=j),q&&q.length>0&&(a.links=q),T&&T.length>0&&(a.images=T),a.content.push(u)}else"list"===i.type?((O=_[C]).text=u,O.list=b(i).flat()):"html"===i.type?_[C].content.push(i.html):"code"===i.type?((S=_[C]).lang=i.lang,S.text=u):(w("unhandled token type"),w(i));var n,t})});return F&&F.then?F.then(d):d()})}catch(e){return Promise.reject(e)}}});
2
2
  //# sourceMappingURL=parse.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"parse.umd.js","sources":["../src/parsers/date.js","../src/parsers/time.js","../src/parsers/index.js","../src/parsers/list.js","../src/parse.js","../src/parsers/duration.js"],"sourcesContent":["'use strict'\n\nimport { parse, isMatch } from 'date-fns'\nimport { zonedTimeToUtc } from 'date-fns-tz'\n\nconst loc = 'UTC'\nconst commonDateFormats = [\n 'yyyy-MM-dd',\n 'dd/MM/yyyy',\n 'dd/MM/yy',\n 'dd-MM-yyyy',\n 'dd-MM-yy',\n 'dd.MM.yyyy',\n 'dd.MM.yy'\n]\n\nexport default function parseDate(text) {\n const match = commonDateFormats.map((format) => {\n return isMatch(text, format)\n })\n if (match.indexOf(true) > -1) {\n const date = zonedTimeToUtc(\n parse(text, commonDateFormats[match.indexOf(true)], new Date()),\n loc\n ).toJSON()\n return date.split('T')[0]\n } else {\n return null\n }\n}\n","'use strict'\n\nimport { parse, isMatch } from 'date-fns'\nimport { zonedTimeToUtc, formatInTimeZone } from 'date-fns-tz'\n\nconst loc = 'UTC'\nconst commonTimeFormats = [\n 'HH:mm',\n 'HH.mm',\n 'hh:mm aaa',\n 'hh:mm a..aa',\n 'hh:mm aaaa'\n]\n\nexport default function parseTime(text) {\n const match = commonTimeFormats.map((format) => {\n return isMatch(text, format)\n })\n if (match.indexOf(true) > -1) {\n const time = zonedTimeToUtc(\n parse(text, commonTimeFormats[match.indexOf(true)], new Date()),\n loc\n )\n return formatInTimeZone(time, loc, 'HH:mm')\n } else {\n return null\n }\n}\n","'use strict'\n\nimport date from './date.js'\nimport time from './time.js'\nimport duration from './duration.js'\nimport list from './list.js'\n\nexport const parseDate = date\nexport const parseTime = time\nexport const parseDuration = duration\nexport const parseList = list\n","'use strict'\n\nexport default function parseList(list) {\n return list.children\n .map((item) => {\n const listItem = {}\n if (item.type === 'list') {\n return parseList(list)\n } else if (item.type === 'listItem') {\n listItem.checked = item.checked\n return item.children\n .map((child) => {\n if (child.type === 'paragraph') {\n listItem.text = child.children\n .map((c) => {\n if (c.type === 'link') {\n listItem.link = c.url\n return `[${c.children[0].value}](${c.url})`\n } else {\n return c.value\n }\n })\n .filter((x) => !!x)\n .join('')\n return listItem\n }\n })\n .filter((x) => !!x)\n }\n })\n .filter((x) => !!x)\n}\n","'use strict'\n\nimport { unified } from 'unified'\nimport remarkParse from 'remark-parse'\nimport remarkGfm from 'remark-gfm'\nimport slugify from '@sindresorhus/slugify'\nimport remarkStringify from 'remark-stringify'\nimport stripFinalNewline from 'strip-final-newline'\nimport createDebug from 'debug'\nconst debug = createDebug('body-parser')\n\nimport {\n parseDate,\n parseTime,\n parseDuration,\n parseList\n} from './parsers/index.js'\n\nexport default async function parseMD(body) {\n debug('parseMD()')\n const tokens = await unified().use(remarkParse).use(remarkGfm).parse(body)\n if (!tokens) {\n return []\n }\n\n const structuredResponse = {}\n let currentHeading = null\n for (const token of tokens.children) {\n const text = await unified()\n .use(remarkGfm)\n .use(remarkStringify)\n .stringify(token)\n let cleanText = stripFinalNewline(text)\n\n // remove `\\\\_`\n if (cleanText.indexOf('\\\\_') > -1) {\n cleanText = cleanText.replace(/\\\\_/g, '_')\n }\n\n // issue forms uses h3 as a heading\n if (token.type === 'heading') {\n currentHeading = slugify(token.children[0].value)\n structuredResponse[currentHeading] = {\n title: token.children[0].value,\n heading: token.depth,\n content: []\n }\n } else if (token.type === 'paragraph' && currentHeading) {\n const obj = structuredResponse[currentHeading]\n\n const date = parseDate(cleanText)\n const time = parseTime(cleanText)\n const duration = parseDuration(cleanText)\n\n if (date) {\n obj.date = date\n }\n\n if (time) {\n obj.time = time\n }\n\n if (duration) {\n obj.duration = duration\n }\n\n obj.content.push(cleanText)\n } else if (token.type === 'list') {\n const obj = structuredResponse[currentHeading]\n obj.text = cleanText\n obj.list = parseList(token).flat()\n } else if (token.type === 'html') {\n const obj = structuredResponse[currentHeading]\n obj.content.push(token.html)\n } else if (token.type === 'code') {\n const obj = structuredResponse[currentHeading]\n obj.lang = token.lang\n obj.text = cleanText\n } else {\n debug('unhandled token type')\n debug(token)\n }\n }\n\n for (const key in structuredResponse) {\n const token = structuredResponse[key]\n const content = token.content.filter(Boolean)\n if (content && content.length > 0) {\n if (content.length === 1) {\n token.text = content[0]\n }\n token.text = content.join('\\n\\n')\n }\n token.content = content\n }\n\n return structuredResponse\n}\n","'use strict'\n\nexport default function parseDuration(text) {\n let matched = false\n const duration = {\n hours: 0,\n minutes: 0\n }\n\n const hoursAndMinutes = new RegExp(/([0-9]+)h([0-9]+)m/)\n const hours = new RegExp(/([0-9]+)h/)\n\n if (text.match(hoursAndMinutes)) {\n matched = true\n const [, h, m] = text.match(hoursAndMinutes)\n duration.hours = parseInt(h)\n duration.minutes = parseInt(m)\n } else if (text.match(hours)) {\n matched = true\n const [, h] = text.match(hours)\n duration.hours = parseInt(h)\n duration.minutes = 0\n }\n\n if (matched) {\n return duration\n } else {\n return null\n }\n}\n"],"names":["commonDateFormats","commonTimeFormats","parseList","list","children","map","item","listItem","type","checked","child","text","c","link","url","value","filter","x","join","_settle","pact","state","s","_Pact","o","bind","v","then","observer","prototype","onFulfilled","onRejected","result","this","callback","e","_this","_isSettledPact","thenable","debug","createDebug","body","_iterator","_step","token","cleanText","obj","date","time","duration","key","content","Promise","resolve","unified","use","remarkParse","remarkGfm","parse","tokens","_temp2","structuredResponse","Boolean","length","currentHeading","_createForOfIteratorHelperLoose","_temp","test","update","stage","shouldContinue","updateValue","reject","_resumeAfterTest","_resumeAfterBody","_resumeAfterUpdate","_for","done","remarkStringify","stringify","_unified$use$use$stri","match","stripFinalNewline","indexOf","replace","slugify","title","heading","depth","format","isMatch","zonedTimeToUtc","Date","toJSON","split","formatInTimeZone","parseTime","matched","hours","minutes","hoursAndMinutes","RegExp","_text$match","m","parseInt","_text$match2","parseDuration","push","flat","html","lang"],"mappings":"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"}
1
+ {"version":3,"file":"parse.umd.js","sources":["../src/parsers/date.js","../src/parsers/time.js","../src/parsers/index.js","../src/parsers/list.js","../src/parse.js","../src/parsers/images.js","../src/parsers/links.js","../src/parsers/duration.js"],"sourcesContent":["'use strict'\n\nimport { parse, isMatch } from 'date-fns'\nimport { fromZonedTime } from 'date-fns-tz'\n\nconst loc = 'UTC'\nconst commonDateFormats = [\n 'yyyy-MM-dd',\n 'dd/MM/yyyy',\n 'dd/MM/yy',\n 'dd-MM-yyyy',\n 'dd-MM-yy',\n 'dd.MM.yyyy',\n 'dd.MM.yy'\n]\n\nexport default function parseDate(text) {\n const match = commonDateFormats.map((format) => {\n return isMatch(text, format)\n })\n if (match.indexOf(true) > -1) {\n const date = fromZonedTime(\n parse(text, commonDateFormats[match.indexOf(true)], new Date()),\n loc\n ).toJSON()\n return date.split('T')[0]\n } else {\n return null\n }\n}\n","'use strict'\n\nimport { parse, isMatch } from 'date-fns'\nimport { fromZonedTime, formatInTimeZone } from 'date-fns-tz'\n\nconst loc = 'UTC'\nconst commonTimeFormats = [\n 'HH:mm',\n 'HH.mm',\n 'hh:mm aaa',\n 'hh:mm a..aa',\n 'hh:mm aaaa'\n]\n\nexport default function parseTime(text) {\n const match = commonTimeFormats.map((format) => {\n return isMatch(text, format)\n })\n if (match.indexOf(true) > -1) {\n const time = fromZonedTime(\n parse(text, commonTimeFormats[match.indexOf(true)], new Date()),\n loc\n )\n return formatInTimeZone(time, loc, 'HH:mm')\n } else {\n return null\n }\n}\n","'use strict'\n\nimport date from './date.js'\nimport time from './time.js'\nimport duration from './duration.js'\nimport list from './list.js'\nimport images from './images.js'\nimport links from './links.js'\n\nexport const parseDate = date\nexport const parseTime = time\nexport const parseDuration = duration\nexport const parseList = list\nexport const parseImages = images\nexport const parseLinks = links\n","'use strict'\n\nexport default function parseList(list) {\n return list.children\n .map((item) => {\n const listItem = {}\n if (item.type === 'list') {\n return parseList(list)\n } else if (item.type === 'listItem') {\n listItem.checked = item.checked\n return item.children\n .map((child) => {\n if (child.type === 'paragraph') {\n listItem.text = child.children\n .map((c) => {\n if (c.type === 'link') {\n listItem.link = c.url\n return `[${c.children[0].value}](${c.url})`\n } else {\n return c.value\n }\n })\n .filter((x) => !!x)\n .join('')\n return listItem\n }\n })\n .filter((x) => !!x)\n }\n })\n .filter((x) => !!x)\n}\n","'use strict'\n\nimport { unified } from 'unified'\nimport remarkParse from 'remark-parse'\nimport remarkGfm from 'remark-gfm'\nimport slugify from '@sindresorhus/slugify'\nimport remarkStringify from 'remark-stringify'\nimport stripFinalNewline from 'strip-final-newline'\nimport createDebug from 'debug'\nconst debug = createDebug('body-parser')\n\nimport {\n parseDate,\n parseTime,\n parseDuration,\n parseList,\n parseImages,\n parseLinks\n} from './parsers/index.js'\n\nexport default async function parseMD(body) {\n debug('parseMD()')\n const tokens = await unified().use(remarkParse).use(remarkGfm).parse(body)\n if (!tokens) {\n return []\n }\n\n const structuredResponse = {}\n let currentHeading = null\n\n for (const token of tokens.children) {\n const text = await unified()\n .use(remarkGfm)\n .use(remarkStringify)\n .stringify(token)\n let cleanText = stripFinalNewline(text)\n\n // remove `\\\\_`\n if (cleanText.indexOf('\\\\_') > -1) {\n cleanText = cleanText.replace(/\\\\_/g, '_')\n }\n\n // issue forms uses h3 as a heading\n if (token.type === 'heading') {\n currentHeading = slugify(token.children[0].value)\n structuredResponse[currentHeading] = {\n title: token.children[0].value,\n heading: token.depth,\n content: []\n }\n } else if (token.type === 'paragraph' && currentHeading) {\n const obj = structuredResponse[currentHeading]\n\n const trimmedText = cleanText.trim()\n if (trimmedText === '*No response*' || trimmedText === '_No response_') {\n obj.text = null\n continue\n }\n\n const date = parseDate(cleanText)\n const images = parseImages(token.children)\n const links = parseLinks(token.children)\n const time = parseTime(cleanText)\n const duration = parseDuration(cleanText)\n\n if (date) {\n obj.date = date\n }\n\n if (time) {\n obj.time = time\n }\n\n if (duration) {\n obj.duration = duration\n }\n\n if (links && links.length > 0) {\n obj.links = links\n }\n\n if (images && images.length > 0) {\n obj.images = images\n }\n\n obj.content.push(cleanText)\n } else if (token.type === 'list') {\n const obj = structuredResponse[currentHeading]\n obj.text = cleanText\n obj.list = parseList(token).flat()\n } else if (token.type === 'html') {\n const obj = structuredResponse[currentHeading]\n obj.content.push(token.html)\n } else if (token.type === 'code') {\n const obj = structuredResponse[currentHeading]\n obj.lang = token.lang\n obj.text = cleanText\n } else {\n debug('unhandled token type')\n debug(token)\n }\n }\n\n for (const key in structuredResponse) {\n const token = structuredResponse[key]\n const content = token.content.filter(Boolean)\n if (content && content.length > 0) {\n if (content.length === 1) {\n token.text = content[0]\n }\n token.text = content.join('\\n\\n')\n }\n token.content = content\n }\n\n return structuredResponse\n}\n","'use strict'\n\nexport default function parseImage(props) {\n return props\n .filter((p) => p.type === 'image')\n .map((p) => {\n return {\n src: p.url,\n alt: p.alt\n }\n })\n}\n","'use strict'\n\nexport default function parseLinks(props) {\n return props\n .filter((p) => p.type === 'link')\n .map((p) => {\n return {\n src: p.url,\n alt: p.children[0].value\n }\n })\n}\n","'use strict'\n\nexport default function parseDuration(text) {\n let matched = false\n const duration = {\n hours: 0,\n minutes: 0\n }\n\n const hoursAndMinutes = new RegExp(/([0-9]+)h([0-9]+)m/)\n const hours = new RegExp(/([0-9]+)h/)\n\n if (text.match(hoursAndMinutes)) {\n matched = true\n const [, h, m] = text.match(hoursAndMinutes)\n duration.hours = parseInt(h)\n duration.minutes = parseInt(m)\n } else if (text.match(hours)) {\n matched = true\n const [, h] = text.match(hours)\n duration.hours = parseInt(h)\n duration.minutes = 0\n }\n\n if (matched) {\n return duration\n } else {\n return null\n }\n}\n"],"names":["commonDateFormats","commonTimeFormats","parseList","list","children","map","item","listItem","type","checked","child","text","c","link","url","value","filter","x","join","_settle","pact","state","s","_Pact","o","bind","v","then","observer","prototype","onFulfilled","onRejected","result","this","callback","e","_this","_isSettledPact","thenable","debug","createDebug","body","_iterator","_step","token","cleanText","obj","trimmedText","date","images","links","time","duration","key","content","Promise","resolve","unified","use","remarkParse","remarkGfm","parse","tokens","_temp2","structuredResponse","Boolean","length","currentHeading","_createForOfIteratorHelperLoose","_temp","test","update","stage","shouldContinue","updateValue","reject","_resumeAfterTest","_resumeAfterBody","_resumeAfterUpdate","_for","done","remarkStringify","stringify","_unified$use$use$stri","stripFinalNewline","indexOf","replace","slugify","title","heading","depth","trim","match","format","isMatch","fromZonedTime","Date","toJSON","split","p","src","alt","formatInTimeZone","parseTime","matched","hours","minutes","hoursAndMinutes","RegExp","_text$match","m","parseInt","_text$match2","parseDuration","push","flat","html","lang"],"mappings":"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"}
package/.eslintignore DELETED
@@ -1,5 +0,0 @@
1
- dist/
2
- action/
3
- pkg/
4
- coverage/
5
- test/
package/.eslintrc.json DELETED
@@ -1,15 +0,0 @@
1
- {
2
- "env": {
3
- "es2021": true,
4
- "node": true
5
- },
6
- "extends": [
7
- "eslint:recommended",
8
- "plugin:node/recommended",
9
- "plugin:json/recommended"
10
- ],
11
- "parserOptions": {
12
- "ecmaVersion": 2021,
13
- "sourceType": "module"
14
- }
15
- }
@@ -1,36 +0,0 @@
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
@@ -1 +0,0 @@
1
- blank_issues_enabled: false
@@ -1,38 +0,0 @@
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
@@ -1,6 +0,0 @@
1
- version: 2
2
- updates:
3
- - package-ecosystem: github-actions
4
- directory: '/'
5
- schedule:
6
- interval: 'monthly'
@@ -1,59 +0,0 @@
1
- name: 'CodeQL'
2
-
3
- on:
4
- push:
5
- branches: [main]
6
- pull_request:
7
- # The branches below must be a subset of the branches above
8
- branches: [main]
9
- schedule:
10
- - cron: '29 21 * * 5'
11
-
12
- jobs:
13
- analyze:
14
- name: Analyze
15
- runs-on: ubuntu-latest
16
- permissions:
17
- actions: read
18
- contents: read
19
- security-events: write
20
-
21
- strategy:
22
- fail-fast: false
23
- matrix:
24
- language: ['javascript']
25
- # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
26
- # Learn more about CodeQL language support at https://git.io/codeql-language-support
27
-
28
- steps:
29
- - name: Checkout repository
30
- uses: actions/checkout@v4
31
-
32
- # Initializes the CodeQL tools for scanning.
33
- - name: Initialize CodeQL
34
- uses: github/codeql-action/init@v2
35
- with:
36
- languages: ${{ matrix.language }}
37
- # If you wish to specify custom queries, you can do so here or in a config file.
38
- # By default, queries listed here will override any specified in a config file.
39
- # Prefix the list here with "+" to use these queries and those in the config file.
40
- # queries: ./path/to/local/query, your-org/your-repo/queries@main
41
-
42
- # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
43
- # If this step fails, then you should remove it and run the build manually (see below)
44
- - name: Autobuild
45
- uses: github/codeql-action/autobuild@v2
46
-
47
- # ℹ️ Command-line programs to run using the OS shell.
48
- # 📚 https://git.io/JvXDl
49
-
50
- # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
51
- # and modify them (or add more) to build your code if your project
52
- # uses a compiled language
53
-
54
- #- run: |
55
- # make bootstrap
56
- # make release
57
-
58
- - name: Perform CodeQL Analysis
59
- uses: github/codeql-action/analyze@v2
@@ -1,26 +0,0 @@
1
- name: e2e test
2
-
3
- on: issues
4
-
5
- jobs:
6
- test:
7
- runs-on: ubuntu-latest
8
- steps:
9
- - uses: actions/checkout@v4
10
- - name: Issue Forms Body Parser
11
- id: parse
12
- uses: ./
13
- - run: echo ${{ toJSON(steps.parse.outputs.data) }}
14
-
15
- - name: Read an issue content
16
- id: read_issue
17
- run: |
18
- echo "body<<EOF" >> $GITHUB_OUTPUT
19
- cat ./test/test-issue-3.md >> $GITHUB_OUTPUT
20
- echo "EOF" >> $GITHUB_OUTPUT
21
- - name: Issue Forms Body Parser With Provided Body
22
- id: parse_with_body
23
- uses: ./
24
- with:
25
- body: ${{ steps.read_issue.outputs.body }}
26
- - run: echo ${{ toJSON(steps.parse_with_body.outputs.data) }}
@@ -1,31 +0,0 @@
1
- name: Publish
2
-
3
- permissions:
4
- contents: write
5
- deployments: write
6
- issues: read
7
- pull-requests: write
8
-
9
- on:
10
- push:
11
- branches:
12
- - 'main'
13
-
14
- jobs:
15
- test:
16
- env:
17
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
18
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
19
- runs-on: ubuntu-latest
20
- steps:
21
- - uses: actions/checkout@v4
22
- - uses: actions/setup-node@v4
23
- with:
24
- node-version: 20
25
- cache: 'npm'
26
- - run: npm ci
27
- - run: npm test
28
- env:
29
- GITHUB_REPOSITORY: zentered/issue-forms-body-parser-test
30
- - run: npm run release
31
- - run: npx semantic-release
@@ -1,51 +0,0 @@
1
- name: Test
2
-
3
- on:
4
- pull_request:
5
- branches:
6
- - '**'
7
- - '!main'
8
- push:
9
- branches:
10
- - '**'
11
- - '!main'
12
-
13
- jobs:
14
- test:
15
- env:
16
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
17
- runs-on: ubuntu-latest
18
- steps:
19
- - uses: actions/checkout@v4
20
- - uses: actions/setup-node@v4
21
- with:
22
- node-version: 20
23
- cache: 'npm'
24
- - run: npm ci
25
- - run: npm run lint
26
- - run: npm test
27
- env:
28
- GITHUB_REPOSITORY: zentered/issue-forms-body-parser-test
29
-
30
- - run: npm run build
31
-
32
- - name: Read an issue content
33
- id: read_issue
34
- run: |
35
- echo "body<<EOF" >> $GITHUB_OUTPUT
36
- cat ./test/test-issue-3.md >> $GITHUB_OUTPUT
37
- echo "EOF" >> $GITHUB_OUTPUT
38
- - name: Issue Forms Body Parser With Provided Body
39
- id: parse_with_body
40
- uses: ./
41
- with:
42
- body: ${{ steps.read_issue.outputs.body }}
43
-
44
- - name: Test input body parsed
45
- run: |
46
- expected="Event Description"
47
- title=$(echo ${{ toJSON(steps.parse_with_body.outputs.data) }} | jq -r '.["event-description"].title')
48
- if [[ $title != $expected ]]; then
49
- echo "Title \"${title}\" does not match \"${expected}\""
50
- exit 1
51
- fi
package/.husky/commit-msg DELETED
@@ -1 +0,0 @@
1
- npx commitlint --edit $1
package/.husky/pre-commit DELETED
@@ -1 +0,0 @@
1
- npx lint-staged
package/.prettierignore DELETED
@@ -1,3 +0,0 @@
1
- action
2
- dist
3
- pkg
package/.prettierrc DELETED
@@ -1,6 +0,0 @@
1
- {
2
- "singleQuote": true,
3
- "semi": false,
4
- "trailingComma": "none",
5
- "proseWrap": "always"
6
- }
package/src/index.js DELETED
@@ -1,29 +0,0 @@
1
- 'use strict'
2
-
3
- import github from '@actions/github'
4
- import core from '@actions/core'
5
- import parse from './parse.js'
6
-
7
- async function run() {
8
- core.info('Parsing issue body ...')
9
-
10
- let content = core.getInput('body')
11
-
12
- if (content === '' && Object.hasOwn(github.context.payload, 'issue')) {
13
- content = github.context.payload.issue.body
14
- }
15
-
16
- try {
17
- const parsedContent = await parse(content)
18
-
19
- if (parsedContent !== undefined) {
20
- core.setOutput('data', parsedContent)
21
- } else {
22
- core.setFailed(`There was no valid payload found in the issue.`)
23
- }
24
- } catch (err) {
25
- core.setFailed(err)
26
- }
27
- }
28
-
29
- run()
package/src/parse.js DELETED
@@ -1,98 +0,0 @@
1
- 'use strict'
2
-
3
- import { unified } from 'unified'
4
- import remarkParse from 'remark-parse'
5
- import remarkGfm from 'remark-gfm'
6
- import slugify from '@sindresorhus/slugify'
7
- import remarkStringify from 'remark-stringify'
8
- import stripFinalNewline from 'strip-final-newline'
9
- import createDebug from 'debug'
10
- const debug = createDebug('body-parser')
11
-
12
- import {
13
- parseDate,
14
- parseTime,
15
- parseDuration,
16
- parseList
17
- } from './parsers/index.js'
18
-
19
- export default async function parseMD(body) {
20
- debug('parseMD()')
21
- const tokens = await unified().use(remarkParse).use(remarkGfm).parse(body)
22
- if (!tokens) {
23
- return []
24
- }
25
-
26
- const structuredResponse = {}
27
- let currentHeading = null
28
- for (const token of tokens.children) {
29
- const text = await unified()
30
- .use(remarkGfm)
31
- .use(remarkStringify)
32
- .stringify(token)
33
- let cleanText = stripFinalNewline(text)
34
-
35
- // remove `\\_`
36
- if (cleanText.indexOf('\\_') > -1) {
37
- cleanText = cleanText.replace(/\\_/g, '_')
38
- }
39
-
40
- // issue forms uses h3 as a heading
41
- if (token.type === 'heading') {
42
- currentHeading = slugify(token.children[0].value)
43
- structuredResponse[currentHeading] = {
44
- title: token.children[0].value,
45
- heading: token.depth,
46
- content: []
47
- }
48
- } else if (token.type === 'paragraph' && currentHeading) {
49
- const obj = structuredResponse[currentHeading]
50
-
51
- const date = parseDate(cleanText)
52
- const time = parseTime(cleanText)
53
- const duration = parseDuration(cleanText)
54
-
55
- if (date) {
56
- obj.date = date
57
- }
58
-
59
- if (time) {
60
- obj.time = time
61
- }
62
-
63
- if (duration) {
64
- obj.duration = duration
65
- }
66
-
67
- obj.content.push(cleanText)
68
- } else if (token.type === 'list') {
69
- const obj = structuredResponse[currentHeading]
70
- obj.text = cleanText
71
- obj.list = parseList(token).flat()
72
- } else if (token.type === 'html') {
73
- const obj = structuredResponse[currentHeading]
74
- obj.content.push(token.html)
75
- } else if (token.type === 'code') {
76
- const obj = structuredResponse[currentHeading]
77
- obj.lang = token.lang
78
- obj.text = cleanText
79
- } else {
80
- debug('unhandled token type')
81
- debug(token)
82
- }
83
- }
84
-
85
- for (const key in structuredResponse) {
86
- const token = structuredResponse[key]
87
- const content = token.content.filter(Boolean)
88
- if (content && content.length > 0) {
89
- if (content.length === 1) {
90
- token.text = content[0]
91
- }
92
- token.text = content.join('\n\n')
93
- }
94
- token.content = content
95
- }
96
-
97
- return structuredResponse
98
- }
@@ -1,30 +0,0 @@
1
- 'use strict'
2
-
3
- import { parse, isMatch } from 'date-fns'
4
- import { zonedTimeToUtc } from 'date-fns-tz'
5
-
6
- const loc = 'UTC'
7
- const commonDateFormats = [
8
- 'yyyy-MM-dd',
9
- 'dd/MM/yyyy',
10
- 'dd/MM/yy',
11
- 'dd-MM-yyyy',
12
- 'dd-MM-yy',
13
- 'dd.MM.yyyy',
14
- 'dd.MM.yy'
15
- ]
16
-
17
- export default function parseDate(text) {
18
- const match = commonDateFormats.map((format) => {
19
- return isMatch(text, format)
20
- })
21
- if (match.indexOf(true) > -1) {
22
- const date = zonedTimeToUtc(
23
- parse(text, commonDateFormats[match.indexOf(true)], new Date()),
24
- loc
25
- ).toJSON()
26
- return date.split('T')[0]
27
- } else {
28
- return null
29
- }
30
- }
@@ -1,30 +0,0 @@
1
- 'use strict'
2
-
3
- export default function parseDuration(text) {
4
- let matched = false
5
- const duration = {
6
- hours: 0,
7
- minutes: 0
8
- }
9
-
10
- const hoursAndMinutes = new RegExp(/([0-9]+)h([0-9]+)m/)
11
- const hours = new RegExp(/([0-9]+)h/)
12
-
13
- if (text.match(hoursAndMinutes)) {
14
- matched = true
15
- const [, h, m] = text.match(hoursAndMinutes)
16
- duration.hours = parseInt(h)
17
- duration.minutes = parseInt(m)
18
- } else if (text.match(hours)) {
19
- matched = true
20
- const [, h] = text.match(hours)
21
- duration.hours = parseInt(h)
22
- duration.minutes = 0
23
- }
24
-
25
- if (matched) {
26
- return duration
27
- } else {
28
- return null
29
- }
30
- }
@@ -1,11 +0,0 @@
1
- 'use strict'
2
-
3
- import date from './date.js'
4
- import time from './time.js'
5
- import duration from './duration.js'
6
- import list from './list.js'
7
-
8
- export const parseDate = date
9
- export const parseTime = time
10
- export const parseDuration = duration
11
- export const parseList = list
@@ -1,32 +0,0 @@
1
- 'use strict'
2
-
3
- export default function parseList(list) {
4
- return list.children
5
- .map((item) => {
6
- const listItem = {}
7
- if (item.type === 'list') {
8
- return parseList(list)
9
- } else if (item.type === 'listItem') {
10
- listItem.checked = item.checked
11
- return item.children
12
- .map((child) => {
13
- if (child.type === 'paragraph') {
14
- listItem.text = child.children
15
- .map((c) => {
16
- if (c.type === 'link') {
17
- listItem.link = c.url
18
- return `[${c.children[0].value}](${c.url})`
19
- } else {
20
- return c.value
21
- }
22
- })
23
- .filter((x) => !!x)
24
- .join('')
25
- return listItem
26
- }
27
- })
28
- .filter((x) => !!x)
29
- }
30
- })
31
- .filter((x) => !!x)
32
- }
@@ -1,28 +0,0 @@
1
- 'use strict'
2
-
3
- import { parse, isMatch } from 'date-fns'
4
- import { zonedTimeToUtc, formatInTimeZone } from 'date-fns-tz'
5
-
6
- const loc = 'UTC'
7
- const commonTimeFormats = [
8
- 'HH:mm',
9
- 'HH.mm',
10
- 'hh:mm aaa',
11
- 'hh:mm a..aa',
12
- 'hh:mm aaaa'
13
- ]
14
-
15
- export default function parseTime(text) {
16
- const match = commonTimeFormats.map((format) => {
17
- return isMatch(text, format)
18
- })
19
- if (match.indexOf(true) > -1) {
20
- const time = zonedTimeToUtc(
21
- parse(text, commonTimeFormats[match.indexOf(true)], new Date()),
22
- loc
23
- )
24
- return formatInTimeZone(time, loc, 'HH:mm')
25
- } else {
26
- return null
27
- }
28
- }