mirror of
https://github.com/peter-evans/dockerhub-description.git
synced 2024-11-21 19:49:32 +01:00
* feat: convert relative urls to absolute * test: add tests for conversion of relative urls Co-authored-by: Marty Winkler <mrtwnklr@users.noreply.github.com>
This commit is contained in:
parent
bbef094b30
commit
e139363f61
9 changed files with 774 additions and 18 deletions
35
README.md
35
README.md
|
@ -25,6 +25,8 @@ This is useful if you `docker push` your images to Docker Hub. It provides an ea
|
||||||
| `repository` | Docker Hub repository in the format `<namespace>/<name>`. | `github.repository` |
|
| `repository` | Docker Hub repository in the format `<namespace>/<name>`. | `github.repository` |
|
||||||
| `short-description` | Docker Hub repository short description. | |
|
| `short-description` | Docker Hub repository short description. | |
|
||||||
| `readme-filepath` | Path to the repository readme. | `./README.md` |
|
| `readme-filepath` | Path to the repository readme. | `./README.md` |
|
||||||
|
| `enable-url-completion` | Enables completion of relative URLs to absolute ones. See also [Known Issues](#known-issues). | `false` |
|
||||||
|
| `image-extensions` | File extensions that will be treated as images. | `bmp,gif,jpg,jpeg,png,svg,webp` |
|
||||||
|
|
||||||
#### Content limits
|
#### Content limits
|
||||||
|
|
||||||
|
@ -86,6 +88,7 @@ jobs:
|
||||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||||
repository: peterevans/dockerhub-description
|
repository: peterevans/dockerhub-description
|
||||||
short-description: ${{ github.event.repository.description }}
|
short-description: ${{ github.event.repository.description }}
|
||||||
|
enable-url-completion: true
|
||||||
```
|
```
|
||||||
|
|
||||||
Updates the Docker Hub repository description whenever a new release is created.
|
Updates the Docker Hub repository description whenever a new release is created.
|
||||||
|
@ -122,6 +125,38 @@ docker run -v $PWD:/workspace \
|
||||||
peterevans/dockerhub-description:3
|
peterevans/dockerhub-description:3
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Known Issues
|
||||||
|
|
||||||
|
The completion of relative urls has some known issues:
|
||||||
|
|
||||||
|
1. Relative markdown links in inline-code and code blocks **are also converted**:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
[link in inline code](#table-of-content)
|
||||||
|
```
|
||||||
|
|
||||||
|
will be converted into
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
[link in inline code](https://github.com/peter-evans/dockerhub-description/blob/main/./README.md#table-of-content)
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Links containing square brackets (`]`) in the text fragment **are not converted**:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
[[link text with square brackets]](#table-of-content)
|
||||||
|
```
|
||||||
|
|
||||||
|
3. [Reference-style links/images](https://www.markdownguide.org/basic-syntax/#reference-style-links) **are not converted**.
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
[table-of-content][toc]
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
[toc]: #table-of-content "Table of content"
|
||||||
|
```
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
[MIT](LICENSE)
|
[MIT](LICENSE)
|
||||||
|
|
335
__test__/readme-helper.unit.test.ts
Normal file
335
__test__/readme-helper.unit.test.ts
Normal file
|
@ -0,0 +1,335 @@
|
||||||
|
import {completeRelativeUrls} from '../src/readme-helper'
|
||||||
|
|
||||||
|
describe('complete relative urls tests', () => {
|
||||||
|
const GITHUB_SERVER_URL = process.env['GITHUB_SERVER_URL']
|
||||||
|
const GITHUB_REPOSITORY = process.env['GITHUB_REPOSITORY']
|
||||||
|
const GITHUB_REF_NAME = process.env['GITHUB_REF_NAME']
|
||||||
|
|
||||||
|
const README_FILEPATH = './README.md'
|
||||||
|
const EXPECTED_REPOSITORY_URL = `${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}`
|
||||||
|
const EXPECTED_BLOB_URL = `${EXPECTED_REPOSITORY_URL}/blob/${GITHUB_REF_NAME}`
|
||||||
|
const EXPECTED_RAW_URL = `${EXPECTED_REPOSITORY_URL}/raw/${GITHUB_REF_NAME}`
|
||||||
|
|
||||||
|
// known issues
|
||||||
|
test('reference-style links/image sources are not converted', async () => {
|
||||||
|
const content = [
|
||||||
|
'table-of-content][toc]',
|
||||||
|
'',
|
||||||
|
'[toc]: #table-of-content "Table of content"'
|
||||||
|
].join('\n')
|
||||||
|
expect(completeRelativeUrls(content, README_FILEPATH, true, '')).toEqual(
|
||||||
|
content
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('links containing square brackets in the text fragment are not converted', async () => {
|
||||||
|
expect(
|
||||||
|
completeRelativeUrls(
|
||||||
|
'[[text with square brackets]](README.md)',
|
||||||
|
README_FILEPATH,
|
||||||
|
true,
|
||||||
|
''
|
||||||
|
)
|
||||||
|
).toEqual('[[text with square brackets]](README.md)')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('links containing square brackets in the text fragment are not converted', async () => {
|
||||||
|
expect(
|
||||||
|
completeRelativeUrls('`[text](README.md)`', README_FILEPATH, true, '')
|
||||||
|
).toEqual(`\`[text](${EXPECTED_BLOB_URL}/README.md)\``)
|
||||||
|
})
|
||||||
|
|
||||||
|
// misc
|
||||||
|
test('do not change content when disabled', async () => {
|
||||||
|
expect(
|
||||||
|
completeRelativeUrls('[text](README.md)', README_FILEPATH, false, '')
|
||||||
|
).toEqual('[text](README.md)')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('do not change link with mailto protocol', async () => {
|
||||||
|
expect(
|
||||||
|
completeRelativeUrls(
|
||||||
|
'[text](mailto:mail@example.com)',
|
||||||
|
README_FILEPATH,
|
||||||
|
true,
|
||||||
|
''
|
||||||
|
)
|
||||||
|
).toEqual(`[text](mailto:mail@example.com)`)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('do not change link with ftp protocol', async () => {
|
||||||
|
expect(
|
||||||
|
completeRelativeUrls(
|
||||||
|
'[text](ftp://example.com)',
|
||||||
|
README_FILEPATH,
|
||||||
|
true,
|
||||||
|
''
|
||||||
|
)
|
||||||
|
).toEqual(`[text](ftp://example.com)`)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('do not change link with http protocol', async () => {
|
||||||
|
expect(
|
||||||
|
completeRelativeUrls(
|
||||||
|
'[text](http://example.com)',
|
||||||
|
README_FILEPATH,
|
||||||
|
true,
|
||||||
|
''
|
||||||
|
)
|
||||||
|
).toEqual(`[text](http://example.com)`)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('do not change link with https protocol', async () => {
|
||||||
|
expect(
|
||||||
|
completeRelativeUrls(
|
||||||
|
'[text](https://example.com)',
|
||||||
|
README_FILEPATH,
|
||||||
|
true,
|
||||||
|
''
|
||||||
|
)
|
||||||
|
).toEqual(`[text](https://example.com)`)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('do not change link with protocol-like beginning', async () => {
|
||||||
|
expect(
|
||||||
|
completeRelativeUrls(
|
||||||
|
'[text](abc://example.com)',
|
||||||
|
README_FILEPATH,
|
||||||
|
true,
|
||||||
|
''
|
||||||
|
)
|
||||||
|
).toEqual(`[text](abc://example.com)`)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('do not change image from absolute source with absolute link', async () => {
|
||||||
|
expect(
|
||||||
|
completeRelativeUrls(
|
||||||
|
'[![alttext](https://example.com/image.svg)](https://example.com/image.svg)',
|
||||||
|
README_FILEPATH,
|
||||||
|
true,
|
||||||
|
'svg'
|
||||||
|
)
|
||||||
|
).toEqual(
|
||||||
|
`[![alttext](https://example.com/image.svg)](https://example.com/image.svg)`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
// anchors
|
||||||
|
test('anchor referencing the current document', async () => {
|
||||||
|
expect(
|
||||||
|
completeRelativeUrls(
|
||||||
|
'[text](#relative-anchor)',
|
||||||
|
README_FILEPATH,
|
||||||
|
true,
|
||||||
|
''
|
||||||
|
)
|
||||||
|
).toEqual(`[text](${EXPECTED_BLOB_URL}/README.md#relative-anchor)`)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('anchor referencing the current document with a title', async () => {
|
||||||
|
expect(
|
||||||
|
completeRelativeUrls(
|
||||||
|
'[text](#relative-anchor "the anchor (a title)")',
|
||||||
|
README_FILEPATH,
|
||||||
|
true,
|
||||||
|
''
|
||||||
|
)
|
||||||
|
).toEqual(
|
||||||
|
`[text](${EXPECTED_BLOB_URL}/README.md#relative-anchor "the anchor (a title)")`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('anchor referencing the current document with a title and unicode', async () => {
|
||||||
|
expect(
|
||||||
|
completeRelativeUrls(
|
||||||
|
'[text with 🌬](#relative-anchor "the anchor (a title with 🌬)")',
|
||||||
|
README_FILEPATH,
|
||||||
|
true,
|
||||||
|
''
|
||||||
|
)
|
||||||
|
).toEqual(
|
||||||
|
`[text with 🌬](${EXPECTED_BLOB_URL}/README.md#relative-anchor "the anchor (a title with 🌬)")`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('anchor referencing another document', async () => {
|
||||||
|
expect(
|
||||||
|
completeRelativeUrls(
|
||||||
|
'[text](OTHER.md#absolute-anchor)',
|
||||||
|
README_FILEPATH,
|
||||||
|
true,
|
||||||
|
''
|
||||||
|
)
|
||||||
|
).toEqual(`[text](${EXPECTED_BLOB_URL}/OTHER.md#absolute-anchor)`)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('anchor referencing another document with a title', async () => {
|
||||||
|
expect(
|
||||||
|
completeRelativeUrls(
|
||||||
|
'[text](OTHER.md#absolute-anchor "the anchor (a title)")',
|
||||||
|
README_FILEPATH,
|
||||||
|
true,
|
||||||
|
''
|
||||||
|
)
|
||||||
|
).toEqual(
|
||||||
|
`[text](${EXPECTED_BLOB_URL}/OTHER.md#absolute-anchor "the anchor (a title)")`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('anchor with image referencing the current document', async () => {
|
||||||
|
expect(
|
||||||
|
completeRelativeUrls(
|
||||||
|
'[![alttext](image.svg)](#absolute-anchor "the anchor (a title)")',
|
||||||
|
README_FILEPATH,
|
||||||
|
true,
|
||||||
|
'svg'
|
||||||
|
)
|
||||||
|
).toEqual(
|
||||||
|
`[![alttext](${EXPECTED_RAW_URL}/image.svg)](${EXPECTED_BLOB_URL}/README.md#absolute-anchor "the anchor (a title)")`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('anchor with image referencing another document', async () => {
|
||||||
|
expect(
|
||||||
|
completeRelativeUrls(
|
||||||
|
'[![alttext](image.svg)](OTHER.md#absolute-anchor "the anchor (a title)")',
|
||||||
|
README_FILEPATH,
|
||||||
|
true,
|
||||||
|
'svg'
|
||||||
|
)
|
||||||
|
).toEqual(
|
||||||
|
`[![alttext](${EXPECTED_RAW_URL}/image.svg)](${EXPECTED_BLOB_URL}/OTHER.md#absolute-anchor "the anchor (a title)")`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
// documents
|
||||||
|
test('text document', async () => {
|
||||||
|
expect(
|
||||||
|
completeRelativeUrls('[text](document.yaml)', README_FILEPATH, true, '')
|
||||||
|
).toEqual(`[text](${EXPECTED_BLOB_URL}/document.yaml)`)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('pdf document', async () => {
|
||||||
|
expect(
|
||||||
|
completeRelativeUrls('[text](document.pdf)', README_FILEPATH, true, '')
|
||||||
|
).toEqual(`[text](${EXPECTED_BLOB_URL}/document.pdf)`)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('document with a title', async () => {
|
||||||
|
expect(
|
||||||
|
completeRelativeUrls(
|
||||||
|
'[text](document.pdf "the document (a title)")',
|
||||||
|
README_FILEPATH,
|
||||||
|
true,
|
||||||
|
''
|
||||||
|
)
|
||||||
|
).toEqual(
|
||||||
|
`[text](${EXPECTED_BLOB_URL}/document.pdf "the document (a title)")`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('document with a title and unicode', async () => {
|
||||||
|
expect(
|
||||||
|
completeRelativeUrls(
|
||||||
|
'[text with 🌬](document.pdf "the document (a title with 🌬)")',
|
||||||
|
README_FILEPATH,
|
||||||
|
true,
|
||||||
|
''
|
||||||
|
)
|
||||||
|
).toEqual(
|
||||||
|
`[text with 🌬](${EXPECTED_BLOB_URL}/document.pdf "the document (a title with 🌬)")`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
// images
|
||||||
|
test('image with supported file extension', async () => {
|
||||||
|
expect(
|
||||||
|
completeRelativeUrls(
|
||||||
|
'![alttext](image.svg)',
|
||||||
|
README_FILEPATH,
|
||||||
|
true,
|
||||||
|
'svg'
|
||||||
|
)
|
||||||
|
).toEqual(`![alttext](${EXPECTED_RAW_URL}/image.svg)`)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('image with unsupported file extension', async () => {
|
||||||
|
expect(
|
||||||
|
completeRelativeUrls(
|
||||||
|
'![alttext](image.svg)',
|
||||||
|
README_FILEPATH,
|
||||||
|
true,
|
||||||
|
'jpeg'
|
||||||
|
)
|
||||||
|
).toEqual(`![alttext](${EXPECTED_BLOB_URL}/image.svg)`)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('image without alternate text', async () => {
|
||||||
|
expect(
|
||||||
|
completeRelativeUrls('![](image.svg)', README_FILEPATH, true, 'svg')
|
||||||
|
).toEqual(`![](${EXPECTED_RAW_URL}/image.svg)`)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('image with a title', async () => {
|
||||||
|
expect(
|
||||||
|
completeRelativeUrls(
|
||||||
|
'![alttext](image.svg "the image (a title)")',
|
||||||
|
README_FILEPATH,
|
||||||
|
true,
|
||||||
|
'svg'
|
||||||
|
)
|
||||||
|
).toEqual(`![alttext](${EXPECTED_RAW_URL}/image.svg "the image (a title)")`)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('image with relative link', async () => {
|
||||||
|
expect(
|
||||||
|
completeRelativeUrls(
|
||||||
|
'[![alttext](image.svg)](image.svg)',
|
||||||
|
README_FILEPATH,
|
||||||
|
true,
|
||||||
|
'svg'
|
||||||
|
)
|
||||||
|
).toEqual(
|
||||||
|
`[![alttext](${EXPECTED_RAW_URL}/image.svg)](${EXPECTED_BLOB_URL}/image.svg)`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('image with a title, unicode and relative link', async () => {
|
||||||
|
expect(
|
||||||
|
completeRelativeUrls(
|
||||||
|
'[![alttext with 🌬](image.🌬.svg "the image.🌬.svg (a title)")](image.🌬.svg)',
|
||||||
|
README_FILEPATH,
|
||||||
|
true,
|
||||||
|
'svg'
|
||||||
|
)
|
||||||
|
).toEqual(
|
||||||
|
`[![alttext with 🌬](${EXPECTED_RAW_URL}/image.🌬.svg "the image.🌬.svg (a title)")](${EXPECTED_BLOB_URL}/image.🌬.svg)`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('image from absolute source with relative link', async () => {
|
||||||
|
expect(
|
||||||
|
completeRelativeUrls(
|
||||||
|
'[![alttext](https://example.com/image.svg)](image.svg)',
|
||||||
|
README_FILEPATH,
|
||||||
|
true,
|
||||||
|
'svg'
|
||||||
|
)
|
||||||
|
).toEqual(
|
||||||
|
`[![alttext](https://example.com/image.svg)](${EXPECTED_BLOB_URL}/image.svg)`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('image with absolute link', async () => {
|
||||||
|
expect(
|
||||||
|
completeRelativeUrls(
|
||||||
|
'[![alttext](image.svg)](https://example.com/image.svg)',
|
||||||
|
README_FILEPATH,
|
||||||
|
true,
|
||||||
|
'svg'
|
||||||
|
)
|
||||||
|
).toEqual(
|
||||||
|
`[![alttext](${EXPECTED_RAW_URL}/image.svg)](https://example.com/image.svg)`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
|
@ -18,6 +18,14 @@ inputs:
|
||||||
description: >
|
description: >
|
||||||
Path to the repository readme
|
Path to the repository readme
|
||||||
Default: `./README.md`
|
Default: `./README.md`
|
||||||
|
enable-url-completion:
|
||||||
|
description: >
|
||||||
|
Enables completion of relative urls to absolute ones
|
||||||
|
Default: `false`
|
||||||
|
image-extensions:
|
||||||
|
description: >
|
||||||
|
Extensions of files that you be treated as images
|
||||||
|
Default: `bmp,gif,jpg,jpeg,png,svg,webp`
|
||||||
runs:
|
runs:
|
||||||
using: 'node16'
|
using: 'node16'
|
||||||
main: 'dist/index.js'
|
main: 'dist/index.js'
|
||||||
|
|
192
dist/index.js
vendored
192
dist/index.js
vendored
|
@ -121,14 +121,16 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.validateInputs = exports.getInputs = void 0;
|
exports.validateInputs = exports.getInputs = void 0;
|
||||||
const core = __importStar(__nccwpck_require__(2186));
|
const core = __importStar(__nccwpck_require__(2186));
|
||||||
const README_FILEPATH_DEFAULT = './README.md';
|
const readmeHelper = __importStar(__nccwpck_require__(3367));
|
||||||
function getInputs() {
|
function getInputs() {
|
||||||
const inputs = {
|
const inputs = {
|
||||||
username: core.getInput('username'),
|
username: core.getInput('username'),
|
||||||
password: core.getInput('password'),
|
password: core.getInput('password'),
|
||||||
repository: core.getInput('repository'),
|
repository: core.getInput('repository'),
|
||||||
shortDescription: core.getInput('short-description'),
|
shortDescription: core.getInput('short-description'),
|
||||||
readmeFilepath: core.getInput('readme-filepath')
|
readmeFilepath: core.getInput('readme-filepath'),
|
||||||
|
enableUrlCompletion: Boolean(core.getInput('enable-url-completion')),
|
||||||
|
imageExtensions: core.getInput('image-extensions')
|
||||||
};
|
};
|
||||||
// Environment variable input alternatives and their aliases
|
// Environment variable input alternatives and their aliases
|
||||||
if (!inputs.username && process.env['DOCKERHUB_USERNAME']) {
|
if (!inputs.username && process.env['DOCKERHUB_USERNAME']) {
|
||||||
|
@ -155,15 +157,28 @@ function getInputs() {
|
||||||
if (!inputs.readmeFilepath && process.env['README_FILEPATH']) {
|
if (!inputs.readmeFilepath && process.env['README_FILEPATH']) {
|
||||||
inputs.readmeFilepath = process.env['README_FILEPATH'];
|
inputs.readmeFilepath = process.env['README_FILEPATH'];
|
||||||
}
|
}
|
||||||
|
if (!inputs.enableUrlCompletion && process.env['ENABLE_URL_COMPLETION']) {
|
||||||
|
inputs.enableUrlCompletion = Boolean(process.env['ENABLE_URL_COMPLETION']);
|
||||||
|
}
|
||||||
|
if (!inputs.imageExtensions && process.env['IMAGE_EXTENSIONS']) {
|
||||||
|
inputs.imageExtensions = process.env['IMAGE_EXTENSIONS'];
|
||||||
|
}
|
||||||
// Set defaults
|
// Set defaults
|
||||||
if (!inputs.readmeFilepath) {
|
if (!inputs.readmeFilepath) {
|
||||||
inputs.readmeFilepath = README_FILEPATH_DEFAULT;
|
inputs.readmeFilepath = readmeHelper.README_FILEPATH_DEFAULT;
|
||||||
|
}
|
||||||
|
if (!inputs.enableUrlCompletion) {
|
||||||
|
inputs.enableUrlCompletion = readmeHelper.ENABLE_URL_COMPLETION_DEFAULT;
|
||||||
|
}
|
||||||
|
if (!inputs.imageExtensions) {
|
||||||
|
inputs.imageExtensions = readmeHelper.IMAGE_EXTENSIONS_DEFAULT;
|
||||||
}
|
}
|
||||||
if (!inputs.repository && process.env['GITHUB_REPOSITORY']) {
|
if (!inputs.repository && process.env['GITHUB_REPOSITORY']) {
|
||||||
inputs.repository = process.env['GITHUB_REPOSITORY'];
|
inputs.repository = process.env['GITHUB_REPOSITORY'];
|
||||||
}
|
}
|
||||||
// Docker repositories must be all lower case
|
// Enforce lower case, where needed
|
||||||
inputs.repository = inputs.repository.toLowerCase();
|
inputs.repository = inputs.repository.toLowerCase();
|
||||||
|
inputs.imageExtensions = inputs.imageExtensions.toLowerCase();
|
||||||
return inputs;
|
return inputs;
|
||||||
}
|
}
|
||||||
exports.getInputs = getInputs;
|
exports.getInputs = getInputs;
|
||||||
|
@ -222,7 +237,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
const core = __importStar(__nccwpck_require__(2186));
|
const core = __importStar(__nccwpck_require__(2186));
|
||||||
const inputHelper = __importStar(__nccwpck_require__(5480));
|
const inputHelper = __importStar(__nccwpck_require__(5480));
|
||||||
const dockerhubHelper = __importStar(__nccwpck_require__(1812));
|
const dockerhubHelper = __importStar(__nccwpck_require__(1812));
|
||||||
const fs = __importStar(__nccwpck_require__(7147));
|
const readmeHelper = __importStar(__nccwpck_require__(3367));
|
||||||
const util_1 = __nccwpck_require__(3837);
|
const util_1 = __nccwpck_require__(3837);
|
||||||
function getErrorMessage(error) {
|
function getErrorMessage(error) {
|
||||||
if (error instanceof Error)
|
if (error instanceof Error)
|
||||||
|
@ -236,9 +251,9 @@ function run() {
|
||||||
core.debug(`Inputs: ${(0, util_1.inspect)(inputs)}`);
|
core.debug(`Inputs: ${(0, util_1.inspect)(inputs)}`);
|
||||||
inputHelper.validateInputs(inputs);
|
inputHelper.validateInputs(inputs);
|
||||||
// Fetch the readme content
|
// Fetch the readme content
|
||||||
const readmeContent = yield fs.promises.readFile(inputs.readmeFilepath, {
|
core.info('Reading description source file');
|
||||||
encoding: 'utf8'
|
const readmeContent = yield readmeHelper.getReadmeContent(inputs.readmeFilepath, inputs.enableUrlCompletion, inputs.imageExtensions);
|
||||||
});
|
core.debug(readmeContent);
|
||||||
// Acquire a token for the Docker Hub API
|
// Acquire a token for the Docker Hub API
|
||||||
core.info('Acquiring token');
|
core.info('Acquiring token');
|
||||||
const token = yield dockerhubHelper.getToken(inputs.username, inputs.password);
|
const token = yield dockerhubHelper.getToken(inputs.username, inputs.password);
|
||||||
|
@ -256,6 +271,167 @@ function run() {
|
||||||
run();
|
run();
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 3367:
|
||||||
|
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||||
|
}
|
||||||
|
Object.defineProperty(o, k2, desc);
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||||
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||||||
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||||
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||||
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||||
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports.completeRelativeUrls = exports.getReadmeContent = exports.ENABLE_URL_COMPLETION_DEFAULT = exports.IMAGE_EXTENSIONS_DEFAULT = exports.README_FILEPATH_DEFAULT = void 0;
|
||||||
|
const core = __importStar(__nccwpck_require__(2186));
|
||||||
|
const fs = __importStar(__nccwpck_require__(7147));
|
||||||
|
exports.README_FILEPATH_DEFAULT = './README.md';
|
||||||
|
exports.IMAGE_EXTENSIONS_DEFAULT = 'bmp,gif,jpg,jpeg,png,svg,webp';
|
||||||
|
exports.ENABLE_URL_COMPLETION_DEFAULT = false;
|
||||||
|
const TITLE_REGEX = `(?: +"[^"]+")?`;
|
||||||
|
const REPOSITORY_URL = `${process.env['GITHUB_SERVER_URL']}/${process.env['GITHUB_REPOSITORY']}`;
|
||||||
|
const BLOB_PREFIX = `${REPOSITORY_URL}/blob/${process.env['GITHUB_REF_NAME']}/`;
|
||||||
|
const RAW_PREFIX = `${REPOSITORY_URL}/raw/${process.env['GITHUB_REF_NAME']}/`;
|
||||||
|
function getReadmeContent(readmeFilepath, enableUrlCompletion, imageExtensions) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
// Fetch the readme content
|
||||||
|
let readmeContent = yield fs.promises.readFile(readmeFilepath, {
|
||||||
|
encoding: 'utf8'
|
||||||
|
});
|
||||||
|
readmeContent = completeRelativeUrls(readmeContent, readmeFilepath, enableUrlCompletion, imageExtensions);
|
||||||
|
return readmeContent;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
exports.getReadmeContent = getReadmeContent;
|
||||||
|
function completeRelativeUrls(readmeContent, readmeFilepath, enableUrlCompletion, imageExtensions) {
|
||||||
|
if (enableUrlCompletion) {
|
||||||
|
readmeFilepath = readmeFilepath.replace(/^[.][/]/, '');
|
||||||
|
// Make relative urls absolute
|
||||||
|
const rules = [
|
||||||
|
...getRelativeReadmeAnchorsRules(readmeFilepath),
|
||||||
|
...getRelativeImageUrlRules(imageExtensions),
|
||||||
|
...getRelativeUrlRules()
|
||||||
|
];
|
||||||
|
readmeContent = applyRules(rules, readmeContent);
|
||||||
|
}
|
||||||
|
return readmeContent;
|
||||||
|
}
|
||||||
|
exports.completeRelativeUrls = completeRelativeUrls;
|
||||||
|
function applyRules(rules, readmeContent) {
|
||||||
|
rules.forEach(rule => {
|
||||||
|
const combinedRegex = `${rule.left.source}[(]${rule.url.source}[)]`;
|
||||||
|
core.debug(`rule: ${combinedRegex}`);
|
||||||
|
const replacement = `$<left>(${rule.absUrlPrefix}$<url>)`;
|
||||||
|
core.debug(`replacement: ${replacement}`);
|
||||||
|
readmeContent = readmeContent.replace(new RegExp(combinedRegex, 'giu'), replacement);
|
||||||
|
});
|
||||||
|
return readmeContent;
|
||||||
|
}
|
||||||
|
// has to be applied first to avoid wrong results
|
||||||
|
function getRelativeReadmeAnchorsRules(readmeFilepath) {
|
||||||
|
const prefix = `${BLOB_PREFIX}${readmeFilepath}`;
|
||||||
|
// matches e.g.:
|
||||||
|
// #table-of-content
|
||||||
|
// #table-of-content "the anchor (a title)"
|
||||||
|
const url = new RegExp(`(?<url>#[^)]+${TITLE_REGEX})`);
|
||||||
|
const rules = [
|
||||||
|
// matches e.g.:
|
||||||
|
// [#table-of-content](#table-of-content)
|
||||||
|
// [#table-of-content](#table-of-content "the anchor (a title)")
|
||||||
|
{
|
||||||
|
left: /(?<left>\[[^\]]+\])/,
|
||||||
|
url: url,
|
||||||
|
absUrlPrefix: prefix
|
||||||
|
},
|
||||||
|
// matches e.g.:
|
||||||
|
// [![media/image.svg](media/image.svg)](#table-of-content)
|
||||||
|
// [![media/image.svg](media/image.svg "title a")](#table-of-content "title b")
|
||||||
|
{
|
||||||
|
left: /(?<left>\[!\[[^\]]*\]\([^)]+\)\])/,
|
||||||
|
url: url,
|
||||||
|
absUrlPrefix: prefix
|
||||||
|
}
|
||||||
|
];
|
||||||
|
return rules;
|
||||||
|
}
|
||||||
|
function getRelativeImageUrlRules(imageExtensions) {
|
||||||
|
const extensionsRegex = imageExtensions.replace(/,/g, '|');
|
||||||
|
// matches e.g.:
|
||||||
|
// media/image.svg
|
||||||
|
// media/image.svg "with title"
|
||||||
|
const url = new RegExp(`(?<url>[^:)]+[.](?:${extensionsRegex})${TITLE_REGEX})`);
|
||||||
|
const rules = [
|
||||||
|
// matches e.g.:
|
||||||
|
// ![media/image.svg](media/image.svg)
|
||||||
|
// ![media/image.svg](media/image.svg "with title")
|
||||||
|
{
|
||||||
|
left: /(?<left>!\[[^\]]*\])/,
|
||||||
|
url: url,
|
||||||
|
absUrlPrefix: RAW_PREFIX
|
||||||
|
}
|
||||||
|
];
|
||||||
|
return rules;
|
||||||
|
}
|
||||||
|
function getRelativeUrlRules() {
|
||||||
|
// matches e.g.:
|
||||||
|
// .releaserc.yaml
|
||||||
|
// README.md#table-of-content "title b"
|
||||||
|
// .releaserc.yaml "the .releaserc.yaml file (a title)"
|
||||||
|
const url = new RegExp(`(?<url>[^:)]+${TITLE_REGEX})`);
|
||||||
|
const rules = [
|
||||||
|
// matches e.g.:
|
||||||
|
// [.releaserc.yaml](.releaserc.yaml)
|
||||||
|
// [.releaserc.yaml](.releaserc.yaml "the .releaserc.yaml file (a title)")
|
||||||
|
{
|
||||||
|
left: /(?<left>\[[^\]]+\])/,
|
||||||
|
url: url,
|
||||||
|
absUrlPrefix: BLOB_PREFIX
|
||||||
|
},
|
||||||
|
// matches e.g.:
|
||||||
|
// [![media/image.svg](media/image.svg)](media/image.svg)
|
||||||
|
// [![media/image.svg](media/image.svg)](README.md#table-of-content "title b")
|
||||||
|
// [![media/image.svg](media/image.svg "title a")](media/image.svg)
|
||||||
|
// [![media/image.svg](media/image.svg "title a")](media/image.svg "title b")
|
||||||
|
// [![media/image.svg](media/image.svg "title a")](README.md#table-of-content "title b")
|
||||||
|
{
|
||||||
|
left: new RegExp(`(?<left>\\[!\\[[^\\]]*\\]\\([^)]+${TITLE_REGEX}\\)\\])`),
|
||||||
|
url: url,
|
||||||
|
absUrlPrefix: BLOB_PREFIX
|
||||||
|
}
|
||||||
|
];
|
||||||
|
return rules;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 7351:
|
/***/ 7351:
|
||||||
|
|
|
@ -9,3 +9,8 @@ module.exports = {
|
||||||
},
|
},
|
||||||
verbose: true
|
verbose: true
|
||||||
}
|
}
|
||||||
|
process.env = Object.assign(process.env, {
|
||||||
|
GITHUB_SERVER_URL: 'https://github.com',
|
||||||
|
GITHUB_REPOSITORY: 'peter-evans/dockerhub-description',
|
||||||
|
GITHUB_REF_NAME: 'main'
|
||||||
|
})
|
|
@ -9,7 +9,7 @@
|
||||||
"format": "prettier --write '**/*.ts'",
|
"format": "prettier --write '**/*.ts'",
|
||||||
"format-check": "prettier --check '**/*.ts'",
|
"format-check": "prettier --check '**/*.ts'",
|
||||||
"lint": "eslint src/**/*.ts",
|
"lint": "eslint src/**/*.ts",
|
||||||
"test": "jest --passWithNoTests"
|
"test": "jest"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
|
import * as readmeHelper from './readme-helper'
|
||||||
const README_FILEPATH_DEFAULT = './README.md'
|
|
||||||
|
|
||||||
interface Inputs {
|
interface Inputs {
|
||||||
username: string
|
username: string
|
||||||
|
@ -8,6 +7,8 @@ interface Inputs {
|
||||||
repository: string
|
repository: string
|
||||||
shortDescription: string
|
shortDescription: string
|
||||||
readmeFilepath: string
|
readmeFilepath: string
|
||||||
|
enableUrlCompletion: boolean
|
||||||
|
imageExtensions: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getInputs(): Inputs {
|
export function getInputs(): Inputs {
|
||||||
|
@ -16,7 +17,9 @@ export function getInputs(): Inputs {
|
||||||
password: core.getInput('password'),
|
password: core.getInput('password'),
|
||||||
repository: core.getInput('repository'),
|
repository: core.getInput('repository'),
|
||||||
shortDescription: core.getInput('short-description'),
|
shortDescription: core.getInput('short-description'),
|
||||||
readmeFilepath: core.getInput('readme-filepath')
|
readmeFilepath: core.getInput('readme-filepath'),
|
||||||
|
enableUrlCompletion: Boolean(core.getInput('enable-url-completion')),
|
||||||
|
imageExtensions: core.getInput('image-extensions')
|
||||||
}
|
}
|
||||||
|
|
||||||
// Environment variable input alternatives and their aliases
|
// Environment variable input alternatives and their aliases
|
||||||
|
@ -50,16 +53,31 @@ export function getInputs(): Inputs {
|
||||||
inputs.readmeFilepath = process.env['README_FILEPATH']
|
inputs.readmeFilepath = process.env['README_FILEPATH']
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!inputs.enableUrlCompletion && process.env['ENABLE_URL_COMPLETION']) {
|
||||||
|
inputs.enableUrlCompletion = Boolean(process.env['ENABLE_URL_COMPLETION'])
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inputs.imageExtensions && process.env['IMAGE_EXTENSIONS']) {
|
||||||
|
inputs.imageExtensions = process.env['IMAGE_EXTENSIONS']
|
||||||
|
}
|
||||||
|
|
||||||
// Set defaults
|
// Set defaults
|
||||||
if (!inputs.readmeFilepath) {
|
if (!inputs.readmeFilepath) {
|
||||||
inputs.readmeFilepath = README_FILEPATH_DEFAULT
|
inputs.readmeFilepath = readmeHelper.README_FILEPATH_DEFAULT
|
||||||
|
}
|
||||||
|
if (!inputs.enableUrlCompletion) {
|
||||||
|
inputs.enableUrlCompletion = readmeHelper.ENABLE_URL_COMPLETION_DEFAULT
|
||||||
|
}
|
||||||
|
if (!inputs.imageExtensions) {
|
||||||
|
inputs.imageExtensions = readmeHelper.IMAGE_EXTENSIONS_DEFAULT
|
||||||
}
|
}
|
||||||
if (!inputs.repository && process.env['GITHUB_REPOSITORY']) {
|
if (!inputs.repository && process.env['GITHUB_REPOSITORY']) {
|
||||||
inputs.repository = process.env['GITHUB_REPOSITORY']
|
inputs.repository = process.env['GITHUB_REPOSITORY']
|
||||||
}
|
}
|
||||||
|
|
||||||
// Docker repositories must be all lower case
|
// Enforce lower case, where needed
|
||||||
inputs.repository = inputs.repository.toLowerCase()
|
inputs.repository = inputs.repository.toLowerCase()
|
||||||
|
inputs.imageExtensions = inputs.imageExtensions.toLowerCase()
|
||||||
|
|
||||||
return inputs
|
return inputs
|
||||||
}
|
}
|
||||||
|
|
12
src/main.ts
12
src/main.ts
|
@ -1,7 +1,7 @@
|
||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import * as inputHelper from './input-helper'
|
import * as inputHelper from './input-helper'
|
||||||
import * as dockerhubHelper from './dockerhub-helper'
|
import * as dockerhubHelper from './dockerhub-helper'
|
||||||
import * as fs from 'fs'
|
import * as readmeHelper from './readme-helper'
|
||||||
import {inspect} from 'util'
|
import {inspect} from 'util'
|
||||||
|
|
||||||
function getErrorMessage(error: unknown) {
|
function getErrorMessage(error: unknown) {
|
||||||
|
@ -17,9 +17,13 @@ async function run(): Promise<void> {
|
||||||
inputHelper.validateInputs(inputs)
|
inputHelper.validateInputs(inputs)
|
||||||
|
|
||||||
// Fetch the readme content
|
// Fetch the readme content
|
||||||
const readmeContent = await fs.promises.readFile(inputs.readmeFilepath, {
|
core.info('Reading description source file')
|
||||||
encoding: 'utf8'
|
const readmeContent = await readmeHelper.getReadmeContent(
|
||||||
})
|
inputs.readmeFilepath,
|
||||||
|
inputs.enableUrlCompletion,
|
||||||
|
inputs.imageExtensions
|
||||||
|
)
|
||||||
|
core.debug(readmeContent)
|
||||||
|
|
||||||
// Acquire a token for the Docker Hub API
|
// Acquire a token for the Docker Hub API
|
||||||
core.info('Acquiring token')
|
core.info('Acquiring token')
|
||||||
|
|
175
src/readme-helper.ts
Normal file
175
src/readme-helper.ts
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
import * as core from '@actions/core'
|
||||||
|
import * as fs from 'fs'
|
||||||
|
|
||||||
|
export const README_FILEPATH_DEFAULT = './README.md'
|
||||||
|
export const IMAGE_EXTENSIONS_DEFAULT = 'bmp,gif,jpg,jpeg,png,svg,webp'
|
||||||
|
export const ENABLE_URL_COMPLETION_DEFAULT = false
|
||||||
|
|
||||||
|
const TITLE_REGEX = `(?: +"[^"]+")?`
|
||||||
|
const REPOSITORY_URL = `${process.env['GITHUB_SERVER_URL']}/${process.env['GITHUB_REPOSITORY']}`
|
||||||
|
const BLOB_PREFIX = `${REPOSITORY_URL}/blob/${process.env['GITHUB_REF_NAME']}/`
|
||||||
|
const RAW_PREFIX = `${REPOSITORY_URL}/raw/${process.env['GITHUB_REF_NAME']}/`
|
||||||
|
|
||||||
|
type Rule = {
|
||||||
|
/**
|
||||||
|
* all left of the relative url belonging to the markdown image/link
|
||||||
|
*/
|
||||||
|
left: RegExp
|
||||||
|
/**
|
||||||
|
* relative url
|
||||||
|
*/
|
||||||
|
url: RegExp
|
||||||
|
/**
|
||||||
|
* part to prefix the relative url with (excluding github repository url)
|
||||||
|
*/
|
||||||
|
absUrlPrefix: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getReadmeContent(
|
||||||
|
readmeFilepath: string,
|
||||||
|
enableUrlCompletion: boolean,
|
||||||
|
imageExtensions: string
|
||||||
|
): Promise<string> {
|
||||||
|
// Fetch the readme content
|
||||||
|
let readmeContent = await fs.promises.readFile(readmeFilepath, {
|
||||||
|
encoding: 'utf8'
|
||||||
|
})
|
||||||
|
|
||||||
|
readmeContent = completeRelativeUrls(
|
||||||
|
readmeContent,
|
||||||
|
readmeFilepath,
|
||||||
|
enableUrlCompletion,
|
||||||
|
imageExtensions
|
||||||
|
)
|
||||||
|
|
||||||
|
return readmeContent
|
||||||
|
}
|
||||||
|
|
||||||
|
export function completeRelativeUrls(
|
||||||
|
readmeContent: string,
|
||||||
|
readmeFilepath: string,
|
||||||
|
enableUrlCompletion: boolean,
|
||||||
|
imageExtensions: string
|
||||||
|
): string {
|
||||||
|
if (enableUrlCompletion) {
|
||||||
|
readmeFilepath = readmeFilepath.replace(/^[.][/]/, '')
|
||||||
|
|
||||||
|
// Make relative urls absolute
|
||||||
|
const rules = [
|
||||||
|
...getRelativeReadmeAnchorsRules(readmeFilepath),
|
||||||
|
...getRelativeImageUrlRules(imageExtensions),
|
||||||
|
...getRelativeUrlRules()
|
||||||
|
]
|
||||||
|
|
||||||
|
readmeContent = applyRules(rules, readmeContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
return readmeContent
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyRules(rules: Rule[], readmeContent: string): string {
|
||||||
|
rules.forEach(rule => {
|
||||||
|
const combinedRegex = `${rule.left.source}[(]${rule.url.source}[)]`
|
||||||
|
core.debug(`rule: ${combinedRegex}`)
|
||||||
|
|
||||||
|
const replacement = `$<left>(${rule.absUrlPrefix}$<url>)`
|
||||||
|
core.debug(`replacement: ${replacement}`)
|
||||||
|
|
||||||
|
readmeContent = readmeContent.replace(
|
||||||
|
new RegExp(combinedRegex, 'giu'),
|
||||||
|
replacement
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
return readmeContent
|
||||||
|
}
|
||||||
|
|
||||||
|
// has to be applied first to avoid wrong results
|
||||||
|
function getRelativeReadmeAnchorsRules(readmeFilepath: string): Rule[] {
|
||||||
|
const prefix = `${BLOB_PREFIX}${readmeFilepath}`
|
||||||
|
|
||||||
|
// matches e.g.:
|
||||||
|
// #table-of-content
|
||||||
|
// #table-of-content "the anchor (a title)"
|
||||||
|
const url = new RegExp(`(?<url>#[^)]+${TITLE_REGEX})`)
|
||||||
|
|
||||||
|
const rules: Rule[] = [
|
||||||
|
// matches e.g.:
|
||||||
|
// [#table-of-content](#table-of-content)
|
||||||
|
// [#table-of-content](#table-of-content "the anchor (a title)")
|
||||||
|
{
|
||||||
|
left: /(?<left>\[[^\]]+\])/,
|
||||||
|
url: url,
|
||||||
|
absUrlPrefix: prefix
|
||||||
|
},
|
||||||
|
|
||||||
|
// matches e.g.:
|
||||||
|
// [![media/image.svg](media/image.svg)](#table-of-content)
|
||||||
|
// [![media/image.svg](media/image.svg "title a")](#table-of-content "title b")
|
||||||
|
{
|
||||||
|
left: /(?<left>\[!\[[^\]]*\]\([^)]+\)\])/,
|
||||||
|
url: url,
|
||||||
|
absUrlPrefix: prefix
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
return rules
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRelativeImageUrlRules(imageExtensions: string): Rule[] {
|
||||||
|
const extensionsRegex = imageExtensions.replace(/,/g, '|')
|
||||||
|
// matches e.g.:
|
||||||
|
// media/image.svg
|
||||||
|
// media/image.svg "with title"
|
||||||
|
const url = new RegExp(
|
||||||
|
`(?<url>[^:)]+[.](?:${extensionsRegex})${TITLE_REGEX})`
|
||||||
|
)
|
||||||
|
|
||||||
|
const rules: Rule[] = [
|
||||||
|
// matches e.g.:
|
||||||
|
// ![media/image.svg](media/image.svg)
|
||||||
|
// ![media/image.svg](media/image.svg "with title")
|
||||||
|
{
|
||||||
|
left: /(?<left>!\[[^\]]*\])/,
|
||||||
|
url: url,
|
||||||
|
absUrlPrefix: RAW_PREFIX
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
return rules
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRelativeUrlRules(): Rule[] {
|
||||||
|
// matches e.g.:
|
||||||
|
// .releaserc.yaml
|
||||||
|
// README.md#table-of-content "title b"
|
||||||
|
// .releaserc.yaml "the .releaserc.yaml file (a title)"
|
||||||
|
const url = new RegExp(`(?<url>[^:)]+${TITLE_REGEX})`)
|
||||||
|
|
||||||
|
const rules: Rule[] = [
|
||||||
|
// matches e.g.:
|
||||||
|
// [.releaserc.yaml](.releaserc.yaml)
|
||||||
|
// [.releaserc.yaml](.releaserc.yaml "the .releaserc.yaml file (a title)")
|
||||||
|
{
|
||||||
|
left: /(?<left>\[[^\]]+\])/,
|
||||||
|
url: url,
|
||||||
|
absUrlPrefix: BLOB_PREFIX
|
||||||
|
},
|
||||||
|
|
||||||
|
// matches e.g.:
|
||||||
|
// [![media/image.svg](media/image.svg)](media/image.svg)
|
||||||
|
// [![media/image.svg](media/image.svg)](README.md#table-of-content "title b")
|
||||||
|
// [![media/image.svg](media/image.svg "title a")](media/image.svg)
|
||||||
|
// [![media/image.svg](media/image.svg "title a")](media/image.svg "title b")
|
||||||
|
// [![media/image.svg](media/image.svg "title a")](README.md#table-of-content "title b")
|
||||||
|
{
|
||||||
|
left: new RegExp(
|
||||||
|
`(?<left>\\[!\\[[^\\]]*\\]\\([^)]+${TITLE_REGEX}\\)\\])`
|
||||||
|
),
|
||||||
|
url: url,
|
||||||
|
absUrlPrefix: BLOB_PREFIX
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
return rules
|
||||||
|
}
|
Loading…
Reference in a new issue