@zentered/issue-forms-body-parser 2.2.0 → 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.
@@ -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/images.js","../src/parsers/links.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'\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 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","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","match","stripFinalNewline","indexOf","replace","slugify","title","heading","depth","format","isMatch","zonedTimeToUtc","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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"}
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,111 +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
- parseImages,
18
- parseLinks
19
- } from './parsers/index.js'
20
-
21
- export default async function parseMD(body) {
22
- debug('parseMD()')
23
- const tokens = await unified().use(remarkParse).use(remarkGfm).parse(body)
24
- if (!tokens) {
25
- return []
26
- }
27
-
28
- const structuredResponse = {}
29
- let currentHeading = null
30
-
31
- for (const token of tokens.children) {
32
- const text = await unified()
33
- .use(remarkGfm)
34
- .use(remarkStringify)
35
- .stringify(token)
36
- let cleanText = stripFinalNewline(text)
37
-
38
- // remove `\\_`
39
- if (cleanText.indexOf('\\_') > -1) {
40
- cleanText = cleanText.replace(/\\_/g, '_')
41
- }
42
-
43
- // issue forms uses h3 as a heading
44
- if (token.type === 'heading') {
45
- currentHeading = slugify(token.children[0].value)
46
- structuredResponse[currentHeading] = {
47
- title: token.children[0].value,
48
- heading: token.depth,
49
- content: []
50
- }
51
- } else if (token.type === 'paragraph' && currentHeading) {
52
- const obj = structuredResponse[currentHeading]
53
-
54
- const date = parseDate(cleanText)
55
- const images = parseImages(token.children)
56
- const links = parseLinks(token.children)
57
- const time = parseTime(cleanText)
58
- const duration = parseDuration(cleanText)
59
-
60
- if (date) {
61
- obj.date = date
62
- }
63
-
64
- if (time) {
65
- obj.time = time
66
- }
67
-
68
- if (duration) {
69
- obj.duration = duration
70
- }
71
-
72
- if (links && links.length > 0) {
73
- obj.links = links
74
- }
75
-
76
- if (images && images.length > 0) {
77
- obj.images = images
78
- }
79
-
80
- obj.content.push(cleanText)
81
- } else if (token.type === 'list') {
82
- const obj = structuredResponse[currentHeading]
83
- obj.text = cleanText
84
- obj.list = parseList(token).flat()
85
- } else if (token.type === 'html') {
86
- const obj = structuredResponse[currentHeading]
87
- obj.content.push(token.html)
88
- } else if (token.type === 'code') {
89
- const obj = structuredResponse[currentHeading]
90
- obj.lang = token.lang
91
- obj.text = cleanText
92
- } else {
93
- debug('unhandled token type')
94
- debug(token)
95
- }
96
- }
97
-
98
- for (const key in structuredResponse) {
99
- const token = structuredResponse[key]
100
- const content = token.content.filter(Boolean)
101
- if (content && content.length > 0) {
102
- if (content.length === 1) {
103
- token.text = content[0]
104
- }
105
- token.text = content.join('\n\n')
106
- }
107
- token.content = content
108
- }
109
-
110
- return structuredResponse
111
- }
@@ -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,12 +0,0 @@
1
- 'use strict'
2
-
3
- export default function parseImage(props) {
4
- return props
5
- .filter((p) => p.type === 'image')
6
- .map((p) => {
7
- return {
8
- src: p.url,
9
- alt: p.alt
10
- }
11
- })
12
- }
@@ -1,15 +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
- import images from './images.js'
8
- import links from './links.js'
9
-
10
- export const parseDate = date
11
- export const parseTime = time
12
- export const parseDuration = duration
13
- export const parseList = list
14
- export const parseImages = images
15
- export const parseLinks = links
@@ -1,12 +0,0 @@
1
- 'use strict'
2
-
3
- export default function parseLinks(props) {
4
- return props
5
- .filter((p) => p.type === 'link')
6
- .map((p) => {
7
- return {
8
- src: p.url,
9
- alt: p.children[0].value
10
- }
11
- })
12
- }
@@ -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
- }