Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4f02b8b744 | ||
|
|
839c2ee3df | ||
|
|
a43fb1aa82 | ||
|
|
8f0b206fd3 | ||
|
|
9b14e2e2d3 | ||
|
|
af980963d6 | ||
|
|
5b1448e480 | ||
|
|
f7b694c6d5 | ||
|
|
e78d6f8d64 |
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. iOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Smartphone (please complete the following information):**
|
||||
- Device: [e.g. iPhone6]
|
||||
- OS: [e.g. iOS8.1]
|
||||
- Browser [e.g. stock browser, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
28
.github/workflows/build.yml
vendored
Normal file
28
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
name: "PR Checks"
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
check_pr:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
|
||||
- name: "yarn install"
|
||||
run: yarn install
|
||||
|
||||
- name: "yarn build"
|
||||
run: yarn build
|
||||
|
||||
- name: "check for uncommitted changes"
|
||||
# Ensure no changes, but ignore node_modules dir since dev/fresh ci deps installed.
|
||||
run: |
|
||||
git diff --exit-code --stat -- . ':!node_modules' \
|
||||
|| (echo "##[error] found changed files after build. please 'yarn build && npm run format'" \
|
||||
"and check in all changes" \
|
||||
&& exit 1)
|
||||
25
.github/workflows/checkin.yml
vendored
25
.github/workflows/checkin.yml
vendored
@@ -1,25 +0,0 @@
|
||||
name: "PR Checks"
|
||||
on: [pull_request, push]
|
||||
|
||||
jobs:
|
||||
check_pr:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
|
||||
- name: "yarn install"
|
||||
run: yarn install
|
||||
|
||||
- name: "yarn build"
|
||||
run: yarn build
|
||||
|
||||
- name: "yarn test"
|
||||
run: yarn test
|
||||
|
||||
- name: "check for uncommitted changes"
|
||||
# Ensure no changes, but ignore node_modules dir since dev/fresh ci deps installed.
|
||||
run: |
|
||||
git diff --exit-code --stat -- . ':!node_modules' \
|
||||
|| (echo "##[error] found changed files after build. please 'yarn build && npm run format'" \
|
||||
"and check in all changes" \
|
||||
&& exit 1)
|
||||
14
.github/workflows/test.yml
vendored
Normal file
14
.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
name: "Test"
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
check_pr:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
|
||||
- name: "yarn install"
|
||||
run: yarn install
|
||||
|
||||
- name: "yarn test"
|
||||
run: yarn test
|
||||
@@ -4,12 +4,14 @@ This action will create a github release and optionally upload an artifact to it
|
||||
|
||||
## Action Inputs
|
||||
- **allowUpdates**: An optional flag which indicates if we should update a release if it already exists. Defaults to false.
|
||||
- **artifactErrorsFailBuild**: An optional flag which indicates if artifact read or upload errors should fail the build.
|
||||
- **artifact**: An optional set of paths representing artifacts to upload to the release. This may be a single path or a comma delimited list of paths (or globs).
|
||||
- **artifacts**: An optional set of paths representing artifacts to upload to the release. This may be a single path or a comma delimited list of paths (or globs).
|
||||
- **artifactContentType**: The content type of the artifact. Defaults to raw.
|
||||
- **body**: An optional body for the release.
|
||||
- **bodyFile**: An optional body file for the release. This should be the path to the file.
|
||||
- **commit**: An optional commit reference. This will be used to create the tag if it does not exist.
|
||||
- **discussionCategory**: When provided this will generate a discussion of the specified category. The category must exist otherwise this will cause the action to fail. This isn't used with draft releases.
|
||||
- **draft**: Optionally marks this release as a draft release. Set to `true` to enable.
|
||||
- **name**: An optional name for the release. If this is omitted the tag will be used.
|
||||
- **omitBody**: Indicates if the release body should be omitted.
|
||||
|
||||
@@ -20,6 +20,7 @@ const artifacts = [
|
||||
const createBody = 'createBody'
|
||||
const createName = 'createName'
|
||||
const commit = 'commit'
|
||||
const discussionCategory = 'discussionCategory'
|
||||
const draft = true
|
||||
const id = 100
|
||||
const prerelease = true
|
||||
@@ -45,7 +46,7 @@ describe("Action", () => {
|
||||
|
||||
await action.perform()
|
||||
|
||||
expect(createMock).toBeCalledWith(tag, createBody, commit, draft, createName, prerelease)
|
||||
expect(createMock).toBeCalledWith(tag, createBody, commit, discussionCategory, draft, createName, prerelease)
|
||||
expect(uploadMock).not.toBeCalled()
|
||||
})
|
||||
|
||||
@@ -56,7 +57,7 @@ describe("Action", () => {
|
||||
|
||||
await action.perform()
|
||||
|
||||
expect(createMock).toBeCalledWith(tag, createBody, commit, draft, createName, prerelease)
|
||||
expect(createMock).toBeCalledWith(tag, createBody, commit, discussionCategory, draft, createName, prerelease)
|
||||
expect(uploadMock).toBeCalledWith(artifacts, releaseId, url)
|
||||
})
|
||||
|
||||
@@ -72,7 +73,7 @@ describe("Action", () => {
|
||||
|
||||
await action.perform()
|
||||
|
||||
expect(createMock).toBeCalledWith(tag, createBody, commit, draft, createName, prerelease)
|
||||
expect(createMock).toBeCalledWith(tag, createBody, commit, discussionCategory, draft, createName, prerelease)
|
||||
expect(uploadMock).toBeCalledWith(artifacts, releaseId, url)
|
||||
|
||||
})
|
||||
@@ -82,7 +83,7 @@ describe("Action", () => {
|
||||
|
||||
await action.perform()
|
||||
|
||||
expect(createMock).toBeCalledWith(tag, createBody, commit, draft, createName, prerelease)
|
||||
expect(createMock).toBeCalledWith(tag, createBody, commit, discussionCategory, draft, createName, prerelease)
|
||||
expect(uploadMock).toBeCalledWith(artifacts, releaseId, url)
|
||||
})
|
||||
|
||||
@@ -97,7 +98,7 @@ describe("Action", () => {
|
||||
expect(error).toEqual("error")
|
||||
}
|
||||
|
||||
expect(createMock).toBeCalledWith(tag, createBody, commit, draft, createName, prerelease)
|
||||
expect(createMock).toBeCalledWith(tag, createBody, commit, discussionCategory, draft, createName, prerelease)
|
||||
expect(uploadMock).not.toBeCalled()
|
||||
})
|
||||
|
||||
@@ -138,22 +139,32 @@ describe("Action", () => {
|
||||
expect(error).toEqual("error")
|
||||
}
|
||||
|
||||
expect(updateMock).toBeCalledWith(id, tag, updateBody, commit, draft, updateName, prerelease)
|
||||
expect(updateMock).toBeCalledWith(
|
||||
id,
|
||||
tag,
|
||||
updateBody,
|
||||
commit,
|
||||
discussionCategory,
|
||||
draft,
|
||||
updateName,
|
||||
prerelease
|
||||
)
|
||||
expect(uploadMock).not.toBeCalled()
|
||||
})
|
||||
|
||||
it('throws error when upload fails', async () => {
|
||||
const action = createAction(false, true)
|
||||
uploadMock.mockRejectedValue("error")
|
||||
const expectedError = {status: 404}
|
||||
uploadMock.mockRejectedValue(expectedError)
|
||||
|
||||
expect.hasAssertions()
|
||||
try {
|
||||
await action.perform()
|
||||
} catch (error) {
|
||||
expect(error).toEqual("error")
|
||||
expect(error).toEqual(expectedError)
|
||||
}
|
||||
|
||||
expect(createMock).toBeCalledWith(tag, createBody, commit, draft, createName, prerelease)
|
||||
expect(createMock).toBeCalledWith(tag, createBody, commit, discussionCategory, draft, createName, prerelease)
|
||||
expect(uploadMock).toBeCalledWith(artifacts, releaseId, url)
|
||||
})
|
||||
|
||||
@@ -170,7 +181,16 @@ describe("Action", () => {
|
||||
|
||||
await action.perform()
|
||||
|
||||
expect(updateMock).toBeCalledWith(id, tag, updateBody, commit, draft, updateName, prerelease)
|
||||
expect(updateMock).toBeCalledWith(
|
||||
id,
|
||||
tag,
|
||||
updateBody,
|
||||
commit,
|
||||
discussionCategory,
|
||||
draft,
|
||||
updateName,
|
||||
prerelease
|
||||
)
|
||||
expect(uploadMock).toBeCalledWith(artifacts, releaseId, url)
|
||||
|
||||
})
|
||||
@@ -180,7 +200,16 @@ describe("Action", () => {
|
||||
|
||||
await action.perform()
|
||||
|
||||
expect(updateMock).toBeCalledWith(id, tag, updateBody, commit, draft, updateName, prerelease)
|
||||
expect(updateMock).toBeCalledWith(
|
||||
id,
|
||||
tag,
|
||||
updateBody,
|
||||
commit,
|
||||
discussionCategory,
|
||||
draft,
|
||||
updateName,
|
||||
prerelease
|
||||
)
|
||||
expect(uploadMock).not.toBeCalled()
|
||||
|
||||
})
|
||||
@@ -190,7 +219,16 @@ describe("Action", () => {
|
||||
|
||||
await action.perform()
|
||||
|
||||
expect(updateMock).toBeCalledWith(id, tag, updateBody, commit, draft, updateName, prerelease)
|
||||
expect(updateMock).toBeCalledWith(
|
||||
id,
|
||||
tag,
|
||||
updateBody,
|
||||
commit,
|
||||
discussionCategory,
|
||||
draft,
|
||||
updateName,
|
||||
prerelease
|
||||
)
|
||||
expect(uploadMock).toBeCalledWith(artifacts, releaseId, url)
|
||||
|
||||
})
|
||||
@@ -239,10 +277,12 @@ describe("Action", () => {
|
||||
const MockInputs = jest.fn<Inputs, any>(() => {
|
||||
return {
|
||||
allowUpdates: allowUpdates,
|
||||
artifactErrorsFailBuild: true,
|
||||
artifacts: inputArtifact,
|
||||
createdReleaseBody: createBody,
|
||||
createdReleaseName: createName,
|
||||
commit: commit,
|
||||
discussionCategory: discussionCategory,
|
||||
draft: draft,
|
||||
owner: "owner",
|
||||
prerelease: prerelease,
|
||||
|
||||
@@ -1,19 +1,45 @@
|
||||
import { FileArtifactGlobber } from "../src/ArtifactGlobber"
|
||||
import { Globber } from "../src/Globber";
|
||||
import { Artifact } from "../src/Artifact";
|
||||
const warnMock = jest.fn()
|
||||
|
||||
import {FileArtifactGlobber} from "../src/ArtifactGlobber"
|
||||
import {Globber} from "../src/Globber";
|
||||
import {Artifact} from "../src/Artifact";
|
||||
import untildify = require("untildify");
|
||||
|
||||
const contentType = "raw"
|
||||
const globMock = jest.fn()
|
||||
const globResults = ["file1", "file2"]
|
||||
|
||||
jest.mock('@actions/core', () => {
|
||||
return {warning: warnMock};
|
||||
})
|
||||
|
||||
describe("ArtifactGlobber", () => {
|
||||
beforeEach(() => {
|
||||
globMock.mockClear()
|
||||
})
|
||||
|
||||
it("expands paths in which start with a ~", () => {
|
||||
const globber = createArtifactGlobber()
|
||||
|
||||
const expectedArtifacts =
|
||||
globResults.map((path) => new Artifact(path, contentType))
|
||||
|
||||
expect(globber.globArtifactString('~/path', 'raw', false))
|
||||
.toEqual(expectedArtifacts)
|
||||
expect(globMock).toBeCalledWith(untildify('~/path'))
|
||||
expect(warnMock).not.toBeCalled()
|
||||
})
|
||||
|
||||
it("globs simple path", () => {
|
||||
const globber = createArtifactGlobber()
|
||||
|
||||
const expectedArtifacts =
|
||||
globResults.map((path) => new Artifact(path, contentType))
|
||||
|
||||
expect(globber.globArtifactString('path', 'raw'))
|
||||
expect(globber.globArtifactString('path', 'raw', false))
|
||||
.toEqual(expectedArtifacts)
|
||||
expect(globMock).toBeCalledWith('path')
|
||||
expect(warnMock).not.toBeCalled()
|
||||
})
|
||||
|
||||
it("splits multiple paths", () => {
|
||||
@@ -24,16 +50,35 @@ describe("ArtifactGlobber", () => {
|
||||
.concat(globResults)
|
||||
.map((path) => new Artifact(path, contentType))
|
||||
|
||||
expect(globber.globArtifactString('path1,path2', 'raw'))
|
||||
expect(globber.globArtifactString('path1,path2', 'raw', false))
|
||||
.toEqual(expectedArtifacts)
|
||||
expect(globMock).toBeCalledWith('path1')
|
||||
expect(globMock).toBeCalledWith('path2')
|
||||
expect(warnMock).not.toBeCalled()
|
||||
})
|
||||
|
||||
function createArtifactGlobber(): FileArtifactGlobber {
|
||||
it("warns when no glob results are produced and empty results shouldn't throw", () => {
|
||||
const globber = createArtifactGlobber([])
|
||||
|
||||
expect(globber.globArtifactString('path', 'raw', false))
|
||||
.toEqual([])
|
||||
expect(warnMock).toBeCalled()
|
||||
})
|
||||
|
||||
it("throws when no glob results are produced and empty results shouild throw", () => {
|
||||
const globber = createArtifactGlobber([])
|
||||
expect(() => {
|
||||
globber.globArtifactString('path', 'raw', true)
|
||||
}).toThrow()
|
||||
})
|
||||
|
||||
function createArtifactGlobber(results: string[] = globResults): FileArtifactGlobber {
|
||||
const MockGlobber = jest.fn<Globber, any>(() => {
|
||||
return {
|
||||
glob: () => globResults
|
||||
glob: globMock
|
||||
}
|
||||
})
|
||||
globMock.mockReturnValue(results)
|
||||
return new FileArtifactGlobber(new MockGlobber())
|
||||
}
|
||||
})
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Artifact } from "../src/Artifact"
|
||||
import { GithubArtifactUploader } from "../src/ArtifactUploader"
|
||||
import { Releases } from "../src/Releases";
|
||||
import { RequestError } from '@octokit/request-error'
|
||||
import {Artifact} from "../src/Artifact"
|
||||
import {GithubArtifactUploader} from "../src/ArtifactUploader"
|
||||
import {Releases} from "../src/Releases";
|
||||
import {RequestError} from '@octokit/request-error'
|
||||
|
||||
const artifacts = [
|
||||
new Artifact('a/art1'),
|
||||
@@ -19,7 +19,9 @@ const uploadMock = jest.fn()
|
||||
jest.mock('fs', () => {
|
||||
return {
|
||||
readFileSync: () => fileContents,
|
||||
statSync: () => { return { size: contentLength } }
|
||||
statSync: () => {
|
||||
return {size: contentLength}
|
||||
}
|
||||
};
|
||||
})
|
||||
|
||||
@@ -124,6 +126,19 @@ describe('ArtifactUploader', () => {
|
||||
expect(deleteMock).toBeCalledTimes(0)
|
||||
})
|
||||
|
||||
it('throws upload error when replacesExistingArtifacts is true', async () => {
|
||||
mockListWithoutAssets()
|
||||
mockUploadError()
|
||||
const uploader = createUploader(true, true)
|
||||
|
||||
expect.hasAssertions()
|
||||
try {
|
||||
await uploader.uploadArtifacts(artifacts, releaseId, url)
|
||||
} catch (error) {
|
||||
expect(error).toEqual(Error("Failed to upload artifact art1. error."))
|
||||
}
|
||||
})
|
||||
|
||||
it('throws error from replace', async () => {
|
||||
mockDeleteError()
|
||||
mockListWithAssets()
|
||||
@@ -155,7 +170,7 @@ describe('ArtifactUploader', () => {
|
||||
expect(deleteMock).toBeCalledTimes(0)
|
||||
})
|
||||
|
||||
function createUploader(replaces: boolean): GithubArtifactUploader {
|
||||
function createUploader(replaces: boolean, throws: boolean = false): GithubArtifactUploader {
|
||||
const MockReleases = jest.fn<Releases, any>(() => {
|
||||
return {
|
||||
create: jest.fn(),
|
||||
@@ -167,7 +182,7 @@ describe('ArtifactUploader', () => {
|
||||
uploadArtifact: uploadMock
|
||||
}
|
||||
})
|
||||
return new GithubArtifactUploader(new MockReleases(), replaces)
|
||||
return new GithubArtifactUploader(new MockReleases(), replaces, throws)
|
||||
}
|
||||
|
||||
function mockDeleteError(): any {
|
||||
@@ -194,14 +209,24 @@ describe('ArtifactUploader', () => {
|
||||
}
|
||||
|
||||
function mockListWithoutAssets() {
|
||||
listArtifactsMock.mockResolvedValue({ data: [] })
|
||||
listArtifactsMock.mockResolvedValue({data: []})
|
||||
}
|
||||
|
||||
function mockUploadArtifact(status: number = 200, failures: number = 0) {
|
||||
const error = new RequestError(`HTTP ${status}`, status, { headers: {}, request: { method: 'GET', url: '', headers: {} } })
|
||||
const error = new RequestError(`HTTP ${status}`, status, {
|
||||
headers: {},
|
||||
request: {method: 'GET', url: '', headers: {}}
|
||||
})
|
||||
for (let index = 0; index < failures; index++) {
|
||||
uploadMock.mockRejectedValueOnce(error)
|
||||
}
|
||||
uploadMock.mockResolvedValue({})
|
||||
}
|
||||
|
||||
function mockUploadError() {
|
||||
uploadMock.mockRejectedValue({
|
||||
message: "error",
|
||||
status: 502
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
import { ErrorMessage } from "../src/ErrorMessage"
|
||||
|
||||
describe('ErrorMessage', () => {
|
||||
|
||||
describe('has error with code', () => {
|
||||
const error = {
|
||||
message: 'something bad happened',
|
||||
errors: [
|
||||
{
|
||||
code: 'missing',
|
||||
resource: 'release'
|
||||
},
|
||||
{
|
||||
code: 'already_exists',
|
||||
resource: 'release'
|
||||
}
|
||||
],
|
||||
status: 422
|
||||
}
|
||||
|
||||
it('does not have error', () => {
|
||||
const errorMessage = new ErrorMessage(error)
|
||||
expect(errorMessage.hasErrorWithCode('missing_field')).toBeFalsy()
|
||||
})
|
||||
|
||||
it('has error', () => {
|
||||
const errorMessage = new ErrorMessage(error)
|
||||
expect(errorMessage.hasErrorWithCode('missing')).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
||||
it('generates message with errors', () => {
|
||||
const error = {
|
||||
message: 'something bad happened',
|
||||
errors: [
|
||||
{
|
||||
code: 'missing',
|
||||
resource: 'release'
|
||||
},
|
||||
{
|
||||
code: 'already_exists',
|
||||
resource: 'release'
|
||||
}
|
||||
],
|
||||
status: 422
|
||||
}
|
||||
|
||||
const errorMessage = new ErrorMessage(error)
|
||||
|
||||
const expectedString = "Error 422: something bad happened\nErrors:\n- release does not exist.\n- release already exists."
|
||||
expect(errorMessage.toString()).toBe(expectedString)
|
||||
})
|
||||
|
||||
it('generates message without errors', () => {
|
||||
const error = {
|
||||
message: 'something bad happened',
|
||||
status: 422
|
||||
}
|
||||
|
||||
const errorMessage = new ErrorMessage(error)
|
||||
|
||||
expect(errorMessage.toString()).toBe('Error 422: something bad happened')
|
||||
})
|
||||
|
||||
it('provides error status', () => {
|
||||
const error = { status: 404 }
|
||||
const errorMessage = new ErrorMessage(error)
|
||||
expect(errorMessage.status).toBe(404)
|
||||
})
|
||||
})
|
||||
@@ -1,99 +1,70 @@
|
||||
import { GithubError } from "../src/GithubError"
|
||||
|
||||
describe('GithubError', () => {
|
||||
describe('ErrorMessage', () => {
|
||||
|
||||
it('provides error code', () => {
|
||||
describe('has error with code', () => {
|
||||
const error = {
|
||||
code: "missing"
|
||||
message: 'something bad happened',
|
||||
errors: [
|
||||
{
|
||||
code: 'missing',
|
||||
resource: 'release'
|
||||
},
|
||||
{
|
||||
code: 'already_exists',
|
||||
resource: 'release'
|
||||
}
|
||||
],
|
||||
status: 422
|
||||
}
|
||||
|
||||
const githubError = new GithubError(error)
|
||||
|
||||
expect(githubError.code).toBe('missing')
|
||||
})
|
||||
|
||||
it('generates missing resource error message', () => {
|
||||
const resource = "release"
|
||||
const error = {
|
||||
code: "missing",
|
||||
resource: resource
|
||||
}
|
||||
|
||||
const githubError = new GithubError(error)
|
||||
const message = githubError.toString()
|
||||
|
||||
expect(message).toBe(`${resource} does not exist.`)
|
||||
})
|
||||
|
||||
it('generates missing field error message', () => {
|
||||
const resource = "release"
|
||||
const field = "body"
|
||||
const error = {
|
||||
code: "missing_field",
|
||||
field: field,
|
||||
resource: resource
|
||||
}
|
||||
|
||||
const githubError = new GithubError(error)
|
||||
const message = githubError.toString()
|
||||
|
||||
expect(message).toBe(`The ${field} field on ${resource} is missing.`)
|
||||
})
|
||||
|
||||
it('generates invalid field error message', () => {
|
||||
const resource = "release"
|
||||
const field = "body"
|
||||
const error = {
|
||||
code: "invalid",
|
||||
field: field,
|
||||
resource: resource
|
||||
}
|
||||
|
||||
const githubError = new GithubError(error)
|
||||
const message = githubError.toString()
|
||||
|
||||
expect(message).toBe(`The ${field} field on ${resource} is an invalid format.`)
|
||||
})
|
||||
|
||||
it('generates resource already exists error message', () => {
|
||||
const resource = "release"
|
||||
const field = "body"
|
||||
const error = {
|
||||
code: "already_exists",
|
||||
resource: resource
|
||||
}
|
||||
|
||||
const githubError = new GithubError(error)
|
||||
const message = githubError.toString()
|
||||
|
||||
expect(message).toBe(`${resource} already exists.`)
|
||||
})
|
||||
|
||||
describe('generates custom error message', () => {
|
||||
it('with documentation url', () => {
|
||||
const url = "https://api.example.com"
|
||||
const error = {
|
||||
code: "custom",
|
||||
message: "foo",
|
||||
documentation_url: url
|
||||
}
|
||||
|
||||
it('does not have error', () => {
|
||||
const githubError = new GithubError(error)
|
||||
const message = githubError.toString()
|
||||
|
||||
expect(message).toBe(`foo\nPlease see ${url}.`)
|
||||
expect(githubError.hasErrorWithCode('missing_field')).toBeFalsy()
|
||||
})
|
||||
|
||||
it('without documentation url', () => {
|
||||
const error = {
|
||||
code: "custom",
|
||||
message: "foo"
|
||||
}
|
||||
|
||||
it('has error', () => {
|
||||
const githubError = new GithubError(error)
|
||||
const message = githubError.toString()
|
||||
|
||||
expect(message).toBe('foo')
|
||||
expect(githubError.hasErrorWithCode('missing')).toBeTruthy()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('generates message with errors', () => {
|
||||
const error = {
|
||||
message: 'something bad happened',
|
||||
errors: [
|
||||
{
|
||||
code: 'missing',
|
||||
resource: 'release'
|
||||
},
|
||||
{
|
||||
code: 'already_exists',
|
||||
resource: 'release'
|
||||
}
|
||||
],
|
||||
status: 422
|
||||
}
|
||||
|
||||
const githubError = new GithubError(error)
|
||||
|
||||
const expectedString = "Error 422: something bad happened\nErrors:\n- release does not exist.\n- release already exists."
|
||||
expect(githubError.toString()).toBe(expectedString)
|
||||
})
|
||||
|
||||
it('generates message without errors', () => {
|
||||
const error = {
|
||||
message: 'something bad happened',
|
||||
status: 422
|
||||
}
|
||||
|
||||
const githubError = new GithubError(error)
|
||||
|
||||
expect(githubError.toString()).toBe('Error 422: something bad happened')
|
||||
})
|
||||
|
||||
it('provides error status', () => {
|
||||
const error = { status: 404 }
|
||||
const githubError = new GithubError(error)
|
||||
expect(githubError.status).toBe(404)
|
||||
})
|
||||
})
|
||||
|
||||
98
__tests__/GithubErrorDetail.test.ts
Normal file
98
__tests__/GithubErrorDetail.test.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
import { GithubErrorDetail } from "../src/GithubErrorDetail"
|
||||
|
||||
describe('GithubErrorDetail', () => {
|
||||
|
||||
it('provides error code', () => {
|
||||
const error = {
|
||||
code: "missing"
|
||||
}
|
||||
|
||||
const detail = new GithubErrorDetail(error)
|
||||
|
||||
expect(detail.code).toBe('missing')
|
||||
})
|
||||
|
||||
it('generates missing resource error message', () => {
|
||||
const resource = "release"
|
||||
const error = {
|
||||
code: "missing",
|
||||
resource: resource
|
||||
}
|
||||
|
||||
const detail = new GithubErrorDetail(error)
|
||||
const message = detail.toString()
|
||||
|
||||
expect(message).toBe(`${resource} does not exist.`)
|
||||
})
|
||||
|
||||
it('generates missing field error message', () => {
|
||||
const resource = "release"
|
||||
const field = "body"
|
||||
const error = {
|
||||
code: "missing_field",
|
||||
field: field,
|
||||
resource: resource
|
||||
}
|
||||
|
||||
const detail = new GithubErrorDetail(error)
|
||||
const message = detail.toString()
|
||||
|
||||
expect(message).toBe(`The ${field} field on ${resource} is missing.`)
|
||||
})
|
||||
|
||||
it('generates invalid field error message', () => {
|
||||
const resource = "release"
|
||||
const field = "body"
|
||||
const error = {
|
||||
code: "invalid",
|
||||
field: field,
|
||||
resource: resource
|
||||
}
|
||||
|
||||
const detail = new GithubErrorDetail(error)
|
||||
const message = detail.toString()
|
||||
|
||||
expect(message).toBe(`The ${field} field on ${resource} is an invalid format.`)
|
||||
})
|
||||
|
||||
it('generates resource already exists error message', () => {
|
||||
const resource = "release"
|
||||
const error = {
|
||||
code: "already_exists",
|
||||
resource: resource
|
||||
}
|
||||
|
||||
const detail = new GithubErrorDetail(error)
|
||||
const message = detail.toString()
|
||||
|
||||
expect(message).toBe(`${resource} already exists.`)
|
||||
})
|
||||
|
||||
describe('generates custom error message', () => {
|
||||
it('with documentation url', () => {
|
||||
const url = "https://api.example.com"
|
||||
const error = {
|
||||
code: "custom",
|
||||
message: "foo",
|
||||
documentation_url: url
|
||||
}
|
||||
|
||||
const detail = new GithubErrorDetail(error)
|
||||
const message = detail.toString()
|
||||
|
||||
expect(message).toBe(`foo\nPlease see ${url}.`)
|
||||
})
|
||||
|
||||
it('without documentation url', () => {
|
||||
const error = {
|
||||
code: "custom",
|
||||
message: "foo"
|
||||
}
|
||||
|
||||
const detail = new GithubErrorDetail(error)
|
||||
const message = detail.toString()
|
||||
|
||||
expect(message).toBe('foo')
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -59,7 +59,28 @@ describe('Inputs', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('artifactErrorsFailBuild', () => {
|
||||
it('returns false', () => {
|
||||
expect(inputs.artifactErrorsFailBuild).toBe(false)
|
||||
})
|
||||
|
||||
it('returns true', () => {
|
||||
mockGetInput.mockReturnValue('true')
|
||||
expect(inputs.artifactErrorsFailBuild).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('artifacts', () => {
|
||||
it('globber told to throw errors', () => {
|
||||
mockGetInput.mockReturnValueOnce('art1')
|
||||
.mockReturnValueOnce('contentType')
|
||||
.mockReturnValueOnce('true')
|
||||
|
||||
expect(inputs.artifacts).toEqual(artifacts)
|
||||
expect(mockGlob).toBeCalledTimes(1)
|
||||
expect(mockGlob).toBeCalledWith('art1', 'contentType', true)
|
||||
})
|
||||
|
||||
it('returns empty artifacts', () => {
|
||||
mockGetInput.mockReturnValueOnce('')
|
||||
.mockReturnValueOnce('')
|
||||
@@ -71,28 +92,32 @@ describe('Inputs', () => {
|
||||
it('returns input.artifacts', () => {
|
||||
mockGetInput.mockReturnValueOnce('art1')
|
||||
.mockReturnValueOnce('contentType')
|
||||
.mockReturnValueOnce('false')
|
||||
|
||||
expect(inputs.artifacts).toEqual(artifacts)
|
||||
expect(mockGlob).toBeCalledTimes(1)
|
||||
expect(mockGlob).toBeCalledWith('art1', 'contentType')
|
||||
expect(mockGlob).toBeCalledWith('art1', 'contentType', false)
|
||||
})
|
||||
|
||||
it('returns input.artifacts with default contentType', () => {
|
||||
mockGetInput.mockReturnValueOnce('art1')
|
||||
.mockReturnValueOnce('raw')
|
||||
.mockReturnValueOnce('false')
|
||||
|
||||
expect(inputs.artifacts).toEqual(artifacts)
|
||||
expect(mockGlob).toBeCalledTimes(1)
|
||||
expect(mockGlob).toBeCalledWith('art1', 'raw')
|
||||
expect(mockGlob).toBeCalledWith('art1', 'raw', false)
|
||||
})
|
||||
|
||||
it('returns input.artifact', () => {
|
||||
mockGetInput.mockReturnValueOnce('')
|
||||
.mockReturnValueOnce('art2')
|
||||
.mockReturnValueOnce('contentType')
|
||||
.mockReturnValueOnce('false')
|
||||
|
||||
expect(inputs.artifacts).toEqual(artifacts)
|
||||
expect(mockGlob).toBeCalledTimes(1)
|
||||
expect(mockGlob).toBeCalledWith('art2', 'contentType')
|
||||
expect(mockGlob).toBeCalledWith('art2', 'contentType', false)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -154,6 +179,18 @@ describe('Inputs', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('discussionCategory', () => {
|
||||
it('returns category', () => {
|
||||
mockGetInput.mockReturnValue('Release')
|
||||
expect(inputs.discussionCategory).toBe('Release')
|
||||
})
|
||||
|
||||
it('returns undefined', () => {
|
||||
mockGetInput.mockReturnValue('')
|
||||
expect(inputs.discussionCategory).toBe(undefined)
|
||||
})
|
||||
})
|
||||
|
||||
describe('draft', () => {
|
||||
it('returns false', () => {
|
||||
expect(inputs.draft).toBe(false)
|
||||
@@ -164,7 +201,7 @@ describe('Inputs', () => {
|
||||
expect(inputs.draft).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
describe('owner', () => {
|
||||
it('returns owner from context', function () {
|
||||
process.env.GITHUB_REPOSITORY = "owner/repo"
|
||||
@@ -175,7 +212,7 @@ describe('Inputs', () => {
|
||||
mockGetInput.mockReturnValue("owner")
|
||||
expect(inputs.owner).toBe("owner")
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
describe('prerelase', () => {
|
||||
it('returns false', () => {
|
||||
|
||||
@@ -3,8 +3,8 @@ import * as github from "@actions/github";
|
||||
import {Inputs} from "../src/Inputs";
|
||||
import {GithubReleases} from "../src/Releases";
|
||||
import {GithubArtifactUploader} from "../src/ArtifactUploader";
|
||||
import {Artifact} from "../src/Artifact";
|
||||
import * as path from "path";
|
||||
import {FileArtifactGlobber} from "../src/ArtifactGlobber";
|
||||
|
||||
// This test is currently intended to be manually run during development. To run:
|
||||
// - Make sure you have an environment variable named GITHUB_TOKEN assigned to your token
|
||||
@@ -18,7 +18,11 @@ describe.skip('Integration Test', () => {
|
||||
|
||||
const inputs = getInputs()
|
||||
const releases = new GithubReleases(inputs, git)
|
||||
const uploader = new GithubArtifactUploader(releases, inputs.replacesArtifacts)
|
||||
const uploader = new GithubArtifactUploader(
|
||||
releases,
|
||||
inputs.replacesArtifacts,
|
||||
inputs.artifactErrorsFailBuild,
|
||||
)
|
||||
action = new Action(inputs, releases, uploader)
|
||||
})
|
||||
|
||||
@@ -27,29 +31,36 @@ describe.skip('Integration Test', () => {
|
||||
})
|
||||
|
||||
function getInputs(): Inputs {
|
||||
const artifactPath = path.join(__dirname, 'Integration.test.ts')
|
||||
// new
|
||||
const MockInputs = jest.fn<Inputs, any>(() => {
|
||||
return {
|
||||
allowUpdates: true,
|
||||
artifacts: [new Artifact(artifactPath)],
|
||||
createdReleaseBody: "release body",
|
||||
createdReleaseName: "release name",
|
||||
artifactErrorsFailBuild: false,
|
||||
artifacts: artifacts(),
|
||||
createdReleaseBody: "This release was generated by release-action's integration test",
|
||||
createdReleaseName: "Releases Action Integration Test 2",
|
||||
commit: "",
|
||||
discussionCategory: 'Release',
|
||||
draft: false,
|
||||
owner: "ncipollo",
|
||||
prerelease: true,
|
||||
prerelease: false,
|
||||
replacesArtifacts: true,
|
||||
repo: "actions-playground",
|
||||
tag: "0.0.71",
|
||||
tag: "release-action-test",
|
||||
token: getToken(),
|
||||
updatedReleaseBody: "updated body",
|
||||
updatedReleaseName: "updated name"
|
||||
updatedReleaseBody: "This release was generated by release-action's integration test",
|
||||
updatedReleaseName: "Releases Action Integration Test 2"
|
||||
}
|
||||
})
|
||||
return new MockInputs();
|
||||
}
|
||||
|
||||
function artifacts() {
|
||||
const globber = new FileArtifactGlobber()
|
||||
const artifactPath = path.join(__dirname, 'Integration.test.ts')
|
||||
const artifactString = `~/Desktop/test.txt,blarg.tx, ${artifactPath}`
|
||||
return globber.globArtifactString(artifactString, "raw", false)
|
||||
}
|
||||
|
||||
function getToken(): string {
|
||||
return process.env.GITHUB_TOKEN ?? ""
|
||||
}
|
||||
|
||||
@@ -6,6 +6,10 @@ inputs:
|
||||
description: 'An optional flag which indicates if we should update a release if it already exists. Defaults to false.'
|
||||
required: false
|
||||
default: ''
|
||||
artifactErrorsFailBuild:
|
||||
description: 'An optional flag which indicates if artifact read or upload errors should fail the build.'
|
||||
required: false
|
||||
default: ''
|
||||
artifact:
|
||||
deprecationMessage: Use 'artifacts' instead.
|
||||
description: 'An optional set of paths representing artifacts to upload to the release. This may be a single path or a comma delimited list of paths (or globs)'
|
||||
@@ -30,6 +34,10 @@ inputs:
|
||||
commit:
|
||||
description: "An optional commit reference. This will be used to create the tag if it does not exist."
|
||||
required: false
|
||||
default: ''
|
||||
discussionCategory:
|
||||
description: "When provided this will generate a discussion of the specified category. The category must exist otherwise this will cause the action to fail. This isn't used with draft releases"
|
||||
required: false
|
||||
default: ''
|
||||
draft:
|
||||
description: "Optionally marks this release as a draft release. Set to true to enable."
|
||||
|
||||
@@ -10,7 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Action = void 0;
|
||||
const ErrorMessage_1 = require("./ErrorMessage");
|
||||
const GithubError_1 = require("./GithubError");
|
||||
class Action {
|
||||
constructor(inputs, releases, uploader) {
|
||||
this.inputs = inputs;
|
||||
@@ -31,32 +31,38 @@ class Action {
|
||||
createOrUpdateRelease() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (this.inputs.allowUpdates) {
|
||||
let getResponse;
|
||||
try {
|
||||
const getResponse = yield this.releases.getByTag(this.inputs.tag);
|
||||
return yield this.updateRelease(getResponse.data.id);
|
||||
getResponse = yield this.releases.getByTag(this.inputs.tag);
|
||||
}
|
||||
catch (error) {
|
||||
if (Action.noPublishedRelease(error)) {
|
||||
return yield this.updateDraftOrCreateRelease();
|
||||
}
|
||||
else {
|
||||
throw error;
|
||||
}
|
||||
return yield this.checkForMissingReleaseError(error);
|
||||
}
|
||||
return yield this.updateRelease(getResponse.data.id);
|
||||
}
|
||||
else {
|
||||
return yield this.createRelease();
|
||||
}
|
||||
});
|
||||
}
|
||||
checkForMissingReleaseError(error) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (Action.noPublishedRelease(error)) {
|
||||
return yield this.updateDraftOrCreateRelease();
|
||||
}
|
||||
else {
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
}
|
||||
updateRelease(id) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
return yield this.releases.update(id, this.inputs.tag, this.inputs.updatedReleaseBody, this.inputs.commit, this.inputs.draft, this.inputs.updatedReleaseName, this.inputs.prerelease);
|
||||
return yield this.releases.update(id, this.inputs.tag, this.inputs.updatedReleaseBody, this.inputs.commit, this.inputs.discussionCategory, this.inputs.draft, this.inputs.updatedReleaseName, this.inputs.prerelease);
|
||||
});
|
||||
}
|
||||
static noPublishedRelease(error) {
|
||||
const errorMessage = new ErrorMessage_1.ErrorMessage(error);
|
||||
return errorMessage.status == 404;
|
||||
const githubError = new GithubError_1.GithubError(error);
|
||||
return githubError.status == 404;
|
||||
}
|
||||
updateDraftOrCreateRelease() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
@@ -80,8 +86,7 @@ class Action {
|
||||
}
|
||||
createRelease() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const response = yield this.releases.create(this.inputs.tag, this.inputs.createdReleaseBody, this.inputs.commit, this.inputs.draft, this.inputs.createdReleaseName, this.inputs.prerelease);
|
||||
return response;
|
||||
return yield this.releases.create(this.inputs.tag, this.inputs.createdReleaseBody, this.inputs.commit, this.inputs.discussionCategory, this.inputs.draft, this.inputs.createdReleaseName, this.inputs.prerelease);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,63 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||||
}) : (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 __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.FileArtifactGlobber = void 0;
|
||||
const core = __importStar(require("@actions/core"));
|
||||
const Globber_1 = require("./Globber");
|
||||
const Artifact_1 = require("./Artifact");
|
||||
const untildify_1 = __importDefault(require("untildify"));
|
||||
class FileArtifactGlobber {
|
||||
constructor(globber = new Globber_1.FileGlobber()) {
|
||||
this.globber = globber;
|
||||
}
|
||||
globArtifactString(artifact, contentType) {
|
||||
globArtifactString(artifact, contentType, throwsWhenNoFiles) {
|
||||
return artifact.split(',')
|
||||
.map((path) => this.globber.glob(path))
|
||||
.map(path => FileArtifactGlobber.expandPath(path))
|
||||
.map(pattern => this.globPattern(pattern, throwsWhenNoFiles))
|
||||
.reduce((accumulated, current) => accumulated.concat(current))
|
||||
.map((path) => new Artifact_1.Artifact(path, contentType));
|
||||
.map(path => new Artifact_1.Artifact(path, contentType));
|
||||
}
|
||||
globPattern(pattern, throwsWhenNoFiles) {
|
||||
const paths = this.globber.glob(pattern);
|
||||
if (paths.length == 0) {
|
||||
if (throwsWhenNoFiles) {
|
||||
FileArtifactGlobber.throwGlobError(pattern);
|
||||
}
|
||||
else {
|
||||
FileArtifactGlobber.reportGlobWarning(pattern);
|
||||
}
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
static reportGlobWarning(pattern) {
|
||||
core.warning(`Artifact pattern :${pattern} did not match any files`);
|
||||
}
|
||||
static throwGlobError(pattern) {
|
||||
throw Error(`Artifact pattern :${pattern} did not match any files`);
|
||||
}
|
||||
static expandPath(path) {
|
||||
return untildify_1.default(path);
|
||||
}
|
||||
}
|
||||
exports.FileArtifactGlobber = FileArtifactGlobber;
|
||||
|
||||
@@ -31,9 +31,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.GithubArtifactUploader = void 0;
|
||||
const core = __importStar(require("@actions/core"));
|
||||
class GithubArtifactUploader {
|
||||
constructor(releases, replacesExistingArtifacts = true) {
|
||||
constructor(releases, replacesExistingArtifacts = true, throwsUploadErrors = false) {
|
||||
this.releases = releases;
|
||||
this.replacesExistingArtifacts = replacesExistingArtifacts;
|
||||
this.throwsUploadErrors = throwsUploadErrors;
|
||||
}
|
||||
uploadArtifacts(artifacts, releaseId, uploadUrl) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
@@ -57,7 +58,12 @@ class GithubArtifactUploader {
|
||||
yield this.uploadArtifact(artifact, releaseId, uploadUrl, retry - 1);
|
||||
}
|
||||
else {
|
||||
core.warning(`Failed to upload artifact ${artifact.name}. ${error.message}.`);
|
||||
if (this.throwsUploadErrors) {
|
||||
throw Error(`Failed to upload artifact ${artifact.name}. ${error.message}.`);
|
||||
}
|
||||
else {
|
||||
core.warning(`Failed to upload artifact ${artifact.name}. ${error.message}.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ErrorMessage = void 0;
|
||||
const GithubError_1 = require("./GithubError");
|
||||
class ErrorMessage {
|
||||
constructor(error) {
|
||||
this.error = error;
|
||||
this.githubErrors = this.generateGithubErrors();
|
||||
}
|
||||
generateGithubErrors() {
|
||||
const errors = this.error.errors;
|
||||
if (errors instanceof Array) {
|
||||
return errors.map((err) => new GithubError_1.GithubError(err));
|
||||
}
|
||||
else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
get status() {
|
||||
return this.error.status;
|
||||
}
|
||||
hasErrorWithCode(code) {
|
||||
return this.githubErrors.some((err) => err.code == code);
|
||||
}
|
||||
toString() {
|
||||
const message = this.error.message;
|
||||
const errors = this.githubErrors;
|
||||
const status = this.status;
|
||||
if (errors.length > 0) {
|
||||
return `Error ${status}: ${message}\nErrors:\n${this.errorBulletedList(errors)}`;
|
||||
}
|
||||
else {
|
||||
return `Error ${status}: ${message}`;
|
||||
}
|
||||
}
|
||||
errorBulletedList(errors) {
|
||||
return errors.map((err) => `- ${err}`).join("\n");
|
||||
}
|
||||
}
|
||||
exports.ErrorMessage = ErrorMessage;
|
||||
@@ -1,57 +1,40 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.GithubError = void 0;
|
||||
const GithubErrorDetail_1 = require("./GithubErrorDetail");
|
||||
class GithubError {
|
||||
constructor(error) {
|
||||
this.error = error;
|
||||
this.githubErrors = this.generateGithubErrors();
|
||||
}
|
||||
get code() {
|
||||
return this.error.code;
|
||||
}
|
||||
toString() {
|
||||
const code = this.error.code;
|
||||
switch (code) {
|
||||
case 'missing':
|
||||
return this.missingResourceMessage();
|
||||
case 'missing_field':
|
||||
return this.missingFieldMessage();
|
||||
case 'invalid':
|
||||
return this.invalidFieldMessage();
|
||||
case 'already_exists':
|
||||
return this.resourceAlreadyExists();
|
||||
default:
|
||||
return this.customErrorMessage();
|
||||
}
|
||||
}
|
||||
customErrorMessage() {
|
||||
const message = this.error.message;
|
||||
const documentation = this.error.documentation_url;
|
||||
let documentationMessage;
|
||||
if (documentation) {
|
||||
documentationMessage = `\nPlease see ${documentation}.`;
|
||||
generateGithubErrors() {
|
||||
const errors = this.error.errors;
|
||||
if (errors instanceof Array) {
|
||||
return errors.map((err) => new GithubErrorDetail_1.GithubErrorDetail(err));
|
||||
}
|
||||
else {
|
||||
documentationMessage = "";
|
||||
return [];
|
||||
}
|
||||
return `${message}${documentationMessage}`;
|
||||
}
|
||||
invalidFieldMessage() {
|
||||
const resource = this.error.resource;
|
||||
const field = this.error.field;
|
||||
return `The ${field} field on ${resource} is an invalid format.`;
|
||||
get status() {
|
||||
return this.error.status;
|
||||
}
|
||||
missingResourceMessage() {
|
||||
const resource = this.error.resource;
|
||||
return `${resource} does not exist.`;
|
||||
hasErrorWithCode(code) {
|
||||
return this.githubErrors.some((err) => err.code == code);
|
||||
}
|
||||
missingFieldMessage() {
|
||||
const resource = this.error.resource;
|
||||
const field = this.error.field;
|
||||
return `The ${field} field on ${resource} is missing.`;
|
||||
toString() {
|
||||
const message = this.error.message;
|
||||
const errors = this.githubErrors;
|
||||
const status = this.status;
|
||||
if (errors.length > 0) {
|
||||
return `Error ${status}: ${message}\nErrors:\n${this.errorBulletedList(errors)}`;
|
||||
}
|
||||
else {
|
||||
return `Error ${status}: ${message}`;
|
||||
}
|
||||
}
|
||||
resourceAlreadyExists() {
|
||||
const resource = this.error.resource;
|
||||
return `${resource} already exists.`;
|
||||
errorBulletedList(errors) {
|
||||
return errors.map((err) => `- ${err}`).join("\n");
|
||||
}
|
||||
}
|
||||
exports.GithubError = GithubError;
|
||||
|
||||
57
lib/GithubErrorDetail.js
Normal file
57
lib/GithubErrorDetail.js
Normal file
@@ -0,0 +1,57 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.GithubErrorDetail = void 0;
|
||||
class GithubErrorDetail {
|
||||
constructor(error) {
|
||||
this.error = error;
|
||||
}
|
||||
get code() {
|
||||
return this.error.code;
|
||||
}
|
||||
toString() {
|
||||
const code = this.error.code;
|
||||
switch (code) {
|
||||
case 'missing':
|
||||
return this.missingResourceMessage();
|
||||
case 'missing_field':
|
||||
return this.missingFieldMessage();
|
||||
case 'invalid':
|
||||
return this.invalidFieldMessage();
|
||||
case 'already_exists':
|
||||
return this.resourceAlreadyExists();
|
||||
default:
|
||||
return this.customErrorMessage();
|
||||
}
|
||||
}
|
||||
customErrorMessage() {
|
||||
const message = this.error.message;
|
||||
const documentation = this.error.documentation_url;
|
||||
let documentationMessage;
|
||||
if (documentation) {
|
||||
documentationMessage = `\nPlease see ${documentation}.`;
|
||||
}
|
||||
else {
|
||||
documentationMessage = "";
|
||||
}
|
||||
return `${message}${documentationMessage}`;
|
||||
}
|
||||
invalidFieldMessage() {
|
||||
const resource = this.error.resource;
|
||||
const field = this.error.field;
|
||||
return `The ${field} field on ${resource} is an invalid format.`;
|
||||
}
|
||||
missingResourceMessage() {
|
||||
const resource = this.error.resource;
|
||||
return `${resource} does not exist.`;
|
||||
}
|
||||
missingFieldMessage() {
|
||||
const resource = this.error.resource;
|
||||
const field = this.error.field;
|
||||
return `The ${field} field on ${resource} is missing.`;
|
||||
}
|
||||
resourceAlreadyExists() {
|
||||
const resource = this.error.resource;
|
||||
return `${resource} already exists.`;
|
||||
}
|
||||
}
|
||||
exports.GithubErrorDetail = GithubErrorDetail;
|
||||
@@ -42,10 +42,14 @@ class CoreInputs {
|
||||
contentType = 'raw';
|
||||
}
|
||||
return this.artifactGlobber
|
||||
.globArtifactString(artifacts, contentType);
|
||||
.globArtifactString(artifacts, contentType, this.artifactErrorsFailBuild);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
get artifactErrorsFailBuild() {
|
||||
const allow = core.getInput('artifactErrorsFailBuild');
|
||||
return allow == 'true';
|
||||
}
|
||||
get createdReleaseBody() {
|
||||
if (CoreInputs.omitBody)
|
||||
return undefined;
|
||||
@@ -73,6 +77,13 @@ class CoreInputs {
|
||||
return undefined;
|
||||
return this.name;
|
||||
}
|
||||
get discussionCategory() {
|
||||
const category = core.getInput('discussionCategory');
|
||||
if (category) {
|
||||
return category;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
static get omitName() {
|
||||
return core.getInput('omitName') == 'true';
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ const Releases_1 = require("./Releases");
|
||||
const Action_1 = require("./Action");
|
||||
const ArtifactUploader_1 = require("./ArtifactUploader");
|
||||
const ArtifactGlobber_1 = require("./ArtifactGlobber");
|
||||
const ErrorMessage_1 = require("./ErrorMessage");
|
||||
const GithubError_1 = require("./GithubError");
|
||||
function run() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
@@ -43,8 +43,8 @@ function run() {
|
||||
yield action.perform();
|
||||
}
|
||||
catch (error) {
|
||||
const errorMessage = new ErrorMessage_1.ErrorMessage(error);
|
||||
core.setFailed(errorMessage.toString());
|
||||
const githubError = new GithubError_1.GithubError(error);
|
||||
core.setFailed(githubError.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -55,7 +55,7 @@ function createAction() {
|
||||
const globber = new ArtifactGlobber_1.FileArtifactGlobber();
|
||||
const inputs = new Inputs_1.CoreInputs(globber, context);
|
||||
const releases = new Releases_1.GithubReleases(inputs, git);
|
||||
const uploader = new ArtifactUploader_1.GithubArtifactUploader(releases, inputs.replacesArtifacts);
|
||||
const uploader = new ArtifactUploader_1.GithubArtifactUploader(releases, inputs.replacesArtifacts, inputs.artifactErrorsFailBuild);
|
||||
return new Action_1.Action(inputs, releases, uploader);
|
||||
}
|
||||
run();
|
||||
|
||||
@@ -15,12 +15,13 @@ class GithubReleases {
|
||||
this.inputs = inputs;
|
||||
this.git = git;
|
||||
}
|
||||
create(tag, body, commitHash, draft, name, prerelease) {
|
||||
create(tag, body, commitHash, discussionCategory, draft, name, prerelease) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
// noinspection TypeScriptValidateJSTypes
|
||||
return this.git.repos.createRelease({
|
||||
body: body,
|
||||
name: name,
|
||||
discussion_category_name: discussionCategory,
|
||||
draft: draft,
|
||||
owner: this.inputs.owner,
|
||||
prerelease: prerelease,
|
||||
@@ -65,13 +66,14 @@ class GithubReleases {
|
||||
});
|
||||
});
|
||||
}
|
||||
update(id, tag, body, commitHash, draft, name, prerelease) {
|
||||
update(id, tag, body, commitHash, discussionCategory, draft, name, prerelease) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
// noinspection TypeScriptValidateJSTypes
|
||||
return this.git.repos.updateRelease({
|
||||
release_id: id,
|
||||
body: body,
|
||||
name: name,
|
||||
discussion_category_name: discussionCategory,
|
||||
draft: draft,
|
||||
owner: this.inputs.owner,
|
||||
prerelease: prerelease,
|
||||
|
||||
11
node_modules/.yarn-integrity
generated
vendored
11
node_modules/.yarn-integrity
generated
vendored
@@ -13,13 +13,12 @@
|
||||
"@types/glob@^7.1.3",
|
||||
"@types/jest@^26.0.20",
|
||||
"@types/node@^14.14.25",
|
||||
"add@^2.0.6",
|
||||
"glob@^7.1.4",
|
||||
"global@^4.4.0",
|
||||
"jest-circus@^26.6.3",
|
||||
"jest@^26.1.0",
|
||||
"ts-jest@^26.5.1",
|
||||
"typescript@^4.1.4"
|
||||
"typescript@^4.1.4",
|
||||
"untildify@^4.0.0"
|
||||
],
|
||||
"lockfileEntries": {
|
||||
"@actions/core@^1.2.6": "https://registry.yarnpkg.com/@actions/core/-/core-1.2.6.tgz#a78d49f41a4def18e88ce47c2cac615d5694bf09",
|
||||
@@ -128,7 +127,6 @@
|
||||
"acorn-globals@^6.0.0": "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45",
|
||||
"acorn-walk@^7.1.1": "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc",
|
||||
"acorn@^7.1.1": "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa",
|
||||
"add@^2.0.6": "https://registry.yarnpkg.com/add/-/add-2.0.6.tgz#248f0a9f6e5a528ef2295dbeec30532130ae2235",
|
||||
"ajv@^6.12.3": "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4",
|
||||
"ansi-escapes@^4.2.1": "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.1.tgz#a5c47cc43181f1f38ffd7076837700d395522a61",
|
||||
"ansi-regex@^5.0.0": "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75",
|
||||
@@ -222,7 +220,6 @@
|
||||
"deprecation@^2.3.1": "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919",
|
||||
"detect-newline@^3.0.0": "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651",
|
||||
"diff-sequences@^26.6.2": "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1",
|
||||
"dom-walk@^0.1.0": "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84",
|
||||
"domexception@^2.0.1": "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304",
|
||||
"ecc-jsbn@~0.1.1": "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9",
|
||||
"emittery@^0.7.1": "https://registry.yarnpkg.com/emittery/-/emittery-0.7.2.tgz#25595908e13af0f5674ab419396e2fb394cdfa82",
|
||||
@@ -277,7 +274,6 @@
|
||||
"glob@^7.1.2": "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6",
|
||||
"glob@^7.1.3": "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6",
|
||||
"glob@^7.1.4": "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6",
|
||||
"global@^4.4.0": "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406",
|
||||
"globals@^11.1.0": "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e",
|
||||
"graceful-fs@^4.2.4": "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee",
|
||||
"growly@^1.3.0": "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081",
|
||||
@@ -413,7 +409,6 @@
|
||||
"mime-types@^2.1.12": "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.28.tgz#1160c4757eab2c5363888e005273ecf79d2a0ecd",
|
||||
"mime-types@~2.1.19": "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.28.tgz#1160c4757eab2c5363888e005273ecf79d2a0ecd",
|
||||
"mimic-fn@^2.1.0": "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b",
|
||||
"min-document@^2.19.0": "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685",
|
||||
"minimatch@^3.0.4": "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083",
|
||||
"minimist@^1.1.1": "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602",
|
||||
"minimist@^1.2.0": "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602",
|
||||
@@ -468,7 +463,6 @@
|
||||
"prelude-ls@~1.1.2": "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54",
|
||||
"pretty-format@^26.0.0": "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93",
|
||||
"pretty-format@^26.6.2": "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93",
|
||||
"process@^0.11.10": "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182",
|
||||
"prompts@^2.0.1": "https://registry.yarnpkg.com/prompts/-/prompts-2.4.0.tgz#4aa5de0723a231d1ee9121c40fdf663df73f61d7",
|
||||
"psl@^1.1.28": "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24",
|
||||
"pump@^3.0.0": "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64",
|
||||
@@ -589,6 +583,7 @@
|
||||
"union-value@^1.0.0": "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847",
|
||||
"universal-user-agent@^6.0.0": "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee",
|
||||
"unset-value@^1.0.0": "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559",
|
||||
"untildify@^4.0.0": "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b",
|
||||
"uri-js@^4.2.2": "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e",
|
||||
"urix@^0.1.0": "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72",
|
||||
"use@^3.1.0": "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f",
|
||||
|
||||
2
node_modules/add/.npmignore
generated
vendored
2
node_modules/add/.npmignore
generated
vendored
@@ -1,2 +0,0 @@
|
||||
node_modules
|
||||
|
||||
7
node_modules/add/.travis.yml
generated
vendored
7
node_modules/add/.travis.yml
generated
vendored
@@ -1,7 +0,0 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.11"
|
||||
- "0.10"
|
||||
- "0.8"
|
||||
- "0.6"
|
||||
|
||||
47
node_modules/add/Readme.md
generated
vendored
47
node_modules/add/Readme.md
generated
vendored
@@ -1,47 +0,0 @@
|
||||
# Add
|
||||
|
||||
[](https://travis-ci.org/ben-ng/add)
|
||||
|
||||
[
|
||||
](https://ci.testling.com/ben-ng/add)
|
||||
|
||||
A cross-browser, numerically stable way to add floats in Javascript. Produces a faithful rounding of the sum (the result is an immediate floating-point neighbor of the true value).
|
||||
|
||||
Algorithm: Rump-Ogita-Oishi
|
||||
|
||||
## Usage
|
||||
|
||||
```javascript
|
||||
var add = require('add')
|
||||
, evil = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7]
|
||||
, dumbsum = function (a,b) { return a+b }
|
||||
|
||||
console.log(evil.reduce(dumbsum)) => 15.299999999999999
|
||||
|
||||
console.log(add(evil)) => 15.3
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Ben Ng
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
36
node_modules/add/bower.json
generated
vendored
36
node_modules/add/bower.json
generated
vendored
@@ -1,36 +0,0 @@
|
||||
{
|
||||
"name": "add",
|
||||
"main": "index.js",
|
||||
"version": "2.0.5",
|
||||
"homepage": "https://github.com/ben-ng/add",
|
||||
"authors": [
|
||||
"Ben Ng <me@benng.me>"
|
||||
],
|
||||
"description": "A cross-browser, numerically stable algorithm to add floats accurately",
|
||||
"moduleType": [
|
||||
"amd",
|
||||
"globals",
|
||||
"node"
|
||||
],
|
||||
"keywords": [
|
||||
"numerical",
|
||||
"stable",
|
||||
"faithful",
|
||||
"rounding",
|
||||
"float",
|
||||
"error",
|
||||
"propagation",
|
||||
"summation",
|
||||
"accumulate",
|
||||
"addition",
|
||||
"numerical",
|
||||
"analysis"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test.js"
|
||||
]
|
||||
}
|
||||
177
node_modules/add/index.js
generated
vendored
177
node_modules/add/index.js
generated
vendored
@@ -1,177 +0,0 @@
|
||||
(function (root, factory) {
|
||||
"use strict";
|
||||
|
||||
// AMD
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define([], factory);
|
||||
}
|
||||
// CommonJS
|
||||
else if (typeof exports === 'object') {
|
||||
module.exports = factory();
|
||||
}
|
||||
// Browser
|
||||
else {
|
||||
root.add = factory();
|
||||
}
|
||||
})(this, function () {
|
||||
"use strict";
|
||||
|
||||
// The minimum machine rounding error
|
||||
var Epsilon = Math.pow(2, -53)
|
||||
, EpsilonReciprocal = (1 / Epsilon)
|
||||
/// The smallest positive number that can be represented
|
||||
, Eta = Math.pow(2, -1074)
|
||||
// limitB is a constant used in the transform function
|
||||
, limitB = 0.5 * EpsilonReciprocal * Eta
|
||||
|
||||
/**
|
||||
* S. M. RUMP, T. OGITA AND S. OISHI
|
||||
* http://www.ti3.tu-harburg.de/paper/rump/RuOgOi07I.pdf
|
||||
*/
|
||||
|
||||
// Page 8
|
||||
// x is result, y is error
|
||||
// third is so the array is allocated for 4 spaces
|
||||
// it speeds up transform
|
||||
function fastTwoSum(a, b) {
|
||||
var x = a + b
|
||||
, q = x - a
|
||||
, y = b - q
|
||||
|
||||
return [x, y, null]
|
||||
}
|
||||
|
||||
// Page 12
|
||||
// p = q + p'
|
||||
// sigma is a power of 2 greater than or equal to |p|
|
||||
function extractScalar(sigma, p) {
|
||||
var q = (sigma + p) - sigma
|
||||
, pPrime = p - q
|
||||
|
||||
return [q, pPrime]
|
||||
}
|
||||
|
||||
// Page 12
|
||||
function extractVector(sigma, p) {
|
||||
var tau = 0.0
|
||||
, extracted
|
||||
, i = 0
|
||||
, ii = p.length
|
||||
, pPrime = new Array(ii)
|
||||
|
||||
for(; i<ii; ++i) {
|
||||
extracted = extractScalar(sigma, p[i])
|
||||
pPrime[i] = extracted[1]
|
||||
tau += extracted[0]
|
||||
}
|
||||
|
||||
return [tau, pPrime]
|
||||
}
|
||||
|
||||
// Finds the immediate power of 2 that is larger than p
|
||||
//// in a fast way
|
||||
function nextPowerTwo (p) {
|
||||
var q = EpsilonReciprocal * p
|
||||
, L = Math.abs((q + p) - q)
|
||||
|
||||
if(L === 0)
|
||||
return Math.abs(p)
|
||||
|
||||
return L
|
||||
}
|
||||
|
||||
// Helper, gets the maximum of the absolute values of an array
|
||||
function maxAbs(arr) {
|
||||
var i = 0
|
||||
, ii = arr.length
|
||||
, best = -1
|
||||
|
||||
for(; i<ii; ++i) {
|
||||
if(Math.abs(arr[i]) > best) {
|
||||
best = arr[i]
|
||||
}
|
||||
}
|
||||
|
||||
return best
|
||||
}
|
||||
|
||||
function transform (p) {
|
||||
var mu = maxAbs(p)
|
||||
, M
|
||||
, sigmaPrime
|
||||
, tPrime
|
||||
, t
|
||||
, tau
|
||||
, sigma
|
||||
, extracted
|
||||
, res
|
||||
|
||||
// Not part of the original paper, here for optimization
|
||||
, temp
|
||||
, bigPow
|
||||
, limitA
|
||||
, twoToTheM
|
||||
|
||||
if(mu === 0) {
|
||||
return [0, 0, p, 0]
|
||||
}
|
||||
|
||||
M = nextPowerTwo(p.length + 2)
|
||||
twoToTheM = Math.pow(2, M)
|
||||
bigPow = 2 * twoToTheM // equiv to Math.pow(2, 2 * M), faster
|
||||
sigmaPrime = twoToTheM * nextPowerTwo(mu)
|
||||
tPrime = 0
|
||||
|
||||
do {
|
||||
t = tPrime
|
||||
sigma = sigmaPrime
|
||||
extracted = extractVector(sigma, p)
|
||||
tau = extracted[0]
|
||||
tPrime = t + tau
|
||||
p = extracted[1]
|
||||
|
||||
if(tPrime === 0) {
|
||||
return transform(p)
|
||||
}
|
||||
|
||||
temp = Epsilon * sigma
|
||||
sigmaPrime = twoToTheM * temp
|
||||
limitA = bigPow * temp
|
||||
}
|
||||
while( Math.abs(tPrime) < limitA && sigma > limitB )
|
||||
|
||||
// res already allocated for 4
|
||||
res = fastTwoSum(t, tau)
|
||||
res[2] = p
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
function dumbSum(p) {
|
||||
var i, ii, sum = 0.0
|
||||
for(i=0, ii=p.length; i<ii; ++i) {
|
||||
sum += p[i]
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
function accSum(p) {
|
||||
|
||||
// Zero length array, or all values are zeros
|
||||
if(p.length === 0 || maxAbs(p) === 0) {
|
||||
return 0
|
||||
}
|
||||
|
||||
var tfmd = transform(p)
|
||||
|
||||
return tfmd[0] + (tfmd[1] +dumbSum(tfmd[2]))
|
||||
}
|
||||
|
||||
|
||||
// exports
|
||||
accSum.dumbSum = dumbSum;
|
||||
accSum.fastTwoSum = fastTwoSum;
|
||||
accSum.nextPowerTwo = nextPowerTwo;
|
||||
return accSum;
|
||||
});
|
||||
|
||||
48
node_modules/add/package.json
generated
vendored
48
node_modules/add/package.json
generated
vendored
@@ -1,48 +0,0 @@
|
||||
{
|
||||
"name": "add",
|
||||
"version": "2.0.6",
|
||||
"description": "A cross-browser, numerically stable algorithm to add floats accurately",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "node test.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ben-ng/add.git"
|
||||
},
|
||||
"keywords": [
|
||||
"numerically",
|
||||
"stable",
|
||||
"faithful",
|
||||
"rounding",
|
||||
"float",
|
||||
"error",
|
||||
"propagation",
|
||||
"summation",
|
||||
"accumulate",
|
||||
"addition",
|
||||
"numerical",
|
||||
"analysis"
|
||||
],
|
||||
"devDependencies": {
|
||||
"tape": "2.x.x"
|
||||
},
|
||||
"testling": {
|
||||
"files": "test.js",
|
||||
"browsers": [
|
||||
"ie/6..latest",
|
||||
"chrome/22..latest",
|
||||
"firefox/16..latest",
|
||||
"safari/latest",
|
||||
"opera/11.0..latest",
|
||||
"iphone/6",
|
||||
"ipad/6"
|
||||
]
|
||||
},
|
||||
"author": "Ben Ng <me@benng.me>",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/ben-ng/add/issues"
|
||||
},
|
||||
"homepage": "https://github.com/ben-ng/add"
|
||||
}
|
||||
41
node_modules/add/test.js
generated
vendored
41
node_modules/add/test.js
generated
vendored
@@ -1,41 +0,0 @@
|
||||
/**
|
||||
* Tests for numeric stability
|
||||
*/
|
||||
var algorithm = require('./')
|
||||
, test = require('tape')
|
||||
, badVector
|
||||
|
||||
badVector = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7]
|
||||
|
||||
test('fastSum', function (t) {
|
||||
t.plan(1);
|
||||
|
||||
t.deepEqual(algorithm.fastTwoSum(1/3, 1/6)
|
||||
, [0.5, -2.7755575615628914e-17, null]
|
||||
, 'Result and error should have been returned')
|
||||
});
|
||||
|
||||
test('nextPowerTwo', function (t) {
|
||||
t.plan(1)
|
||||
|
||||
t.equal(algorithm.nextPowerTwo(1534)
|
||||
, 2048
|
||||
, 'Should be Math.pow(2, Math.ceil(algorithm.logBase2(Math.abs(1534))))')
|
||||
})
|
||||
|
||||
test('accumulate', function (t) {
|
||||
t.plan(5)
|
||||
|
||||
|
||||
t.equal(algorithm([1,2,3,4]), 10, 'Integer sum should work')
|
||||
|
||||
|
||||
t.equal(algorithm.dumbSum(badVector), 15.299999999999999, 'Inaccurate summation using naive method')
|
||||
|
||||
t.equal(algorithm(badVector), 15.3, 'Rump-Ogita-Oishi summation of insidious sum')
|
||||
|
||||
t.equal(algorithm([0, 0, 0]), 0, 'Rump-Ogita-Oishi summation of zero array')
|
||||
|
||||
t.equal(algorithm([]), 0, 'Rump-Ogita-Oishi summation of empty array')
|
||||
})
|
||||
|
||||
19
node_modules/dom-walk/LICENCE
generated
vendored
19
node_modules/dom-walk/LICENCE
generated
vendored
@@ -1,19 +0,0 @@
|
||||
Copyright (c) 2012 Raynos.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
2
node_modules/dom-walk/Makefile
generated
vendored
2
node_modules/dom-walk/Makefile
generated
vendored
@@ -1,2 +0,0 @@
|
||||
run:
|
||||
./node_modules/.bin/browserify-server --cwd example
|
||||
23
node_modules/dom-walk/README.md
generated
vendored
23
node_modules/dom-walk/README.md
generated
vendored
@@ -1,23 +0,0 @@
|
||||
# dom-walk
|
||||
|
||||
iteratively walk a DOM node
|
||||
|
||||
## Example
|
||||
|
||||
``` js
|
||||
var walk = require("dom-walk")
|
||||
|
||||
walk(document.body.childNodes, function (node) {
|
||||
console.log("node", node)
|
||||
})
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
`npm install dom-walk`
|
||||
|
||||
## Contributors
|
||||
|
||||
- Raynos
|
||||
|
||||
## MIT Licenced
|
||||
5
node_modules/dom-walk/example/index.js
generated
vendored
5
node_modules/dom-walk/example/index.js
generated
vendored
@@ -1,5 +0,0 @@
|
||||
var walk = require("../index")
|
||||
|
||||
walk(document, function (node) {
|
||||
console.log("node", node)
|
||||
})
|
||||
24
node_modules/dom-walk/index.js
generated
vendored
24
node_modules/dom-walk/index.js
generated
vendored
@@ -1,24 +0,0 @@
|
||||
var slice = Array.prototype.slice
|
||||
|
||||
module.exports = iterativelyWalk
|
||||
|
||||
function iterativelyWalk(nodes, cb) {
|
||||
if (!('length' in nodes)) {
|
||||
nodes = [nodes]
|
||||
}
|
||||
|
||||
nodes = slice.call(nodes)
|
||||
|
||||
while(nodes.length) {
|
||||
var node = nodes.shift(),
|
||||
ret = cb(node)
|
||||
|
||||
if (ret) {
|
||||
return ret
|
||||
}
|
||||
|
||||
if (node.childNodes && node.childNodes.length) {
|
||||
nodes = slice.call(node.childNodes).concat(nodes)
|
||||
}
|
||||
}
|
||||
}
|
||||
32
node_modules/dom-walk/package.json
generated
vendored
32
node_modules/dom-walk/package.json
generated
vendored
@@ -1,32 +0,0 @@
|
||||
{
|
||||
"name": "dom-walk",
|
||||
"version": "0.1.2",
|
||||
"description": "iteratively walk a DOM node",
|
||||
"keywords": [],
|
||||
"author": "Raynos <raynos2@gmail.com>",
|
||||
"repository": "git://github.com/Raynos/dom-walk.git",
|
||||
"main": "index",
|
||||
"homepage": "https://github.com/Raynos/dom-walk",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Jake Verbaten"
|
||||
}
|
||||
],
|
||||
"bugs": {
|
||||
"url": "https://github.com/Raynos/dom-walk/issues",
|
||||
"email": "raynos2@gmail.com"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"budo": "11.6.3"
|
||||
},
|
||||
"licenses": [
|
||||
{
|
||||
"type": "MIT",
|
||||
"url": "http://github.com/Raynos/dom-walk/raw/master/LICENSE"
|
||||
}
|
||||
],
|
||||
"scripts": {
|
||||
"example": "budo example/index.js"
|
||||
}
|
||||
}
|
||||
4
node_modules/global/.travis.yml
generated
vendored
4
node_modules/global/.travis.yml
generated
vendored
@@ -1,4 +0,0 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 0.8
|
||||
- 0.9
|
||||
19
node_modules/global/LICENSE
generated
vendored
19
node_modules/global/LICENSE
generated
vendored
@@ -1,19 +0,0 @@
|
||||
Copyright (c) 2012 Colingo.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
30
node_modules/global/README.md
generated
vendored
30
node_modules/global/README.md
generated
vendored
@@ -1,30 +0,0 @@
|
||||
# global
|
||||
|
||||
<!-- [![build status][1]][2]
|
||||
|
||||
[![browser support][3]][4] -->
|
||||
|
||||
Require global variables
|
||||
|
||||
## Example
|
||||
|
||||
```js
|
||||
var global = require("global")
|
||||
var document = require("global/document")
|
||||
var window = require("global/window")
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
`npm install global`
|
||||
|
||||
## Contributors
|
||||
|
||||
- Raynos
|
||||
|
||||
## MIT Licenced
|
||||
|
||||
[1]: https://secure.travis-ci.org/Colingo/global.png
|
||||
[2]: http://travis-ci.org/Colingo/global
|
||||
[3]: http://ci.testling.com/Colingo/global.png
|
||||
[4]: http://ci.testling.com/Colingo/global
|
||||
1
node_modules/global/console.js
generated
vendored
1
node_modules/global/console.js
generated
vendored
@@ -1 +0,0 @@
|
||||
module.exports = console;
|
||||
17
node_modules/global/document.js
generated
vendored
17
node_modules/global/document.js
generated
vendored
@@ -1,17 +0,0 @@
|
||||
var topLevel = typeof global !== 'undefined' ? global :
|
||||
typeof window !== 'undefined' ? window : {}
|
||||
var minDoc = require('min-document');
|
||||
|
||||
var doccy;
|
||||
|
||||
if (typeof document !== 'undefined') {
|
||||
doccy = document;
|
||||
} else {
|
||||
doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'];
|
||||
|
||||
if (!doccy) {
|
||||
doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'] = minDoc;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = doccy;
|
||||
63
node_modules/global/package.json
generated
vendored
63
node_modules/global/package.json
generated
vendored
@@ -1,63 +0,0 @@
|
||||
{
|
||||
"name": "global",
|
||||
"version": "4.4.0",
|
||||
"description": "Require global variables",
|
||||
"keywords": [],
|
||||
"author": "Raynos <raynos2@gmail.com>",
|
||||
"repository": "git://github.com/Raynos/global.git",
|
||||
"main": "window.js",
|
||||
"homepage": "https://github.com/Raynos/global",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Raynos"
|
||||
}
|
||||
],
|
||||
"bugs": {
|
||||
"url": "https://github.com/Raynos/global/issues",
|
||||
"email": "raynos2@gmail.com"
|
||||
},
|
||||
"browser": {
|
||||
"min-document": false,
|
||||
"individual": false
|
||||
},
|
||||
"dependencies": {
|
||||
"min-document": "^2.19.0",
|
||||
"process": "^0.11.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tape": "^2.12.0"
|
||||
},
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"test": "node ./test",
|
||||
"build": "browserify test/index.js -o test/static/bundle.js",
|
||||
"testem": "testem"
|
||||
},
|
||||
"testling": {
|
||||
"files": "test/index.js",
|
||||
"browsers": {
|
||||
"ie": [
|
||||
"8",
|
||||
"9",
|
||||
"10"
|
||||
],
|
||||
"firefox": [
|
||||
"16",
|
||||
"17",
|
||||
"nightly"
|
||||
],
|
||||
"chrome": [
|
||||
"22",
|
||||
"23",
|
||||
"canary"
|
||||
],
|
||||
"opera": [
|
||||
"12",
|
||||
"next"
|
||||
],
|
||||
"safari": [
|
||||
"5.1"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
1
node_modules/global/process.js
generated
vendored
1
node_modules/global/process.js
generated
vendored
@@ -1 +0,0 @@
|
||||
module.exports = require('process');
|
||||
13
node_modules/global/window.js
generated
vendored
13
node_modules/global/window.js
generated
vendored
@@ -1,13 +0,0 @@
|
||||
var win;
|
||||
|
||||
if (typeof window !== "undefined") {
|
||||
win = window;
|
||||
} else if (typeof global !== "undefined") {
|
||||
win = global;
|
||||
} else if (typeof self !== "undefined"){
|
||||
win = self;
|
||||
} else {
|
||||
win = {};
|
||||
}
|
||||
|
||||
module.exports = win;
|
||||
30
node_modules/min-document/.jshintrc
generated
vendored
30
node_modules/min-document/.jshintrc
generated
vendored
@@ -1,30 +0,0 @@
|
||||
{
|
||||
"maxdepth": 4,
|
||||
"maxstatements": 200,
|
||||
"maxcomplexity": 12,
|
||||
"maxlen": 80,
|
||||
"maxparams": 5,
|
||||
|
||||
"curly": true,
|
||||
"eqeqeq": true,
|
||||
"immed": true,
|
||||
"latedef": false,
|
||||
"noarg": true,
|
||||
"noempty": true,
|
||||
"nonew": true,
|
||||
"undef": true,
|
||||
"unused": "vars",
|
||||
"trailing": true,
|
||||
|
||||
"quotmark": true,
|
||||
"expr": true,
|
||||
"asi": true,
|
||||
|
||||
"browser": false,
|
||||
"esnext": true,
|
||||
"devel": false,
|
||||
"node": false,
|
||||
"nonstandard": false,
|
||||
|
||||
"predef": ["require", "module", "__dirname", "__filename"]
|
||||
}
|
||||
15
node_modules/min-document/.npmignore
generated
vendored
15
node_modules/min-document/.npmignore
generated
vendored
@@ -1,15 +0,0 @@
|
||||
.DS_Store
|
||||
.monitor
|
||||
.*.swp
|
||||
.nodemonignore
|
||||
releases
|
||||
*.log
|
||||
*.err
|
||||
fleet.json
|
||||
public/browserify
|
||||
bin/*.json
|
||||
.bin
|
||||
build
|
||||
compile
|
||||
.lock-wscript
|
||||
node_modules
|
||||
14
node_modules/min-document/.testem.json
generated
vendored
14
node_modules/min-document/.testem.json
generated
vendored
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"launchers": {
|
||||
"node": {
|
||||
"command": "node ./test"
|
||||
}
|
||||
},
|
||||
"src_files": [
|
||||
"./**/*.js"
|
||||
],
|
||||
"before_tests": "npm run build-test",
|
||||
"on_exit": "rm test/static/bundle.js",
|
||||
"test_page": "test/static/index.html",
|
||||
"launch_in_dev": ["node", "phantomjs"]
|
||||
}
|
||||
6
node_modules/min-document/.travis.yml
generated
vendored
6
node_modules/min-document/.travis.yml
generated
vendored
@@ -1,6 +0,0 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 0.8
|
||||
- 0.9
|
||||
- 0.10
|
||||
script: node ./test/index.js
|
||||
48
node_modules/min-document/CONTRIBUTION.md
generated
vendored
48
node_modules/min-document/CONTRIBUTION.md
generated
vendored
@@ -1,48 +0,0 @@
|
||||
# This is an OPEN Open Source Project
|
||||
|
||||
## What?
|
||||
|
||||
Individuals making significant and valuable contributions are given commit-access to the project to contribute as they see fit. This project is more like an open wiki than a standard guarded open source project.
|
||||
|
||||
## Rules
|
||||
|
||||
There are a few basic ground-rules for contributors:
|
||||
|
||||
- No --force pushes or modifying the Git history in any way.
|
||||
- Non-master branches ought to be used for ongoing work.
|
||||
- External API changes and significant modifications ought to be subject to an internal pull-request to solicit feedback from other contributors.
|
||||
- Internal pull-requests to solicit feedback are encouraged for any other non-trivial contribution but left to the discretion of the contributor.
|
||||
- For significant changes wait a full 24 hours before merging so that active contributors who are distributed throughout the world have a chance to weigh in.
|
||||
- Contributors should attempt to adhere to the prevailing code-style.
|
||||
Releases
|
||||
|
||||
Declaring formal releases requires peer review.
|
||||
|
||||
- A reviewer of a pull request should recommend a new version number (patch, minor or major).
|
||||
- Once your change is merged feel free to bump the version as recommended by the reviewer.
|
||||
- A new version number should not be cut without peer review unless done by the project maintainer.
|
||||
|
||||
## Want to contribute?
|
||||
|
||||
Even though collaborators may contribute as they see fit, if you are not sure what to do, here's a suggested process:
|
||||
|
||||
## Cutting a new version
|
||||
|
||||
- Get your branch merged on master
|
||||
- Run `npm version major` or `npm version minor` or `npm version patch`
|
||||
- `git push origin master --tags`
|
||||
- If you are a project owner, then `npm publish`
|
||||
|
||||
## If you want to have a bug fixed or a feature added:
|
||||
|
||||
- Check open issues for what you want.
|
||||
- If there is an open issue, comment on it, otherwise open an issue describing your bug or feature with use cases.
|
||||
- Discussion happens on the issue about how to solve your problem.
|
||||
- You or a core contributor opens a pull request solving the issue with tests and documentation.
|
||||
- The pull requests gets reviewed and then merged.
|
||||
- A new release version get's cut.
|
||||
- (Disclaimer: Your feature might get rejected.)
|
||||
|
||||
### Changes to this arrangement
|
||||
|
||||
This is an experiment and feedback is welcome! This document may also be subject to pull-requests or changes by contributors where you believe you have something valuable to add or change.
|
||||
19
node_modules/min-document/LICENCE
generated
vendored
19
node_modules/min-document/LICENCE
generated
vendored
@@ -1,19 +0,0 @@
|
||||
Copyright (c) 2013 Colingo.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
43
node_modules/min-document/README.md
generated
vendored
43
node_modules/min-document/README.md
generated
vendored
@@ -1,43 +0,0 @@
|
||||
# min-document
|
||||
|
||||
[![build status][1]][2] [![dependency status][3]][4]
|
||||
|
||||
<!-- [![browser support][5]][6] -->
|
||||
|
||||
A minimal DOM implementation
|
||||
|
||||
## Example
|
||||
|
||||
```js
|
||||
var document = require("min-document")
|
||||
|
||||
var div = document.createElement("div")
|
||||
div.className = "foo bar"
|
||||
|
||||
var span = document.createElement("span")
|
||||
div.appendChild(span)
|
||||
span.textContent = "Hello!"
|
||||
|
||||
/* <div class="foo bar">
|
||||
<span>Hello!</span>
|
||||
</div>
|
||||
*/
|
||||
var html = String(div)
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
`npm install min-document`
|
||||
|
||||
## Contributors
|
||||
|
||||
- Raynos
|
||||
|
||||
## MIT Licenced
|
||||
|
||||
[1]: https://secure.travis-ci.org/Raynos/min-document.png
|
||||
[2]: https://travis-ci.org/Raynos/min-document
|
||||
[3]: https://david-dm.org/Raynos/min-document.png
|
||||
[4]: https://david-dm.org/Raynos/min-document
|
||||
[5]: https://ci.testling.com/Raynos/min-document.png
|
||||
[6]: https://ci.testling.com/Raynos/min-document
|
||||
156
node_modules/min-document/docs.mli
generated
vendored
156
node_modules/min-document/docs.mli
generated
vendored
@@ -1,156 +0,0 @@
|
||||
type Comment := {
|
||||
data: String,
|
||||
length: Number,
|
||||
nodeName: "#comment",
|
||||
nodeType: 8,
|
||||
nodeValue: String,
|
||||
ownerDoucment: null | Document,
|
||||
|
||||
toString: (this: Comment) => String
|
||||
}
|
||||
|
||||
type DOMText := {
|
||||
data: String,
|
||||
type: "DOMTextNode",
|
||||
length: Number,
|
||||
nodeType: 3,
|
||||
|
||||
toString: (this: DOMText) => String,
|
||||
replaceChild: (
|
||||
this: DOMText,
|
||||
index: Number,
|
||||
length: Number,
|
||||
value: String
|
||||
) => void
|
||||
}
|
||||
|
||||
type DOMNode := DOMText | DOMElement | DocumentFragment
|
||||
type DOMChild := DOMText | DOMElement
|
||||
|
||||
type DOMElement := {
|
||||
tagName: String,
|
||||
className: String,
|
||||
dataset: Object<String, Any>,
|
||||
childNodes: Array<DOMChild>,
|
||||
parentNode: null | DOMElement,
|
||||
style: Object<String, String>,
|
||||
type: "DOMElement",
|
||||
nodeType: 1,
|
||||
ownerDoucment: null | Document,
|
||||
namespaceURI: null | String,
|
||||
|
||||
appendChild: (this: DOMElement, child: DOMChild) => DOMChild,
|
||||
replaceChild:(
|
||||
this: DOMElement,
|
||||
elem: DOMChild,
|
||||
needle: DOMChild
|
||||
) => DOMChild,
|
||||
removeChild: (this: DOMElement, child: DOMChild) => DOMChild,
|
||||
insertBefore: (
|
||||
this: DOMElement,
|
||||
elem: DOMChild,
|
||||
needle: DOMChild | null | undefined
|
||||
) => DOMChild,
|
||||
addEventListener: addEventListener,
|
||||
dispatchEvent: dispatchEvent,
|
||||
focus: () => void,
|
||||
toString: (this: DOMElement) => String,
|
||||
getElementsByClassName: (
|
||||
this: DOMElement,
|
||||
className: String
|
||||
) => Array<DOMElement>,
|
||||
getElementsByTagName: (
|
||||
this: DOMElement,
|
||||
tagName: String
|
||||
) => Array<DOMElement>,
|
||||
}
|
||||
|
||||
type DocumentFragment := {
|
||||
childNodes: Array<DOMChild>,
|
||||
parentNode: null | DOMElement,
|
||||
type: "DocumentFragment",
|
||||
nodeType: 11,
|
||||
nodeName: "#document-fragment",
|
||||
ownerDoucment: Document | null,
|
||||
|
||||
appendChild: (this: DocumentFragment, child: DOMChild),
|
||||
replaceChild:
|
||||
(this: DocumentFragment, elem: DOMChild, needle: DOMChild),
|
||||
removeChild: (this: DocumentFragment, child: DOMChild),
|
||||
toString: (this: DocumentFragment) => String
|
||||
}
|
||||
|
||||
type Document := {
|
||||
body: DOMElement,
|
||||
childNodes: Array<DOMChild>,
|
||||
documentElement: DOMElement,
|
||||
nodeType: 9,
|
||||
|
||||
createComment: (this: Document, data: String) => Commment,
|
||||
createTextNode: (this: Document, value: String) => DOMText,
|
||||
createElement: (this: Document, tagName: String) => DOMElement,
|
||||
createElementNS: (
|
||||
this: Document,
|
||||
namespace: String | null,
|
||||
tagName: String
|
||||
) => DOMElement,
|
||||
createDocumentFragment: (this: Document) => DocumentFragment,
|
||||
createEvent: () => Event,
|
||||
getElementById: (
|
||||
this: Document,
|
||||
id: String,
|
||||
) => null | DOMElement,
|
||||
getElementsByClassName: (
|
||||
this: Document,
|
||||
className: String
|
||||
) => Array<DOMElement>,
|
||||
getElementsByTagName: (
|
||||
this: Document,
|
||||
tagName: String
|
||||
) => Array<DOMElement>
|
||||
}
|
||||
|
||||
type Event := {
|
||||
type: String,
|
||||
bubbles: Boolean,
|
||||
cancelable: Boolean,
|
||||
|
||||
initEvent: (
|
||||
this: Event,
|
||||
type: String,
|
||||
bubbles: Boolean,
|
||||
cancelable: Boolean
|
||||
) => void
|
||||
}
|
||||
|
||||
type addEventListener := (
|
||||
this: DOMElement,
|
||||
type: String,
|
||||
listener: Listener
|
||||
) => void
|
||||
|
||||
type dispatchEvent := (
|
||||
this: DOMElement,
|
||||
ev: Event
|
||||
)
|
||||
|
||||
min-document/event/add-event-listener := addEventListener
|
||||
|
||||
min-document/event/dispatch-event := dispatchEvent
|
||||
|
||||
min-document/document := () => Document
|
||||
|
||||
min-document/dom-element :=
|
||||
(tagName: String, owner?: Document, namespace?: String | null) => DOMElement
|
||||
|
||||
min-document/dom-fragment :=
|
||||
(owner?: Document) => DocumentFragment
|
||||
|
||||
min-document/dom-text :=
|
||||
(value: String, owner?: Document) => DOMText
|
||||
|
||||
min-document/event := () => Event
|
||||
|
||||
min-document/serialize := (DOMElement) => String
|
||||
|
||||
min-document := Document
|
||||
72
node_modules/min-document/document.js
generated
vendored
72
node_modules/min-document/document.js
generated
vendored
@@ -1,72 +0,0 @@
|
||||
var domWalk = require("dom-walk")
|
||||
|
||||
var Comment = require("./dom-comment.js")
|
||||
var DOMText = require("./dom-text.js")
|
||||
var DOMElement = require("./dom-element.js")
|
||||
var DocumentFragment = require("./dom-fragment.js")
|
||||
var Event = require("./event.js")
|
||||
var dispatchEvent = require("./event/dispatch-event.js")
|
||||
var addEventListener = require("./event/add-event-listener.js")
|
||||
var removeEventListener = require("./event/remove-event-listener.js")
|
||||
|
||||
module.exports = Document;
|
||||
|
||||
function Document() {
|
||||
if (!(this instanceof Document)) {
|
||||
return new Document();
|
||||
}
|
||||
|
||||
this.head = this.createElement("head")
|
||||
this.body = this.createElement("body")
|
||||
this.documentElement = this.createElement("html")
|
||||
this.documentElement.appendChild(this.head)
|
||||
this.documentElement.appendChild(this.body)
|
||||
this.childNodes = [this.documentElement]
|
||||
this.nodeType = 9
|
||||
}
|
||||
|
||||
var proto = Document.prototype;
|
||||
proto.createTextNode = function createTextNode(value) {
|
||||
return new DOMText(value, this)
|
||||
}
|
||||
|
||||
proto.createElementNS = function createElementNS(namespace, tagName) {
|
||||
var ns = namespace === null ? null : String(namespace)
|
||||
return new DOMElement(tagName, this, ns)
|
||||
}
|
||||
|
||||
proto.createElement = function createElement(tagName) {
|
||||
return new DOMElement(tagName, this)
|
||||
}
|
||||
|
||||
proto.createDocumentFragment = function createDocumentFragment() {
|
||||
return new DocumentFragment(this)
|
||||
}
|
||||
|
||||
proto.createEvent = function createEvent(family) {
|
||||
return new Event(family)
|
||||
}
|
||||
|
||||
proto.createComment = function createComment(data) {
|
||||
return new Comment(data, this)
|
||||
}
|
||||
|
||||
proto.getElementById = function getElementById(id) {
|
||||
id = String(id)
|
||||
|
||||
var result = domWalk(this.childNodes, function (node) {
|
||||
if (String(node.id) === id) {
|
||||
return node
|
||||
}
|
||||
})
|
||||
|
||||
return result || null
|
||||
}
|
||||
|
||||
proto.getElementsByClassName = DOMElement.prototype.getElementsByClassName
|
||||
proto.getElementsByTagName = DOMElement.prototype.getElementsByTagName
|
||||
proto.contains = DOMElement.prototype.contains
|
||||
|
||||
proto.removeEventListener = removeEventListener
|
||||
proto.addEventListener = addEventListener
|
||||
proto.dispatchEvent = dispatchEvent
|
||||
19
node_modules/min-document/dom-comment.js
generated
vendored
19
node_modules/min-document/dom-comment.js
generated
vendored
@@ -1,19 +0,0 @@
|
||||
module.exports = Comment
|
||||
|
||||
function Comment(data, owner) {
|
||||
if (!(this instanceof Comment)) {
|
||||
return new Comment(data, owner)
|
||||
}
|
||||
|
||||
this.data = data
|
||||
this.nodeValue = data
|
||||
this.length = data.length
|
||||
this.ownerDocument = owner || null
|
||||
}
|
||||
|
||||
Comment.prototype.nodeType = 8
|
||||
Comment.prototype.nodeName = "#comment"
|
||||
|
||||
Comment.prototype.toString = function _Comment_toString() {
|
||||
return "[object Comment]"
|
||||
}
|
||||
209
node_modules/min-document/dom-element.js
generated
vendored
209
node_modules/min-document/dom-element.js
generated
vendored
@@ -1,209 +0,0 @@
|
||||
var domWalk = require("dom-walk")
|
||||
var dispatchEvent = require("./event/dispatch-event.js")
|
||||
var addEventListener = require("./event/add-event-listener.js")
|
||||
var removeEventListener = require("./event/remove-event-listener.js")
|
||||
var serializeNode = require("./serialize.js")
|
||||
|
||||
var htmlns = "http://www.w3.org/1999/xhtml"
|
||||
|
||||
module.exports = DOMElement
|
||||
|
||||
function DOMElement(tagName, owner, namespace) {
|
||||
if (!(this instanceof DOMElement)) {
|
||||
return new DOMElement(tagName)
|
||||
}
|
||||
|
||||
var ns = namespace === undefined ? htmlns : (namespace || null)
|
||||
|
||||
this.tagName = ns === htmlns ? String(tagName).toUpperCase() : tagName
|
||||
this.nodeName = this.tagName
|
||||
this.className = ""
|
||||
this.dataset = {}
|
||||
this.childNodes = []
|
||||
this.parentNode = null
|
||||
this.style = {}
|
||||
this.ownerDocument = owner || null
|
||||
this.namespaceURI = ns
|
||||
this._attributes = {}
|
||||
|
||||
if (this.tagName === 'INPUT') {
|
||||
this.type = 'text'
|
||||
}
|
||||
}
|
||||
|
||||
DOMElement.prototype.type = "DOMElement"
|
||||
DOMElement.prototype.nodeType = 1
|
||||
|
||||
DOMElement.prototype.appendChild = function _Element_appendChild(child) {
|
||||
if (child.parentNode) {
|
||||
child.parentNode.removeChild(child)
|
||||
}
|
||||
|
||||
this.childNodes.push(child)
|
||||
child.parentNode = this
|
||||
|
||||
return child
|
||||
}
|
||||
|
||||
DOMElement.prototype.replaceChild =
|
||||
function _Element_replaceChild(elem, needle) {
|
||||
// TODO: Throw NotFoundError if needle.parentNode !== this
|
||||
|
||||
if (elem.parentNode) {
|
||||
elem.parentNode.removeChild(elem)
|
||||
}
|
||||
|
||||
var index = this.childNodes.indexOf(needle)
|
||||
|
||||
needle.parentNode = null
|
||||
this.childNodes[index] = elem
|
||||
elem.parentNode = this
|
||||
|
||||
return needle
|
||||
}
|
||||
|
||||
DOMElement.prototype.removeChild = function _Element_removeChild(elem) {
|
||||
// TODO: Throw NotFoundError if elem.parentNode !== this
|
||||
|
||||
var index = this.childNodes.indexOf(elem)
|
||||
this.childNodes.splice(index, 1)
|
||||
|
||||
elem.parentNode = null
|
||||
return elem
|
||||
}
|
||||
|
||||
DOMElement.prototype.insertBefore =
|
||||
function _Element_insertBefore(elem, needle) {
|
||||
// TODO: Throw NotFoundError if referenceElement is a dom node
|
||||
// and parentNode !== this
|
||||
|
||||
if (elem.parentNode) {
|
||||
elem.parentNode.removeChild(elem)
|
||||
}
|
||||
|
||||
var index = needle === null || needle === undefined ?
|
||||
-1 :
|
||||
this.childNodes.indexOf(needle)
|
||||
|
||||
if (index > -1) {
|
||||
this.childNodes.splice(index, 0, elem)
|
||||
} else {
|
||||
this.childNodes.push(elem)
|
||||
}
|
||||
|
||||
elem.parentNode = this
|
||||
return elem
|
||||
}
|
||||
|
||||
DOMElement.prototype.setAttributeNS =
|
||||
function _Element_setAttributeNS(namespace, name, value) {
|
||||
var prefix = null
|
||||
var localName = name
|
||||
var colonPosition = name.indexOf(":")
|
||||
if (colonPosition > -1) {
|
||||
prefix = name.substr(0, colonPosition)
|
||||
localName = name.substr(colonPosition + 1)
|
||||
}
|
||||
if (this.tagName === 'INPUT' && name === 'type') {
|
||||
this.type = value;
|
||||
}
|
||||
else {
|
||||
var attributes = this._attributes[namespace] || (this._attributes[namespace] = {})
|
||||
attributes[localName] = {value: value, prefix: prefix}
|
||||
}
|
||||
}
|
||||
|
||||
DOMElement.prototype.getAttributeNS =
|
||||
function _Element_getAttributeNS(namespace, name) {
|
||||
var attributes = this._attributes[namespace];
|
||||
var value = attributes && attributes[name] && attributes[name].value
|
||||
if (this.tagName === 'INPUT' && name === 'type') {
|
||||
return this.type;
|
||||
}
|
||||
if (typeof value !== "string") {
|
||||
return null
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
DOMElement.prototype.removeAttributeNS =
|
||||
function _Element_removeAttributeNS(namespace, name) {
|
||||
var attributes = this._attributes[namespace];
|
||||
if (attributes) {
|
||||
delete attributes[name]
|
||||
}
|
||||
}
|
||||
|
||||
DOMElement.prototype.hasAttributeNS =
|
||||
function _Element_hasAttributeNS(namespace, name) {
|
||||
var attributes = this._attributes[namespace]
|
||||
return !!attributes && name in attributes;
|
||||
}
|
||||
|
||||
DOMElement.prototype.setAttribute = function _Element_setAttribute(name, value) {
|
||||
return this.setAttributeNS(null, name, value)
|
||||
}
|
||||
|
||||
DOMElement.prototype.getAttribute = function _Element_getAttribute(name) {
|
||||
return this.getAttributeNS(null, name)
|
||||
}
|
||||
|
||||
DOMElement.prototype.removeAttribute = function _Element_removeAttribute(name) {
|
||||
return this.removeAttributeNS(null, name)
|
||||
}
|
||||
|
||||
DOMElement.prototype.hasAttribute = function _Element_hasAttribute(name) {
|
||||
return this.hasAttributeNS(null, name)
|
||||
}
|
||||
|
||||
DOMElement.prototype.removeEventListener = removeEventListener
|
||||
DOMElement.prototype.addEventListener = addEventListener
|
||||
DOMElement.prototype.dispatchEvent = dispatchEvent
|
||||
|
||||
// Un-implemented
|
||||
DOMElement.prototype.focus = function _Element_focus() {
|
||||
return void 0
|
||||
}
|
||||
|
||||
DOMElement.prototype.toString = function _Element_toString() {
|
||||
return serializeNode(this)
|
||||
}
|
||||
|
||||
DOMElement.prototype.getElementsByClassName = function _Element_getElementsByClassName(classNames) {
|
||||
var classes = classNames.split(" ");
|
||||
var elems = []
|
||||
|
||||
domWalk(this, function (node) {
|
||||
if (node.nodeType === 1) {
|
||||
var nodeClassName = node.className || ""
|
||||
var nodeClasses = nodeClassName.split(" ")
|
||||
|
||||
if (classes.every(function (item) {
|
||||
return nodeClasses.indexOf(item) !== -1
|
||||
})) {
|
||||
elems.push(node)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return elems
|
||||
}
|
||||
|
||||
DOMElement.prototype.getElementsByTagName = function _Element_getElementsByTagName(tagName) {
|
||||
tagName = tagName.toLowerCase()
|
||||
var elems = []
|
||||
|
||||
domWalk(this.childNodes, function (node) {
|
||||
if (node.nodeType === 1 && (tagName === '*' || node.tagName.toLowerCase() === tagName)) {
|
||||
elems.push(node)
|
||||
}
|
||||
})
|
||||
|
||||
return elems
|
||||
}
|
||||
|
||||
DOMElement.prototype.contains = function _Element_contains(element) {
|
||||
return domWalk(this, function (node) {
|
||||
return element === node
|
||||
}) || false
|
||||
}
|
||||
28
node_modules/min-document/dom-fragment.js
generated
vendored
28
node_modules/min-document/dom-fragment.js
generated
vendored
@@ -1,28 +0,0 @@
|
||||
var DOMElement = require("./dom-element.js")
|
||||
|
||||
module.exports = DocumentFragment
|
||||
|
||||
function DocumentFragment(owner) {
|
||||
if (!(this instanceof DocumentFragment)) {
|
||||
return new DocumentFragment()
|
||||
}
|
||||
|
||||
this.childNodes = []
|
||||
this.parentNode = null
|
||||
this.ownerDocument = owner || null
|
||||
}
|
||||
|
||||
DocumentFragment.prototype.type = "DocumentFragment"
|
||||
DocumentFragment.prototype.nodeType = 11
|
||||
DocumentFragment.prototype.nodeName = "#document-fragment"
|
||||
|
||||
DocumentFragment.prototype.appendChild = DOMElement.prototype.appendChild
|
||||
DocumentFragment.prototype.replaceChild = DOMElement.prototype.replaceChild
|
||||
DocumentFragment.prototype.removeChild = DOMElement.prototype.removeChild
|
||||
|
||||
DocumentFragment.prototype.toString =
|
||||
function _DocumentFragment_toString() {
|
||||
return this.childNodes.map(function (node) {
|
||||
return String(node)
|
||||
}).join("")
|
||||
}
|
||||
27
node_modules/min-document/dom-text.js
generated
vendored
27
node_modules/min-document/dom-text.js
generated
vendored
@@ -1,27 +0,0 @@
|
||||
module.exports = DOMText
|
||||
|
||||
function DOMText(value, owner) {
|
||||
if (!(this instanceof DOMText)) {
|
||||
return new DOMText(value)
|
||||
}
|
||||
|
||||
this.data = value || ""
|
||||
this.length = this.data.length
|
||||
this.ownerDocument = owner || null
|
||||
}
|
||||
|
||||
DOMText.prototype.type = "DOMTextNode"
|
||||
DOMText.prototype.nodeType = 3
|
||||
DOMText.prototype.nodeName = "#text"
|
||||
|
||||
DOMText.prototype.toString = function _Text_toString() {
|
||||
return this.data
|
||||
}
|
||||
|
||||
DOMText.prototype.replaceData = function replaceData(index, length, value) {
|
||||
var current = this.data
|
||||
var left = current.substring(0, index)
|
||||
var right = current.substring(index + length, current.length)
|
||||
this.data = left + value + right
|
||||
this.length = this.data.length
|
||||
}
|
||||
13
node_modules/min-document/event.js
generated
vendored
13
node_modules/min-document/event.js
generated
vendored
@@ -1,13 +0,0 @@
|
||||
module.exports = Event
|
||||
|
||||
function Event(family) {}
|
||||
|
||||
Event.prototype.initEvent = function _Event_initEvent(type, bubbles, cancelable) {
|
||||
this.type = type
|
||||
this.bubbles = bubbles
|
||||
this.cancelable = cancelable
|
||||
}
|
||||
|
||||
Event.prototype.preventDefault = function _Event_preventDefault() {
|
||||
|
||||
}
|
||||
17
node_modules/min-document/event/add-event-listener.js
generated
vendored
17
node_modules/min-document/event/add-event-listener.js
generated
vendored
@@ -1,17 +0,0 @@
|
||||
module.exports = addEventListener
|
||||
|
||||
function addEventListener(type, listener) {
|
||||
var elem = this
|
||||
|
||||
if (!elem.listeners) {
|
||||
elem.listeners = {}
|
||||
}
|
||||
|
||||
if (!elem.listeners[type]) {
|
||||
elem.listeners[type] = []
|
||||
}
|
||||
|
||||
if (elem.listeners[type].indexOf(listener) === -1) {
|
||||
elem.listeners[type].push(listener)
|
||||
}
|
||||
}
|
||||
31
node_modules/min-document/event/dispatch-event.js
generated
vendored
31
node_modules/min-document/event/dispatch-event.js
generated
vendored
@@ -1,31 +0,0 @@
|
||||
module.exports = dispatchEvent
|
||||
|
||||
function dispatchEvent(ev) {
|
||||
var elem = this
|
||||
var type = ev.type
|
||||
|
||||
if (!ev.target) {
|
||||
ev.target = elem
|
||||
}
|
||||
|
||||
if (!elem.listeners) {
|
||||
elem.listeners = {}
|
||||
}
|
||||
|
||||
var listeners = elem.listeners[type]
|
||||
|
||||
if (listeners) {
|
||||
return listeners.forEach(function (listener) {
|
||||
ev.currentTarget = elem
|
||||
if (typeof listener === 'function') {
|
||||
listener(ev)
|
||||
} else {
|
||||
listener.handleEvent(ev)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (elem.parentNode) {
|
||||
elem.parentNode.dispatchEvent(ev)
|
||||
}
|
||||
}
|
||||
19
node_modules/min-document/event/remove-event-listener.js
generated
vendored
19
node_modules/min-document/event/remove-event-listener.js
generated
vendored
@@ -1,19 +0,0 @@
|
||||
module.exports = removeEventListener
|
||||
|
||||
function removeEventListener(type, listener) {
|
||||
var elem = this
|
||||
|
||||
if (!elem.listeners) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!elem.listeners[type]) {
|
||||
return
|
||||
}
|
||||
|
||||
var list = elem.listeners[type]
|
||||
var index = list.indexOf(listener)
|
||||
if (index !== -1) {
|
||||
list.splice(index, 1)
|
||||
}
|
||||
}
|
||||
3
node_modules/min-document/index.js
generated
vendored
3
node_modules/min-document/index.js
generated
vendored
@@ -1,3 +0,0 @@
|
||||
var Document = require('./document.js');
|
||||
|
||||
module.exports = new Document();
|
||||
58
node_modules/min-document/package.json
generated
vendored
58
node_modules/min-document/package.json
generated
vendored
@@ -1,58 +0,0 @@
|
||||
{
|
||||
"name": "min-document",
|
||||
"version": "2.19.0",
|
||||
"description": "A minimal DOM implementation",
|
||||
"keywords": [],
|
||||
"author": "Raynos <raynos2@gmail.com>",
|
||||
"repository": "git://github.com/Raynos/min-document.git",
|
||||
"main": "index",
|
||||
"homepage": "https://github.com/Raynos/min-document",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Raynos"
|
||||
}
|
||||
],
|
||||
"bugs": {
|
||||
"url": "https://github.com/Raynos/min-document/issues",
|
||||
"email": "raynos2@gmail.com"
|
||||
},
|
||||
"dependencies": {
|
||||
"dom-walk": "^0.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"run-browser": "git://github.com/Raynos/run-browser",
|
||||
"tap-dot": "^0.2.1",
|
||||
"tap-spec": "^0.1.8",
|
||||
"tape": "^2.12.3"
|
||||
},
|
||||
"licenses": [
|
||||
{
|
||||
"type": "MIT",
|
||||
"url": "http://github.com/Raynos/min-document/raw/master/LICENSE"
|
||||
}
|
||||
],
|
||||
"scripts": {
|
||||
"test": "node ./test/index.js | tap-spec",
|
||||
"dot": "node ./test/index.js | tap-dot",
|
||||
"cover": "istanbul cover --report none --print detail ./test/index.js",
|
||||
"view-cover": "istanbul report html && google-chrome ./coverage/index.html",
|
||||
"browser": "run-browser test/index.js",
|
||||
"phantom": "run-browser test/index.js -b | tap-spec"
|
||||
},
|
||||
"testling": {
|
||||
"files": "test/index.js",
|
||||
"browsers": [
|
||||
"ie/8..latest",
|
||||
"firefox/16..latest",
|
||||
"firefox/nightly",
|
||||
"chrome/22..latest",
|
||||
"chrome/canary",
|
||||
"opera/12..latest",
|
||||
"opera/next",
|
||||
"safari/5.1..latest",
|
||||
"ipad/6.0..latest",
|
||||
"iphone/6.0..latest",
|
||||
"android-browser/4.2..latest"
|
||||
]
|
||||
}
|
||||
}
|
||||
139
node_modules/min-document/serialize.js
generated
vendored
139
node_modules/min-document/serialize.js
generated
vendored
@@ -1,139 +0,0 @@
|
||||
module.exports = serializeNode
|
||||
|
||||
var voidElements = ["area","base","br","col","embed","hr","img","input","keygen","link","menuitem","meta","param","source","track","wbr"];
|
||||
|
||||
function serializeNode(node) {
|
||||
switch (node.nodeType) {
|
||||
case 3:
|
||||
return escapeText(node.data)
|
||||
case 8:
|
||||
return "<!--" + node.data + "-->"
|
||||
default:
|
||||
return serializeElement(node)
|
||||
}
|
||||
}
|
||||
|
||||
function serializeElement(elem) {
|
||||
var strings = []
|
||||
|
||||
var tagname = elem.tagName
|
||||
|
||||
if (elem.namespaceURI === "http://www.w3.org/1999/xhtml") {
|
||||
tagname = tagname.toLowerCase()
|
||||
}
|
||||
|
||||
strings.push("<" + tagname + properties(elem) + datasetify(elem))
|
||||
|
||||
if (voidElements.indexOf(tagname) > -1) {
|
||||
strings.push(" />")
|
||||
} else {
|
||||
strings.push(">")
|
||||
|
||||
if (elem.childNodes.length) {
|
||||
strings.push.apply(strings, elem.childNodes.map(serializeNode))
|
||||
} else if (elem.textContent || elem.innerText) {
|
||||
strings.push(escapeText(elem.textContent || elem.innerText))
|
||||
} else if (elem.innerHTML) {
|
||||
strings.push(elem.innerHTML)
|
||||
}
|
||||
|
||||
strings.push("</" + tagname + ">")
|
||||
}
|
||||
|
||||
return strings.join("")
|
||||
}
|
||||
|
||||
function isProperty(elem, key) {
|
||||
var type = typeof elem[key]
|
||||
|
||||
if (key === "style" && Object.keys(elem.style).length > 0) {
|
||||
return true
|
||||
}
|
||||
|
||||
return elem.hasOwnProperty(key) &&
|
||||
(type === "string" || type === "boolean" || type === "number") &&
|
||||
key !== "nodeName" && key !== "className" && key !== "tagName" &&
|
||||
key !== "textContent" && key !== "innerText" && key !== "namespaceURI" && key !== "innerHTML"
|
||||
}
|
||||
|
||||
function stylify(styles) {
|
||||
if (typeof styles === 'string') return styles
|
||||
var attr = ""
|
||||
Object.keys(styles).forEach(function (key) {
|
||||
var value = styles[key]
|
||||
key = key.replace(/[A-Z]/g, function(c) {
|
||||
return "-" + c.toLowerCase();
|
||||
})
|
||||
attr += key + ":" + value + ";"
|
||||
})
|
||||
return attr
|
||||
}
|
||||
|
||||
function datasetify(elem) {
|
||||
var ds = elem.dataset
|
||||
var props = []
|
||||
|
||||
for (var key in ds) {
|
||||
props.push({ name: "data-" + key, value: ds[key] })
|
||||
}
|
||||
|
||||
return props.length ? stringify(props) : ""
|
||||
}
|
||||
|
||||
function stringify(list) {
|
||||
var attributes = []
|
||||
list.forEach(function (tuple) {
|
||||
var name = tuple.name
|
||||
var value = tuple.value
|
||||
|
||||
if (name === "style") {
|
||||
value = stylify(value)
|
||||
}
|
||||
|
||||
attributes.push(name + "=" + "\"" + escapeAttributeValue(value) + "\"")
|
||||
})
|
||||
|
||||
return attributes.length ? " " + attributes.join(" ") : ""
|
||||
}
|
||||
|
||||
function properties(elem) {
|
||||
var props = []
|
||||
for (var key in elem) {
|
||||
if (isProperty(elem, key)) {
|
||||
props.push({ name: key, value: elem[key] })
|
||||
}
|
||||
}
|
||||
|
||||
for (var ns in elem._attributes) {
|
||||
for (var attribute in elem._attributes[ns]) {
|
||||
var prop = elem._attributes[ns][attribute]
|
||||
var name = (prop.prefix ? prop.prefix + ":" : "") + attribute
|
||||
props.push({ name: name, value: prop.value })
|
||||
}
|
||||
}
|
||||
|
||||
if (elem.className) {
|
||||
props.push({ name: "class", value: elem.className })
|
||||
}
|
||||
|
||||
return props.length ? stringify(props) : ""
|
||||
}
|
||||
|
||||
function escapeText(s) {
|
||||
var str = '';
|
||||
|
||||
if (typeof(s) === 'string') {
|
||||
str = s;
|
||||
} else if (s) {
|
||||
str = s.toString();
|
||||
}
|
||||
|
||||
return str
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
}
|
||||
|
||||
function escapeAttributeValue(str) {
|
||||
return escapeText(str).replace(/"/g, """)
|
||||
}
|
||||
13
node_modules/min-document/test/cleanup.js
generated
vendored
13
node_modules/min-document/test/cleanup.js
generated
vendored
@@ -1,13 +0,0 @@
|
||||
module.exports = Cleanup
|
||||
|
||||
function Cleanup (document) {
|
||||
|
||||
return cleanup
|
||||
|
||||
function cleanup () {
|
||||
var childNodes = document.body.childNodes
|
||||
for (var i = 0; i < childNodes.length; i++) {
|
||||
document.body.removeChild(childNodes[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
14
node_modules/min-document/test/index.js
generated
vendored
14
node_modules/min-document/test/index.js
generated
vendored
@@ -1,14 +0,0 @@
|
||||
var testDocument = require("./test-document")
|
||||
var testDomElement = require("./test-dom-element")
|
||||
var testDomComment = require("./test-dom-comment")
|
||||
var document = require("../index")
|
||||
|
||||
testDocument(document)
|
||||
testDomElement(document)
|
||||
testDomComment(document)
|
||||
|
||||
if (typeof window !== "undefined" && window.document) {
|
||||
testDocument(window.document)
|
||||
testDomElement(window.document)
|
||||
testDomComment(window.document)
|
||||
}
|
||||
11
node_modules/min-document/test/static/index.html
generated
vendored
11
node_modules/min-document/test/static/index.html
generated
vendored
@@ -1,11 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>TAPE Example</title>
|
||||
<script src="/testem.js"></script>
|
||||
<script src="test-adapter.js"></script>
|
||||
<script src="bundle.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
49
node_modules/min-document/test/static/test-adapter.js
generated
vendored
49
node_modules/min-document/test/static/test-adapter.js
generated
vendored
@@ -1,49 +0,0 @@
|
||||
(function () {
|
||||
var Testem = window.Testem
|
||||
var regex = /^((?:not )?ok) (\d+) (.+)$/
|
||||
|
||||
Testem.useCustomAdapter(tapAdapter)
|
||||
|
||||
function tapAdapter(socket){
|
||||
var results = {
|
||||
failed: 0
|
||||
, passed: 0
|
||||
, total: 0
|
||||
, tests: []
|
||||
}
|
||||
|
||||
socket.emit('tests-start')
|
||||
|
||||
Testem.handleConsoleMessage = function(msg){
|
||||
var m = msg.match(regex)
|
||||
if (m) {
|
||||
var passed = m[1] === 'ok'
|
||||
var test = {
|
||||
passed: passed ? 1 : 0,
|
||||
failed: passed ? 0 : 1,
|
||||
total: 1,
|
||||
id: m[2],
|
||||
name: m[3],
|
||||
items: []
|
||||
}
|
||||
|
||||
if (passed) {
|
||||
results.passed++
|
||||
} else {
|
||||
results.failed++
|
||||
}
|
||||
|
||||
results.total++
|
||||
|
||||
socket.emit('test-result', test)
|
||||
results.tests.push(test)
|
||||
} else if (msg === '# ok' || msg.match(/^# tests \d+/)){
|
||||
socket.emit('all-test-results', results)
|
||||
}
|
||||
|
||||
// return false if you want to prevent the console message from
|
||||
// going to the console
|
||||
// return false
|
||||
}
|
||||
}
|
||||
}())
|
||||
564
node_modules/min-document/test/test-document.js
generated
vendored
564
node_modules/min-document/test/test-document.js
generated
vendored
@@ -1,564 +0,0 @@
|
||||
var test = require("tape")
|
||||
|
||||
module.exports = testDocument
|
||||
|
||||
function testDocument(document) {
|
||||
var cleanup = require('./cleanup')(document)
|
||||
var Event = require('../event');
|
||||
|
||||
test("document is a Document", function (assert) {
|
||||
assert.equal(typeof document.createTextNode, "function")
|
||||
assert.equal(typeof document.createElement, "function")
|
||||
assert.equal(typeof document.createDocumentFragment, "function")
|
||||
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("document has a head property", function(assert) {
|
||||
assert.equal(document.head.tagName, "HEAD")
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("document has nodeType 9", function (assert) {
|
||||
assert.equal(document.nodeType, 9)
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("can do stuff", function (assert) {
|
||||
var div = document.createElement("div")
|
||||
div.className = "foo bar"
|
||||
|
||||
var span = document.createElement("span")
|
||||
div.appendChild(span)
|
||||
span.textContent = "Hello! <&>"
|
||||
|
||||
var html = String(div.outerHTML || div)
|
||||
|
||||
assert.equal(html, "<div class=\"foo bar\">" +
|
||||
"<span>Hello! <&></span></div>")
|
||||
|
||||
cleanup()
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("can createDocumentFragment", function (assert) {
|
||||
var frag = document.createDocumentFragment()
|
||||
|
||||
assert.equal(frag.nodeType, 11)
|
||||
|
||||
var h1 = document.createElement("h1")
|
||||
var h2 = document.createElement("h2")
|
||||
|
||||
assert.equal(h1.nodeType, 1)
|
||||
assert.equal(h1.nodeType, 1)
|
||||
|
||||
frag.appendChild(h1)
|
||||
assert.equal(fragString(frag), "<h1></h1>")
|
||||
|
||||
frag.appendChild(h2)
|
||||
assert.equal(fragString(frag), "<h1></h1><h2></h2>")
|
||||
|
||||
frag.removeChild(h1)
|
||||
assert.equal(fragString(frag), "<h2></h2>")
|
||||
|
||||
frag.replaceChild(h1, h2)
|
||||
assert.equal(fragString(frag), "<h1></h1>")
|
||||
|
||||
cleanup()
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("can getElementById", function (assert) {
|
||||
|
||||
function append_div(id, parent) {
|
||||
var div = document.createElement("div")
|
||||
div.id = id
|
||||
parent.appendChild(div)
|
||||
return div
|
||||
}
|
||||
|
||||
var div1 = append_div(1, document.body)
|
||||
var div2 = append_div(2, document.body)
|
||||
var div3 = append_div(3, document.body)
|
||||
|
||||
var div11 = append_div(11, div1)
|
||||
var div12 = append_div(12, div1)
|
||||
var div21 = append_div(21, div2)
|
||||
var div22 = append_div(22, div2)
|
||||
var div221 = append_div(221, div22)
|
||||
var div222 = append_div(222, div22)
|
||||
|
||||
assert.equal(document.getElementById(1), div1)
|
||||
assert.equal(document.getElementById("2"), div2)
|
||||
assert.equal(document.getElementById(3), div3)
|
||||
assert.equal(document.getElementById(11), div11)
|
||||
assert.equal(document.getElementById(12), div12)
|
||||
assert.equal(document.getElementById(21), div21)
|
||||
assert.equal(document.getElementById(22), div22)
|
||||
assert.equal(document.getElementById(221), div221)
|
||||
assert.equal(document.getElementById(222), div222)
|
||||
|
||||
cleanup()
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("can getElementsByClassName for a single class", function(assert) {
|
||||
function append_div(className, parent) {
|
||||
var div = document.createElement("div")
|
||||
div.className = className
|
||||
parent.appendChild(div)
|
||||
return div
|
||||
}
|
||||
|
||||
function assertSingleMatch(className, expectedElement) {
|
||||
var result = document.getElementsByClassName(className)
|
||||
assert.equal(result.length, 1)
|
||||
assert.equal(result[0], expectedElement)
|
||||
}
|
||||
|
||||
var divA = append_div("A", document.body)
|
||||
var divB = append_div("B", document.body)
|
||||
var divC = append_div("C", document.body)
|
||||
|
||||
var divA1 = append_div("A1", divA)
|
||||
var divA2 = append_div("A2", divA)
|
||||
var divB1 = append_div("B1", divB)
|
||||
var divB2 = append_div("B2", divB)
|
||||
var divB2a = append_div("B2a", divB2)
|
||||
var divB2b = append_div("B2b", divB2)
|
||||
|
||||
assertSingleMatch("A", divA)
|
||||
assertSingleMatch("B", divB)
|
||||
assertSingleMatch("C", divC)
|
||||
assertSingleMatch("A1", divA1)
|
||||
assertSingleMatch("A2", divA2)
|
||||
assertSingleMatch("B1", divB1)
|
||||
assertSingleMatch("B2", divB2)
|
||||
assertSingleMatch("B2a", divB2a)
|
||||
assertSingleMatch("B2b", divB2b)
|
||||
|
||||
cleanup()
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("can getElementsByClassName for many elements", function (assert) {
|
||||
function h(className) {
|
||||
var div = document.createElement("div")
|
||||
div.className = className
|
||||
return div
|
||||
}
|
||||
|
||||
document.body.appendChild(h("multi-class-bar"))
|
||||
document.body.appendChild(h("multi-class-bar"))
|
||||
|
||||
var elems = document.getElementsByClassName("multi-class-bar")
|
||||
assert.equal(elems.length, 2)
|
||||
|
||||
cleanup()
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("can getElementsByClassName for many classes", function(assert) {
|
||||
function append_div(classNames, parent) {
|
||||
var div = document.createElement("div")
|
||||
div.className = classNames
|
||||
parent.appendChild(div)
|
||||
return div
|
||||
}
|
||||
|
||||
function assertMatch(classNames, expectedElements) {
|
||||
var result = document.getElementsByClassName(classNames)
|
||||
assert.equal(result.length, expectedElements.length)
|
||||
for (var i = 0; i < expectedElements.length; i++) {
|
||||
assert.notEqual(expectedElements.indexOf(result[i]), -1)
|
||||
}
|
||||
}
|
||||
|
||||
var divXYZ = append_div("X Y Z", document.body)
|
||||
var divYZ = append_div("Y Z", document.body)
|
||||
var divZX = append_div("Z X", document.body)
|
||||
|
||||
var divX1X2 = append_div("X1 X2", divXYZ)
|
||||
var divX1X2Y1 = append_div("X1 X2 Y1", divXYZ)
|
||||
|
||||
|
||||
assertMatch("X", [divXYZ, divZX])
|
||||
assertMatch("Y Z", [divXYZ, divYZ])
|
||||
assertMatch("X Y Z", [divXYZ])
|
||||
assertMatch("X1 X2", [divX1X2, divX1X2Y1])
|
||||
|
||||
cleanup()
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("can create/manipulate textnodes", function (assert) {
|
||||
var textnode = document.createTextNode("hello")
|
||||
|
||||
assert.equal(textnode.nodeType, 3)
|
||||
assert.equal(textnode.data, "hello")
|
||||
assert.equal(typeof textnode.replaceData, "function")
|
||||
|
||||
textnode.replaceData(0, 7, "nightly")
|
||||
assert.equal(textnode.nodeType, 3)
|
||||
assert.equal(textnode.data, "nightly")
|
||||
assert.equal(typeof textnode.replaceData, "function")
|
||||
|
||||
textnode.replaceData(1, 1, "ou")
|
||||
assert.equal(textnode.nodeType, 3)
|
||||
assert.equal(textnode.data, "noughtly")
|
||||
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("owner document is set", function (assert) {
|
||||
var textnode = document.createTextNode("hello")
|
||||
var domnode = document.createElement("div")
|
||||
var fragment = document.createDocumentFragment()
|
||||
|
||||
assert.equal(textnode.ownerDocument, document)
|
||||
assert.equal(domnode.ownerDocument, document)
|
||||
assert.equal(fragment.ownerDocument, document)
|
||||
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("Create namespaced nodes", function (assert) {
|
||||
var svgURI = "http://www.w3.org/2000/svg"
|
||||
var htmlURI = "http://www.w3.org/1999/xhtml"
|
||||
|
||||
var noNS = document.createElement("div")
|
||||
var svgNS = document.createElementNS(svgURI, "svg")
|
||||
var emptyNS = document.createElementNS("", "div")
|
||||
var nullNS = document.createElementNS(null, "div")
|
||||
var undefNS = document.createElementNS(undefined, "div")
|
||||
var caseNS = document.createElementNS("Oops", "AbC")
|
||||
var htmlNS = document.createElement("div")
|
||||
|
||||
assert.equal(noNS.tagName, "DIV")
|
||||
assert.equal(noNS.namespaceURI, htmlURI)
|
||||
assert.equal(elemString(noNS), "<div></div>")
|
||||
|
||||
assert.equal(svgNS.tagName, "svg")
|
||||
assert.equal(svgNS.namespaceURI, svgURI)
|
||||
assert.equal(elemString(svgNS), "<svg></svg>")
|
||||
|
||||
assert.equal(emptyNS.tagName, "div")
|
||||
assert.equal(emptyNS.namespaceURI, null)
|
||||
assert.equal(elemString(emptyNS), "<div></div>")
|
||||
|
||||
assert.equal(nullNS.tagName, "div")
|
||||
assert.equal(nullNS.namespaceURI, null)
|
||||
assert.equal(elemString(nullNS), "<div></div>")
|
||||
|
||||
assert.equal(undefNS.tagName, "div")
|
||||
assert.equal(undefNS.namespaceURI, "undefined")
|
||||
assert.equal(elemString(undefNS), "<div></div>")
|
||||
|
||||
assert.equal(caseNS.tagName, "AbC")
|
||||
assert.equal(caseNS.namespaceURI, "Oops")
|
||||
assert.equal(elemString(caseNS), "<AbC></AbC>")
|
||||
|
||||
assert.equal(htmlNS.tagName, "DIV")
|
||||
assert.equal(htmlNS.namespaceURI, htmlURI)
|
||||
assert.equal(elemString(htmlNS), "<div></div>")
|
||||
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("Can insert before", function (assert) {
|
||||
var rootNode = document.createElement("div")
|
||||
var child = document.createElement("div")
|
||||
var newElement = document.createElement("div")
|
||||
rootNode.appendChild(child)
|
||||
var el = rootNode.insertBefore(newElement, child)
|
||||
assert.equal(el, newElement)
|
||||
assert.equal(rootNode.childNodes.length, 2)
|
||||
assert.equal(rootNode.childNodes[0], newElement)
|
||||
assert.equal(rootNode.childNodes[1], child)
|
||||
cleanup()
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("Insert before null appends to end", function (assert) {
|
||||
var rootNode = document.createElement("div")
|
||||
var child = document.createElement("div")
|
||||
var newElement = document.createElement("div")
|
||||
rootNode.appendChild(child)
|
||||
var el = rootNode.insertBefore(newElement, null)
|
||||
assert.equal(el, newElement)
|
||||
assert.equal(rootNode.childNodes.length, 2)
|
||||
assert.equal(rootNode.childNodes[0], child)
|
||||
assert.equal(rootNode.childNodes[1], newElement)
|
||||
cleanup()
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("Node insertions remove node from parent", function (assert) {
|
||||
var parent = document.createElement("div")
|
||||
var c1 = document.createElement("div")
|
||||
var c2 = document.createElement("div")
|
||||
var c3 = document.createElement("div")
|
||||
parent.appendChild(c1)
|
||||
parent.appendChild(c2)
|
||||
parent.appendChild(c3)
|
||||
|
||||
var rootNode = document.createElement("div")
|
||||
|
||||
var node1 = rootNode.appendChild(c1)
|
||||
assert.equal(node1, c1)
|
||||
assert.equal(parent.childNodes.length, 2)
|
||||
assert.equal(c1.parentNode, rootNode)
|
||||
|
||||
var node2 = rootNode.insertBefore(c2, c1)
|
||||
assert.equal(node2, c2)
|
||||
assert.equal(parent.childNodes.length, 1)
|
||||
assert.equal(c2.parentNode, rootNode)
|
||||
|
||||
var node3 = rootNode.replaceChild(c3, c2)
|
||||
assert.equal(node3, c2)
|
||||
assert.equal(parent.childNodes.length, 0)
|
||||
assert.equal(c3.parentNode, rootNode)
|
||||
assert.equal(c2.parentNode, null)
|
||||
|
||||
cleanup()
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("input has type=text by default", function (assert) {
|
||||
var elem = document.createElement("input")
|
||||
assert.equal(elem.getAttribute("type"), "text");
|
||||
assert.equal(elemString(elem), "<input type=\"text\" />")
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("input type=text can be overridden", function (assert) {
|
||||
var elem = document.createElement("input")
|
||||
elem.setAttribute("type", "hidden")
|
||||
assert.equal(elem.getAttribute("type"), "hidden");
|
||||
assert.equal(elemString(elem), "<input type=\"hidden\" />")
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("can set and get attributes", function (assert) {
|
||||
var elem = document.createElement("div")
|
||||
assert.equal(elem.getAttribute("foo"), null)
|
||||
assert.equal(elemString(elem), "<div></div>")
|
||||
assert.notOk(elem.hasAttribute('foo'))
|
||||
|
||||
elem.setAttribute("foo", "bar")
|
||||
assert.equal(elem.getAttribute("foo"), "bar")
|
||||
assert.equal(elemString(elem), "<div foo=\"bar\"></div>")
|
||||
assert.ok(elem.hasAttribute('foo'))
|
||||
|
||||
elem.removeAttribute("foo")
|
||||
assert.equal(elem.getAttribute("foo"), null)
|
||||
assert.equal(elemString(elem), "<div></div>")
|
||||
assert.notOk(elem.hasAttribute('foo'))
|
||||
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("can set and set style properties", function(assert) {
|
||||
var elem = document.createElement("div")
|
||||
assert.equal(elemString(elem), "<div></div>")
|
||||
|
||||
elem.style.color = "red";
|
||||
assert.equal(elem.style.color, "red")
|
||||
assert.equal(elemString(elem), "<div style=\"color:red;\"></div>")
|
||||
|
||||
elem.style.background = "blue";
|
||||
assert.equal(elem.style.color, "red")
|
||||
assert.equal(elem.style.background, "blue")
|
||||
assert.equal(elemString(elem),
|
||||
"<div style=\"color:red;background:blue;\"></div>")
|
||||
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("can set and get namespaced attributes", function(assert) {
|
||||
var elem = document.createElement("div")
|
||||
|
||||
var ns = "http://ns.com/my"
|
||||
assert.equal(elem.getAttributeNS(ns, "myattr"), blankAttributeNS())
|
||||
elem.setAttributeNS(ns, "myns:myattr", "the value")
|
||||
assert.equal(elem.getAttributeNS(ns, "myattr"), "the value")
|
||||
assert.equal(elemString(elem), '<div myns:myattr="the value"></div>')
|
||||
elem.removeAttributeNS(ns, "myattr")
|
||||
assert.equal(elem.getAttributeNS(ns, "myattr"), blankAttributeNS())
|
||||
|
||||
// Should work much like get/setAttribute when namespace is null.
|
||||
assert.equal(elem.getAttributeNS(null, "foo"), blankAttributeNS())
|
||||
assert.equal(elem.getAttribute("foo"), null)
|
||||
elem.setAttributeNS(null, "foo", "bar")
|
||||
assert.equal(elem.getAttributeNS(null, "foo"), "bar")
|
||||
assert.equal(elem.getAttribute("foo"), "bar")
|
||||
elem.removeAttributeNS(null, "foo")
|
||||
assert.equal(elem.getAttributeNS(null, "foo"), blankAttributeNS())
|
||||
assert.equal(elem.getAttribute("foo"), null)
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("can getElementsByTagName", function(assert) {
|
||||
var parent = document.createElement("div")
|
||||
var child1 = document.createElement("span")
|
||||
var child2 = document.createElement("span")
|
||||
|
||||
child1.id = "foo"
|
||||
child2.id = "bar"
|
||||
|
||||
child1.appendChild(child2)
|
||||
parent.appendChild(child1)
|
||||
document.body.appendChild(parent)
|
||||
|
||||
var elems = document.getElementsByTagName("SPAN")
|
||||
|
||||
assert.equal(elems.length, 2)
|
||||
assert.equal(elems[0].id, "foo")
|
||||
assert.equal(elems[1].id, "bar")
|
||||
|
||||
cleanup()
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("can getElementsByTagName with *", function(assert) {
|
||||
document.body.appendChild(document.createElement("div"))
|
||||
|
||||
var elems = document.getElementsByTagName("*")
|
||||
|
||||
assert.equal(elems.length, 4)
|
||||
assert.equal(elems[0].tagName, "HTML")
|
||||
assert.equal(elems[1].tagName, "HEAD")
|
||||
assert.equal(elems[2].tagName, "BODY")
|
||||
assert.equal(elems[3].tagName, "DIV")
|
||||
|
||||
cleanup()
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("getElement* methods search outside the body", function(assert) {
|
||||
var html = document.documentElement;
|
||||
assert.equal(document.getElementsByTagName("html")[0], html)
|
||||
|
||||
html.id = "foo"
|
||||
assert.equal(document.getElementById("foo"), html)
|
||||
|
||||
html.className = "bar"
|
||||
assert.equal(document.getElementsByClassName("bar")[0], html)
|
||||
|
||||
// cleanup
|
||||
html.id = ""
|
||||
html.className = ""
|
||||
|
||||
cleanup()
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("getElement* methods can be passed to map()", function(assert) {
|
||||
var e1 = document.createElement("div")
|
||||
var e2 = document.createElement("span")
|
||||
|
||||
document.body.appendChild(e1)
|
||||
document.body.appendChild(e2)
|
||||
|
||||
assert.deepEqual(
|
||||
["div", "span"].map(document.getElementsByTagName.bind(document)),
|
||||
[[e1], [e2]]
|
||||
)
|
||||
|
||||
e1.id = "1"
|
||||
e2.id = "2"
|
||||
|
||||
assert.deepEqual(
|
||||
["1", "2"].map(document.getElementById.bind(document)),
|
||||
[e1, e2]
|
||||
)
|
||||
|
||||
e1.className = "foo"
|
||||
e2.className = "bar"
|
||||
|
||||
assert.deepEqual(
|
||||
["foo", "bar"].map(document.getElementsByClassName.bind(document)),
|
||||
[[e1], [e2]]
|
||||
)
|
||||
|
||||
cleanup()
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("can check if it contains an element", function(assert) {
|
||||
var el = document.createElement("div")
|
||||
document.body.appendChild(el)
|
||||
|
||||
assert.equals(document.contains(document.body), true)
|
||||
assert.equals(document.contains(el), true)
|
||||
|
||||
cleanup()
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("can do events", function (assert) {
|
||||
var x = 1
|
||||
function incx() { x++ }
|
||||
|
||||
var ev = new Event();
|
||||
ev.initEvent("click");
|
||||
document.addEventListener("click", incx)
|
||||
document.dispatchEvent(ev)
|
||||
|
||||
assert.equal(x, 2)
|
||||
|
||||
document.removeEventListener("click", incx)
|
||||
document.dispatchEvent(ev)
|
||||
|
||||
assert.equal(x, 2)
|
||||
assert.end()
|
||||
})
|
||||
|
||||
function blankAttributeNS() {
|
||||
// Most browsers conform to the latest version of the DOM spec,
|
||||
// which requires `getAttributeNS` to return `null` when the attribute
|
||||
// doesn't exist, but some browsers (including phantomjs) implement the
|
||||
// old version of the spec and return an empty string instead, see:
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/element.getAttributeNS#Return_value
|
||||
var div = document.createElement("div")
|
||||
var blank = div.getAttributeNS(null, "foo")
|
||||
if (!(blank === null || blank === "")) {
|
||||
throw "Expected blank attribute to be either null or empty string"
|
||||
}
|
||||
return blank;
|
||||
}
|
||||
|
||||
function elemString(element) {
|
||||
var html = String(element) || "[]"
|
||||
|
||||
if (html.charAt(0) === "[") {
|
||||
html = element.outerHTML
|
||||
if (!html && !element.parentNode) {
|
||||
var div = document.createElement("div")
|
||||
div.appendChild(element)
|
||||
html = div.innerHTML
|
||||
div.removeChild(element)
|
||||
}
|
||||
}
|
||||
|
||||
return html
|
||||
}
|
||||
|
||||
function fragString(fragment) {
|
||||
var html = String(fragment)
|
||||
|
||||
|
||||
if (html === "[object DocumentFragment]") {
|
||||
var innerHTML = []
|
||||
for (var i = 0; i < fragment.childNodes.length; i++) {
|
||||
var node = fragment.childNodes[i]
|
||||
innerHTML.push(String(node.outerHTML || node))
|
||||
}
|
||||
html = innerHTML.join("")
|
||||
}
|
||||
|
||||
return html
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
20
node_modules/min-document/test/test-dom-comment.js
generated
vendored
20
node_modules/min-document/test/test-dom-comment.js
generated
vendored
@@ -1,20 +0,0 @@
|
||||
var test = require("tape")
|
||||
|
||||
module.exports = testDomComment
|
||||
|
||||
function testDomComment(document) {
|
||||
var cleanup = require('./cleanup')(document)
|
||||
|
||||
test("can createComment", function(assert) {
|
||||
var comment = document.createComment("test")
|
||||
assert.equal(comment.data, "test")
|
||||
assert.equal(comment.length, 4)
|
||||
assert.equal(comment.nodeName, "#comment")
|
||||
assert.equal(comment.nodeType, 8)
|
||||
assert.equal(comment.nodeValue, "test")
|
||||
assert.equal(comment.ownerDocument, document)
|
||||
assert.equal(comment.toString(), "[object Comment]")
|
||||
cleanup()
|
||||
assert.end()
|
||||
})
|
||||
}
|
||||
219
node_modules/min-document/test/test-dom-element.js
generated
vendored
219
node_modules/min-document/test/test-dom-element.js
generated
vendored
@@ -1,219 +0,0 @@
|
||||
var test = require("tape")
|
||||
|
||||
module.exports = testDomElement
|
||||
|
||||
function testDomElement(document) {
|
||||
|
||||
var cleanup = require('./cleanup')(document)
|
||||
|
||||
test("can getElementsByClassName", function(assert) {
|
||||
function append_div(classNames, parent) {
|
||||
var div = document.createElement("div")
|
||||
div.className = classNames
|
||||
parent.appendChild(div)
|
||||
return div
|
||||
}
|
||||
|
||||
function assertMatch(classNames, expectedElements, parent) {
|
||||
var parent = parent || document
|
||||
var result = parent.getElementsByClassName(classNames)
|
||||
assert.equal(result.length, expectedElements.length)
|
||||
for (var i = 0; i < expectedElements.length; i++) {
|
||||
assert.notEqual(expectedElements.indexOf(result[i]), -1)
|
||||
}
|
||||
}
|
||||
|
||||
var divA = append_div("A", document.body)
|
||||
var divB = append_div("B", document.body)
|
||||
var divC = append_div("C", document.body)
|
||||
|
||||
var divA1 = append_div("A1", divA)
|
||||
var divA2 = append_div("A2", divA)
|
||||
var divB1 = append_div("B1", divB)
|
||||
var divB2 = append_div("B2", divB)
|
||||
var divB2a = append_div("B2a", divB2)
|
||||
var divB2b = append_div("B2b", divB2)
|
||||
|
||||
assertMatch("A", [divA])
|
||||
assertMatch("B", [divB])
|
||||
assertMatch("C", [divC])
|
||||
assertMatch("A1", [divA1])
|
||||
assertMatch("A2", [divA2])
|
||||
assertMatch("B1", [divB1])
|
||||
assertMatch("B2", [divB2])
|
||||
assertMatch("B2a", [divB2a])
|
||||
assertMatch("B2b", [divB2b])
|
||||
|
||||
assertMatch("A1", [divA1], divA)
|
||||
assertMatch("A2", [divA2], divA)
|
||||
assertMatch("A1", [], divB)
|
||||
assertMatch("A2", [], divC)
|
||||
assertMatch("B1", [divB1], divB)
|
||||
assertMatch("B2", [divB2], divB)
|
||||
assertMatch("B2a", [divB2a], divB)
|
||||
assertMatch("B2a", [divB2a], divB2)
|
||||
assertMatch("B2b", [], divA)
|
||||
|
||||
cleanup()
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("does not serialize innerText as an attribute", function(assert) {
|
||||
var div = document.createElement("div")
|
||||
div.innerText = "Test <&>"
|
||||
assert.equal(div.toString(), "<div>Test <&></div>")
|
||||
cleanup()
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("does not serialize innerHTML as an attribute", function(assert) {
|
||||
var div = document.createElement("div")
|
||||
div.innerHTML = "Test <img />"
|
||||
assert.equal(div.toString(), "<div>Test <img /></div>")
|
||||
cleanup()
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("can getElementsByTagName", function(assert) {
|
||||
var parent = document.createElement("div")
|
||||
var child1 = document.createElement("span")
|
||||
var child2 = document.createElement("span")
|
||||
|
||||
child1.id = "foo"
|
||||
child2.id = "bar"
|
||||
|
||||
child1.appendChild(child2)
|
||||
parent.appendChild(child1)
|
||||
|
||||
var elems = parent.getElementsByTagName("SPAN")
|
||||
|
||||
assert.equal(elems.length, 2)
|
||||
assert.equal(elems[0].id, "foo")
|
||||
assert.equal(elems[1].id, "bar")
|
||||
|
||||
cleanup()
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("can getElementsByTagName with *", function(assert) {
|
||||
var e1 = document.createElement("div")
|
||||
var e2 = document.createElement("p")
|
||||
var e3 = document.createElement("span")
|
||||
|
||||
e1.appendChild(e2)
|
||||
e2.appendChild(e3)
|
||||
// non-elements should be ignored
|
||||
e3.appendChild(document.createTextNode('foo'))
|
||||
e3.appendChild(document.createComment('bar'))
|
||||
|
||||
var elems = e1.getElementsByTagName("*")
|
||||
|
||||
assert.equal(elems.length, 2)
|
||||
assert.equal(elems[0].tagName, "P")
|
||||
assert.equal(elems[1].tagName, "SPAN")
|
||||
|
||||
cleanup()
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("getElement* methods can be passed to map()", function(assert) {
|
||||
var container = document.createElement("div")
|
||||
var e1 = document.createElement("div")
|
||||
var e2 = document.createElement("span")
|
||||
container.appendChild(e1)
|
||||
container.appendChild(e2)
|
||||
|
||||
assert.deepEqual(
|
||||
["div", "span"].map(container.getElementsByTagName.bind(container)),
|
||||
[[e1], [e2]]
|
||||
)
|
||||
|
||||
e1.className = "foo"
|
||||
e2.className = "bar"
|
||||
|
||||
assert.deepEqual(
|
||||
["foo", "bar"].map(container.getElementsByClassName.bind(container)),
|
||||
[[e1], [e2]]
|
||||
)
|
||||
|
||||
cleanup()
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("can serialize comment nodes", function(assert) {
|
||||
var div = document.createElement("div")
|
||||
div.appendChild(document.createComment("test"))
|
||||
assert.equal(div.toString(), "<div><!--test--></div>")
|
||||
cleanup()
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("can serialize style property", function(assert) {
|
||||
var div = document.createElement("div")
|
||||
div.style.fontSize = "16px"
|
||||
assert.equal(div.toString(), "<div style=\"font-size:16px;\"></div>")
|
||||
cleanup();
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("can serialize style as a string", function(assert) {
|
||||
var div = document.createElement("div")
|
||||
div.setAttribute('style', 'display: none')
|
||||
assert.equal(div.toString(), "<div style=\"display: none\"></div>")
|
||||
cleanup()
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("can serialize text nodes", function(assert) {
|
||||
var div = document.createElement("div")
|
||||
div.appendChild(document.createTextNode('<test> "&'))
|
||||
assert.equal(div.toString(), '<div><test> "&</div>')
|
||||
cleanup()
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("escapes serialized attribute values", function(assert) {
|
||||
var div = document.createElement("div")
|
||||
div.setAttribute("data-foo", '<p>"&')
|
||||
assert.equal(div.toString(), '<div data-foo="<p>"&"></div>')
|
||||
cleanup()
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("can check if an element contains another", function(assert) {
|
||||
var parent = document.createElement("div")
|
||||
var sibling = document.createElement("div")
|
||||
var child1 = document.createElement("div")
|
||||
var child2 = document.createElement("div")
|
||||
|
||||
child1.appendChild(child2)
|
||||
parent.appendChild(child1)
|
||||
|
||||
assert.equal(parent.contains(parent), true)
|
||||
assert.equal(parent.contains(sibling), false)
|
||||
assert.equal(parent.contains(child1), true)
|
||||
assert.equal(parent.contains(child2), true)
|
||||
|
||||
cleanup()
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("can handle non string attribute values", function(assert) {
|
||||
var div = document.createElement("div")
|
||||
div.setAttribute("data-number", 100)
|
||||
div.setAttribute("data-boolean", true)
|
||||
div.setAttribute("data-null", null)
|
||||
assert.equal(div.toString(), '<div data-number="100" data-boolean="true" data-null=""></div>')
|
||||
cleanup()
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test("can serialize textarea correctly", function(assert) {
|
||||
var input = document.createElement("textarea")
|
||||
input.setAttribute("name", "comment")
|
||||
input.innerHTML = "user input here"
|
||||
assert.equal(input.toString(), '<textarea name="comment">user input here</textarea>')
|
||||
cleanup()
|
||||
assert.end()
|
||||
})
|
||||
}
|
||||
21
node_modules/process/.eslintrc
generated
vendored
21
node_modules/process/.eslintrc
generated
vendored
@@ -1,21 +0,0 @@
|
||||
{
|
||||
extends: "eslint:recommended",
|
||||
"env": {
|
||||
"node": true,
|
||||
"browser": true,
|
||||
"es6" : true,
|
||||
"mocha": true
|
||||
},
|
||||
"rules": {
|
||||
"indent": [2, 4],
|
||||
"brace-style": [2, "1tbs"],
|
||||
"quotes": [2, "single"],
|
||||
"no-console": 0,
|
||||
"no-shadow": 0,
|
||||
"no-use-before-define": [2, "nofunc"],
|
||||
"no-underscore-dangle": 0,
|
||||
"no-constant-condition": 0,
|
||||
"space-after-function-name": 0,
|
||||
"consistent-return": 0
|
||||
}
|
||||
}
|
||||
22
node_modules/process/LICENSE
generated
vendored
22
node_modules/process/LICENSE
generated
vendored
@@ -1,22 +0,0 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2013 Roman Shtylman <shtylman@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
26
node_modules/process/README.md
generated
vendored
26
node_modules/process/README.md
generated
vendored
@@ -1,26 +0,0 @@
|
||||
# process
|
||||
|
||||
```require('process');``` just like any other module.
|
||||
|
||||
Works in node.js and browsers via the browser.js shim provided with the module.
|
||||
|
||||
## browser implementation
|
||||
|
||||
The goal of this module is not to be a full-fledged alternative to the builtin process module. This module mostly exists to provide the nextTick functionality and little more. We keep this module lean because it will often be included by default by tools like browserify when it detects a module has used the `process` global.
|
||||
|
||||
It also exposes a "browser" member (i.e. `process.browser`) which is `true` in this implementation but `undefined` in node. This can be used in isomorphic code that adjusts it's behavior depending on which environment it's running in.
|
||||
|
||||
If you are looking to provide other process methods, I suggest you monkey patch them onto the process global in your app. A list of user created patches is below.
|
||||
|
||||
* [hrtime](https://github.com/kumavis/browser-process-hrtime)
|
||||
* [stdout](https://github.com/kumavis/browser-stdout)
|
||||
|
||||
## package manager notes
|
||||
|
||||
If you are writing a bundler to package modules for client side use, make sure you use the ```browser``` field hint in package.json.
|
||||
|
||||
See https://gist.github.com/4339901 for details.
|
||||
|
||||
The [browserify](https://github.com/substack/node-browserify) module will properly handle this field when bundling your files.
|
||||
|
||||
|
||||
184
node_modules/process/browser.js
generated
vendored
184
node_modules/process/browser.js
generated
vendored
@@ -1,184 +0,0 @@
|
||||
// shim for using process in browser
|
||||
var process = module.exports = {};
|
||||
|
||||
// cached from whatever global is present so that test runners that stub it
|
||||
// don't break things. But we need to wrap it in a try catch in case it is
|
||||
// wrapped in strict mode code which doesn't define any globals. It's inside a
|
||||
// function because try/catches deoptimize in certain engines.
|
||||
|
||||
var cachedSetTimeout;
|
||||
var cachedClearTimeout;
|
||||
|
||||
function defaultSetTimout() {
|
||||
throw new Error('setTimeout has not been defined');
|
||||
}
|
||||
function defaultClearTimeout () {
|
||||
throw new Error('clearTimeout has not been defined');
|
||||
}
|
||||
(function () {
|
||||
try {
|
||||
if (typeof setTimeout === 'function') {
|
||||
cachedSetTimeout = setTimeout;
|
||||
} else {
|
||||
cachedSetTimeout = defaultSetTimout;
|
||||
}
|
||||
} catch (e) {
|
||||
cachedSetTimeout = defaultSetTimout;
|
||||
}
|
||||
try {
|
||||
if (typeof clearTimeout === 'function') {
|
||||
cachedClearTimeout = clearTimeout;
|
||||
} else {
|
||||
cachedClearTimeout = defaultClearTimeout;
|
||||
}
|
||||
} catch (e) {
|
||||
cachedClearTimeout = defaultClearTimeout;
|
||||
}
|
||||
} ())
|
||||
function runTimeout(fun) {
|
||||
if (cachedSetTimeout === setTimeout) {
|
||||
//normal enviroments in sane situations
|
||||
return setTimeout(fun, 0);
|
||||
}
|
||||
// if setTimeout wasn't available but was latter defined
|
||||
if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
|
||||
cachedSetTimeout = setTimeout;
|
||||
return setTimeout(fun, 0);
|
||||
}
|
||||
try {
|
||||
// when when somebody has screwed with setTimeout but no I.E. maddness
|
||||
return cachedSetTimeout(fun, 0);
|
||||
} catch(e){
|
||||
try {
|
||||
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
|
||||
return cachedSetTimeout.call(null, fun, 0);
|
||||
} catch(e){
|
||||
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
|
||||
return cachedSetTimeout.call(this, fun, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
function runClearTimeout(marker) {
|
||||
if (cachedClearTimeout === clearTimeout) {
|
||||
//normal enviroments in sane situations
|
||||
return clearTimeout(marker);
|
||||
}
|
||||
// if clearTimeout wasn't available but was latter defined
|
||||
if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
|
||||
cachedClearTimeout = clearTimeout;
|
||||
return clearTimeout(marker);
|
||||
}
|
||||
try {
|
||||
// when when somebody has screwed with setTimeout but no I.E. maddness
|
||||
return cachedClearTimeout(marker);
|
||||
} catch (e){
|
||||
try {
|
||||
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
|
||||
return cachedClearTimeout.call(null, marker);
|
||||
} catch (e){
|
||||
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
|
||||
// Some versions of I.E. have different rules for clearTimeout vs setTimeout
|
||||
return cachedClearTimeout.call(this, marker);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
var queue = [];
|
||||
var draining = false;
|
||||
var currentQueue;
|
||||
var queueIndex = -1;
|
||||
|
||||
function cleanUpNextTick() {
|
||||
if (!draining || !currentQueue) {
|
||||
return;
|
||||
}
|
||||
draining = false;
|
||||
if (currentQueue.length) {
|
||||
queue = currentQueue.concat(queue);
|
||||
} else {
|
||||
queueIndex = -1;
|
||||
}
|
||||
if (queue.length) {
|
||||
drainQueue();
|
||||
}
|
||||
}
|
||||
|
||||
function drainQueue() {
|
||||
if (draining) {
|
||||
return;
|
||||
}
|
||||
var timeout = runTimeout(cleanUpNextTick);
|
||||
draining = true;
|
||||
|
||||
var len = queue.length;
|
||||
while(len) {
|
||||
currentQueue = queue;
|
||||
queue = [];
|
||||
while (++queueIndex < len) {
|
||||
if (currentQueue) {
|
||||
currentQueue[queueIndex].run();
|
||||
}
|
||||
}
|
||||
queueIndex = -1;
|
||||
len = queue.length;
|
||||
}
|
||||
currentQueue = null;
|
||||
draining = false;
|
||||
runClearTimeout(timeout);
|
||||
}
|
||||
|
||||
process.nextTick = function (fun) {
|
||||
var args = new Array(arguments.length - 1);
|
||||
if (arguments.length > 1) {
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
args[i - 1] = arguments[i];
|
||||
}
|
||||
}
|
||||
queue.push(new Item(fun, args));
|
||||
if (queue.length === 1 && !draining) {
|
||||
runTimeout(drainQueue);
|
||||
}
|
||||
};
|
||||
|
||||
// v8 likes predictible objects
|
||||
function Item(fun, array) {
|
||||
this.fun = fun;
|
||||
this.array = array;
|
||||
}
|
||||
Item.prototype.run = function () {
|
||||
this.fun.apply(null, this.array);
|
||||
};
|
||||
process.title = 'browser';
|
||||
process.browser = true;
|
||||
process.env = {};
|
||||
process.argv = [];
|
||||
process.version = ''; // empty string to avoid regexp issues
|
||||
process.versions = {};
|
||||
|
||||
function noop() {}
|
||||
|
||||
process.on = noop;
|
||||
process.addListener = noop;
|
||||
process.once = noop;
|
||||
process.off = noop;
|
||||
process.removeListener = noop;
|
||||
process.removeAllListeners = noop;
|
||||
process.emit = noop;
|
||||
process.prependListener = noop;
|
||||
process.prependOnceListener = noop;
|
||||
|
||||
process.listeners = function (name) { return [] }
|
||||
|
||||
process.binding = function (name) {
|
||||
throw new Error('process.binding is not supported');
|
||||
};
|
||||
|
||||
process.cwd = function () { return '/' };
|
||||
process.chdir = function (dir) {
|
||||
throw new Error('process.chdir is not supported');
|
||||
};
|
||||
process.umask = function() { return 0; };
|
||||
2
node_modules/process/index.js
generated
vendored
2
node_modules/process/index.js
generated
vendored
@@ -1,2 +0,0 @@
|
||||
// for now just expose the builtin process global from node.js
|
||||
module.exports = global.process;
|
||||
27
node_modules/process/package.json
generated
vendored
27
node_modules/process/package.json
generated
vendored
@@ -1,27 +0,0 @@
|
||||
{
|
||||
"author": "Roman Shtylman <shtylman@gmail.com>",
|
||||
"name": "process",
|
||||
"description": "process information for node.js and browsers",
|
||||
"keywords": [
|
||||
"process"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "mocha test.js",
|
||||
"browser": "zuul --no-coverage --ui mocha-bdd --local 8080 -- test.js"
|
||||
},
|
||||
"version": "0.11.10",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/shtylman/node-process.git"
|
||||
},
|
||||
"license": "MIT",
|
||||
"browser": "./browser.js",
|
||||
"main": "./index.js",
|
||||
"engines": {
|
||||
"node": ">= 0.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "2.2.1",
|
||||
"zuul": "^3.10.3"
|
||||
}
|
||||
}
|
||||
199
node_modules/process/test.js
generated
vendored
199
node_modules/process/test.js
generated
vendored
@@ -1,199 +0,0 @@
|
||||
var assert = require('assert');
|
||||
var ourProcess = require('./browser');
|
||||
describe('test against our process', function () {
|
||||
test(ourProcess);
|
||||
});
|
||||
if (!process.browser) {
|
||||
describe('test against node', function () {
|
||||
test(process);
|
||||
});
|
||||
vmtest();
|
||||
}
|
||||
function test (ourProcess) {
|
||||
describe('test arguments', function () {
|
||||
it ('works', function (done) {
|
||||
var order = 0;
|
||||
|
||||
|
||||
ourProcess.nextTick(function (num) {
|
||||
assert.equal(num, order++, 'first one works');
|
||||
ourProcess.nextTick(function (num) {
|
||||
assert.equal(num, order++, 'recursive one is 4th');
|
||||
}, 3);
|
||||
}, 0);
|
||||
ourProcess.nextTick(function (num) {
|
||||
assert.equal(num, order++, 'second one starts');
|
||||
ourProcess.nextTick(function (num) {
|
||||
assert.equal(num, order++, 'this is third');
|
||||
ourProcess.nextTick(function (num) {
|
||||
assert.equal(num, order++, 'this is last');
|
||||
done();
|
||||
}, 5);
|
||||
}, 4);
|
||||
}, 1);
|
||||
ourProcess.nextTick(function (num) {
|
||||
|
||||
assert.equal(num, order++, '3rd schedualed happens after the error');
|
||||
}, 2);
|
||||
});
|
||||
});
|
||||
if (!process.browser) {
|
||||
describe('test errors', function (t) {
|
||||
it ('works', function (done) {
|
||||
var order = 0;
|
||||
process.removeAllListeners('uncaughtException');
|
||||
process.once('uncaughtException', function(err) {
|
||||
assert.equal(2, order++, 'error is third');
|
||||
ourProcess.nextTick(function () {
|
||||
assert.equal(5, order++, 'schedualed in error is last');
|
||||
done();
|
||||
});
|
||||
});
|
||||
ourProcess.nextTick(function () {
|
||||
assert.equal(0, order++, 'first one works');
|
||||
ourProcess.nextTick(function () {
|
||||
assert.equal(4, order++, 'recursive one is 4th');
|
||||
});
|
||||
});
|
||||
ourProcess.nextTick(function () {
|
||||
assert.equal(1, order++, 'second one starts');
|
||||
throw(new Error('an error is thrown'));
|
||||
});
|
||||
ourProcess.nextTick(function () {
|
||||
assert.equal(3, order++, '3rd schedualed happens after the error');
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
describe('rename globals', function (t) {
|
||||
var oldTimeout = setTimeout;
|
||||
var oldClear = clearTimeout;
|
||||
|
||||
it('clearTimeout', function (done){
|
||||
|
||||
var ok = true;
|
||||
clearTimeout = function () {
|
||||
ok = false;
|
||||
}
|
||||
var ran = false;
|
||||
function cleanup() {
|
||||
clearTimeout = oldClear;
|
||||
var err;
|
||||
try {
|
||||
assert.ok(ok, 'fake clearTimeout ran');
|
||||
assert.ok(ran, 'should have run');
|
||||
} catch (e) {
|
||||
err = e;
|
||||
}
|
||||
done(err);
|
||||
}
|
||||
setTimeout(cleanup, 1000);
|
||||
ourProcess.nextTick(function () {
|
||||
ran = true;
|
||||
});
|
||||
});
|
||||
it('just setTimeout', function (done){
|
||||
|
||||
|
||||
setTimeout = function () {
|
||||
setTimeout = oldTimeout;
|
||||
try {
|
||||
assert.ok(false, 'fake setTimeout called')
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ourProcess.nextTick(function () {
|
||||
setTimeout = oldTimeout;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
function vmtest() {
|
||||
var vm = require('vm');
|
||||
var fs = require('fs');
|
||||
var process = fs.readFileSync('./browser.js', {encoding: 'utf8'});
|
||||
|
||||
|
||||
describe('should work in vm in strict mode with no globals', function () {
|
||||
it('should parse', function (done) {
|
||||
var str = '"use strict";var module = {exports:{}};';
|
||||
str += process;
|
||||
str += 'this.works = process.browser;';
|
||||
var script = new vm.Script(str);
|
||||
var context = {
|
||||
works: false
|
||||
};
|
||||
script.runInNewContext(context);
|
||||
assert.ok(context.works);
|
||||
done();
|
||||
});
|
||||
it('setTimeout throws error', function (done) {
|
||||
var str = '"use strict";var module = {exports:{}};';
|
||||
str += process;
|
||||
str += 'try {process.nextTick(function () {})} catch (e){this.works = e;}';
|
||||
var script = new vm.Script(str);
|
||||
var context = {
|
||||
works: false
|
||||
};
|
||||
script.runInNewContext(context);
|
||||
assert.ok(context.works);
|
||||
done();
|
||||
});
|
||||
it('should generally work', function (done) {
|
||||
var str = '"use strict";var module = {exports:{}};';
|
||||
str += process;
|
||||
str += 'process.nextTick(function () {assert.ok(true);done();})';
|
||||
var script = new vm.Script(str);
|
||||
var context = {
|
||||
clearTimeout: clearTimeout,
|
||||
setTimeout: setTimeout,
|
||||
done: done,
|
||||
assert: assert
|
||||
};
|
||||
script.runInNewContext(context);
|
||||
});
|
||||
it('late defs setTimeout', function (done) {
|
||||
var str = '"use strict";var module = {exports:{}};';
|
||||
str += process;
|
||||
str += 'var setTimeout = hiddenSetTimeout;process.nextTick(function () {assert.ok(true);done();})';
|
||||
var script = new vm.Script(str);
|
||||
var context = {
|
||||
clearTimeout: clearTimeout,
|
||||
hiddenSetTimeout: setTimeout,
|
||||
done: done,
|
||||
assert: assert
|
||||
};
|
||||
script.runInNewContext(context);
|
||||
});
|
||||
it('late defs clearTimeout', function (done) {
|
||||
var str = '"use strict";var module = {exports:{}};';
|
||||
str += process;
|
||||
str += 'var clearTimeout = hiddenClearTimeout;process.nextTick(function () {assert.ok(true);done();})';
|
||||
var script = new vm.Script(str);
|
||||
var context = {
|
||||
hiddenClearTimeout: clearTimeout,
|
||||
setTimeout: setTimeout,
|
||||
done: done,
|
||||
assert: assert
|
||||
};
|
||||
script.runInNewContext(context);
|
||||
});
|
||||
it('late defs setTimeout and then redefine', function (done) {
|
||||
var str = '"use strict";var module = {exports:{}};';
|
||||
str += process;
|
||||
str += 'var setTimeout = hiddenSetTimeout;process.nextTick(function () {setTimeout = function (){throw new Error("foo")};hiddenSetTimeout(function(){process.nextTick(function (){assert.ok(true);done();});});});';
|
||||
var script = new vm.Script(str);
|
||||
var context = {
|
||||
clearTimeout: clearTimeout,
|
||||
hiddenSetTimeout: setTimeout,
|
||||
done: done,
|
||||
assert: assert
|
||||
};
|
||||
script.runInNewContext(context);
|
||||
});
|
||||
});
|
||||
}
|
||||
14
node_modules/untildify/index.d.ts
generated
vendored
Normal file
14
node_modules/untildify/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
Convert a tilde path to an absolute path: `~/dev` → `/Users/sindresorhus/dev`.
|
||||
|
||||
@example
|
||||
```
|
||||
import untildify = require('untildify');
|
||||
|
||||
untildify('~/dev');
|
||||
//=> '/Users/sindresorhus/dev'
|
||||
```
|
||||
*/
|
||||
declare function untildify(pathWithTilde: string): string;
|
||||
|
||||
export = untildify;
|
||||
12
node_modules/untildify/index.js
generated
vendored
Normal file
12
node_modules/untildify/index.js
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
'use strict';
|
||||
const os = require('os');
|
||||
|
||||
const homeDirectory = os.homedir();
|
||||
|
||||
module.exports = pathWithTilde => {
|
||||
if (typeof pathWithTilde !== 'string') {
|
||||
throw new TypeError(`Expected a string, got ${typeof pathWithTilde}`);
|
||||
}
|
||||
|
||||
return homeDirectory ? pathWithTilde.replace(/^~(?=$|\/|\\)/, homeDirectory) : pathWithTilde;
|
||||
};
|
||||
9
node_modules/untildify/license
generated
vendored
Normal file
9
node_modules/untildify/license
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
43
node_modules/untildify/package.json
generated
vendored
Normal file
43
node_modules/untildify/package.json
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"name": "untildify",
|
||||
"version": "4.0.0",
|
||||
"description": "Convert a tilde path to an absolute path: `~/dev` → `/Users/sindresorhus/dev`",
|
||||
"license": "MIT",
|
||||
"repository": "sindresorhus/untildify",
|
||||
"author": {
|
||||
"name": "Sindre Sorhus",
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"url": "sindresorhus.com"
|
||||
},
|
||||
"contributors": [
|
||||
"silverwind <me@silverwind.io> (https://silverwind.io)"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "xo && ava && tsd"
|
||||
},
|
||||
"files": [
|
||||
"index.js",
|
||||
"index.d.ts"
|
||||
],
|
||||
"keywords": [
|
||||
"tilde",
|
||||
"expansion",
|
||||
"expand",
|
||||
"untildify",
|
||||
"path",
|
||||
"home",
|
||||
"directory",
|
||||
"user",
|
||||
"shell",
|
||||
"bash"
|
||||
],
|
||||
"devDependencies": {
|
||||
"ava": "^1.4.1",
|
||||
"rewire": "^4.0.1",
|
||||
"tsd": "^0.7.2",
|
||||
"xo": "^0.24.0"
|
||||
}
|
||||
}
|
||||
30
node_modules/untildify/readme.md
generated
vendored
Normal file
30
node_modules/untildify/readme.md
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
# untildify [](https://travis-ci.org/sindresorhus/untildify)
|
||||
|
||||
> Convert a tilde path to an absolute path: `~/dev` → `/Users/sindresorhus/dev`
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
$ npm install untildify
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
const untildify = require('untildify');
|
||||
|
||||
untildify('~/dev');
|
||||
//=> '/Users/sindresorhus/dev'
|
||||
```
|
||||
|
||||
|
||||
## Related
|
||||
|
||||
See [tildify](https://github.com/sindresorhus/tildify) for the inverse.
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Sindre Sorhus](https://sindresorhus.com)
|
||||
@@ -26,9 +26,8 @@
|
||||
"@actions/core": "^1.2.6",
|
||||
"@actions/github": "^4.0.0",
|
||||
"@types/glob": "^7.1.3",
|
||||
"add": "^2.0.6",
|
||||
"glob": "^7.1.4",
|
||||
"global": "^4.4.0"
|
||||
"untildify": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^26.0.20",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {Inputs} from "./Inputs";
|
||||
import {CreateReleaseResponse, Releases, UpdateReleaseResponse} from "./Releases";
|
||||
import {CreateReleaseResponse, ReleaseByTagResponse, Releases, UpdateReleaseResponse} from "./Releases";
|
||||
import {ArtifactUploader} from "./ArtifactUploader";
|
||||
import {ErrorMessage} from "./ErrorMessage";
|
||||
import {GithubError} from "./GithubError";
|
||||
|
||||
export class Action {
|
||||
private inputs: Inputs
|
||||
@@ -27,20 +27,26 @@ export class Action {
|
||||
|
||||
private async createOrUpdateRelease(): Promise<CreateReleaseResponse | UpdateReleaseResponse> {
|
||||
if (this.inputs.allowUpdates) {
|
||||
let getResponse: ReleaseByTagResponse
|
||||
try {
|
||||
const getResponse = await this.releases.getByTag(this.inputs.tag)
|
||||
return await this.updateRelease(getResponse.data.id)
|
||||
getResponse = await this.releases.getByTag(this.inputs.tag)
|
||||
} catch (error) {
|
||||
if (Action.noPublishedRelease(error)) {
|
||||
return await this.updateDraftOrCreateRelease()
|
||||
} else {
|
||||
throw error
|
||||
}
|
||||
return await this.checkForMissingReleaseError(error)
|
||||
}
|
||||
|
||||
return await this.updateRelease(getResponse.data.id)
|
||||
} else {
|
||||
return await this.createRelease()
|
||||
}
|
||||
}
|
||||
|
||||
private async checkForMissingReleaseError(error: Error) : Promise<CreateReleaseResponse | UpdateReleaseResponse> {
|
||||
if (Action.noPublishedRelease(error)) {
|
||||
return await this.updateDraftOrCreateRelease()
|
||||
} else {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
private async updateRelease(id: number): Promise<UpdateReleaseResponse> {
|
||||
return await this.releases.update(
|
||||
@@ -48,6 +54,7 @@ export class Action {
|
||||
this.inputs.tag,
|
||||
this.inputs.updatedReleaseBody,
|
||||
this.inputs.commit,
|
||||
this.inputs.discussionCategory,
|
||||
this.inputs.draft,
|
||||
this.inputs.updatedReleaseName,
|
||||
this.inputs.prerelease
|
||||
@@ -55,8 +62,8 @@ export class Action {
|
||||
}
|
||||
|
||||
private static noPublishedRelease(error: any): boolean {
|
||||
const errorMessage = new ErrorMessage(error)
|
||||
return errorMessage.status == 404
|
||||
const githubError = new GithubError(error)
|
||||
return githubError.status == 404
|
||||
}
|
||||
|
||||
private async updateDraftOrCreateRelease(): Promise<CreateReleaseResponse | UpdateReleaseResponse> {
|
||||
@@ -78,15 +85,14 @@ export class Action {
|
||||
}
|
||||
|
||||
private async createRelease(): Promise<CreateReleaseResponse> {
|
||||
const response = await this.releases.create(
|
||||
return await this.releases.create(
|
||||
this.inputs.tag,
|
||||
this.inputs.createdReleaseBody,
|
||||
this.inputs.commit,
|
||||
this.inputs.discussionCategory,
|
||||
this.inputs.draft,
|
||||
this.inputs.createdReleaseName,
|
||||
this.inputs.prerelease
|
||||
)
|
||||
|
||||
return response
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { Globber, FileGlobber } from "./Globber";
|
||||
import { Artifact } from "./Artifact";
|
||||
import * as core from '@actions/core';
|
||||
import {Globber, FileGlobber} from "./Globber";
|
||||
import {Artifact} from "./Artifact";
|
||||
import untildify from "untildify";
|
||||
|
||||
export interface ArtifactGlobber {
|
||||
globArtifactString(artifact: string, contentType: string): Artifact[]
|
||||
globArtifactString(artifact: string, contentType: string, throwsWhenNoFiles: boolean): Artifact[]
|
||||
}
|
||||
|
||||
export class FileArtifactGlobber implements ArtifactGlobber {
|
||||
@@ -12,11 +14,35 @@ export class FileArtifactGlobber implements ArtifactGlobber {
|
||||
this.globber = globber
|
||||
}
|
||||
|
||||
globArtifactString(artifact: string, contentType: string): Artifact[] {
|
||||
globArtifactString(artifact: string, contentType: string, throwsWhenNoFiles: boolean): Artifact[] {
|
||||
return artifact.split(',')
|
||||
.map((path) => this.globber.glob(path))
|
||||
.map(path => FileArtifactGlobber.expandPath(path))
|
||||
.map(pattern => this.globPattern(pattern, throwsWhenNoFiles))
|
||||
.reduce((accumulated, current) => accumulated.concat(current))
|
||||
.map((path) => new Artifact(path, contentType))
|
||||
.map(path => new Artifact(path, contentType))
|
||||
}
|
||||
}
|
||||
|
||||
private globPattern(pattern: string, throwsWhenNoFiles: boolean): string[] {
|
||||
const paths = this.globber.glob(pattern)
|
||||
if (paths.length == 0) {
|
||||
if (throwsWhenNoFiles) {
|
||||
FileArtifactGlobber.throwGlobError(pattern)
|
||||
} else {
|
||||
FileArtifactGlobber.reportGlobWarning(pattern)
|
||||
}
|
||||
}
|
||||
return paths
|
||||
}
|
||||
|
||||
private static reportGlobWarning(pattern: string) {
|
||||
core.warning(`Artifact pattern :${pattern} did not match any files`)
|
||||
}
|
||||
|
||||
private static throwGlobError(pattern: string) {
|
||||
throw Error(`Artifact pattern :${pattern} did not match any files`)
|
||||
}
|
||||
|
||||
private static expandPath(path: string): string {
|
||||
return untildify(path)
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ export class GithubArtifactUploader implements ArtifactUploader {
|
||||
constructor(
|
||||
private releases: Releases,
|
||||
private replacesExistingArtifacts: boolean = true,
|
||||
private throwsUploadErrors: boolean = false,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -41,7 +42,11 @@ export class GithubArtifactUploader implements ArtifactUploader {
|
||||
core.warning(`Failed to upload artifact ${artifact.name}. ${error.message}. Retrying...`)
|
||||
await this.uploadArtifact(artifact, releaseId, uploadUrl, retry - 1)
|
||||
} else {
|
||||
core.warning(`Failed to upload artifact ${artifact.name}. ${error.message}.`)
|
||||
if (this.throwsUploadErrors) {
|
||||
throw Error(`Failed to upload artifact ${artifact.name}. ${error.message}.`)
|
||||
} else {
|
||||
core.warning(`Failed to upload artifact ${artifact.name}. ${error.message}.`)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
import {GithubError} from "./GithubError"
|
||||
|
||||
export class ErrorMessage {
|
||||
private error: any
|
||||
private githubErrors: GithubError[]
|
||||
|
||||
constructor(error: any) {
|
||||
this.error = error
|
||||
this.githubErrors = this.generateGithubErrors()
|
||||
}
|
||||
|
||||
private generateGithubErrors(): GithubError[] {
|
||||
const errors = this.error.errors
|
||||
if (errors instanceof Array) {
|
||||
return errors.map((err) => new GithubError(err))
|
||||
} else {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
get status(): number {
|
||||
return this.error.status
|
||||
}
|
||||
|
||||
hasErrorWithCode(code: String): boolean {
|
||||
return this.githubErrors.some((err) => err.code == code)
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
const message = this.error.message
|
||||
const errors = this.githubErrors
|
||||
const status = this.status
|
||||
if (errors.length > 0) {
|
||||
return `Error ${status}: ${message}\nErrors:\n${this.errorBulletedList(errors)}`
|
||||
} else {
|
||||
return `Error ${status}: ${message}`
|
||||
}
|
||||
}
|
||||
|
||||
private errorBulletedList(errors: GithubError[]): string {
|
||||
return errors.map((err) => `- ${err}`).join("\n")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,65 +1,44 @@
|
||||
import {GithubErrorDetail} from "./GithubErrorDetail"
|
||||
|
||||
export class GithubError {
|
||||
private error: any;
|
||||
private error: any
|
||||
private readonly githubErrors: GithubErrorDetail[]
|
||||
|
||||
constructor(error: any) {
|
||||
this.error = error
|
||||
this.githubErrors = this.generateGithubErrors()
|
||||
}
|
||||
|
||||
get code(): string {
|
||||
return this.error.code
|
||||
private generateGithubErrors(): GithubErrorDetail[] {
|
||||
const errors = this.error.errors
|
||||
if (errors instanceof Array) {
|
||||
return errors.map((err) => new GithubErrorDetail(err))
|
||||
} else {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
get status(): number {
|
||||
return this.error.status
|
||||
}
|
||||
|
||||
hasErrorWithCode(code: String): boolean {
|
||||
return this.githubErrors.some((err) => err.code == code)
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
const code = this.error.code
|
||||
switch (code) {
|
||||
case 'missing':
|
||||
return this.missingResourceMessage()
|
||||
case 'missing_field':
|
||||
return this.missingFieldMessage()
|
||||
case 'invalid':
|
||||
return this.invalidFieldMessage()
|
||||
case 'already_exists':
|
||||
return this.resourceAlreadyExists()
|
||||
default:
|
||||
return this.customErrorMessage()
|
||||
}
|
||||
}
|
||||
|
||||
private customErrorMessage(): string {
|
||||
const message = this.error.message;
|
||||
const documentation = this.error.documentation_url
|
||||
|
||||
let documentationMessage: string
|
||||
if (documentation) {
|
||||
documentationMessage = `\nPlease see ${documentation}.`
|
||||
const message = this.error.message
|
||||
const errors = this.githubErrors
|
||||
const status = this.status
|
||||
if (errors.length > 0) {
|
||||
return `Error ${status}: ${message}\nErrors:\n${this.errorBulletedList(errors)}`
|
||||
} else {
|
||||
documentationMessage = ""
|
||||
return `Error ${status}: ${message}`
|
||||
}
|
||||
|
||||
return `${message}${documentationMessage}`
|
||||
}
|
||||
|
||||
private invalidFieldMessage(): string {
|
||||
const resource = this.error.resource
|
||||
const field = this.error.field
|
||||
|
||||
return `The ${field} field on ${resource} is an invalid format.`
|
||||
}
|
||||
|
||||
private missingResourceMessage(): string {
|
||||
const resource = this.error.resource
|
||||
return `${resource} does not exist.`
|
||||
}
|
||||
|
||||
private missingFieldMessage(): string {
|
||||
const resource = this.error.resource
|
||||
const field = this.error.field
|
||||
|
||||
return `The ${field} field on ${resource} is missing.`
|
||||
}
|
||||
|
||||
private resourceAlreadyExists(): string {
|
||||
const resource = this.error.resource
|
||||
return `${resource} already exists.`
|
||||
private errorBulletedList(errors: GithubErrorDetail[]): string {
|
||||
return errors.map((err) => `- ${err}`).join("\n")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
65
src/GithubErrorDetail.ts
Normal file
65
src/GithubErrorDetail.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
export class GithubErrorDetail {
|
||||
private error: any;
|
||||
|
||||
constructor(error: any) {
|
||||
this.error = error
|
||||
}
|
||||
|
||||
get code(): string {
|
||||
return this.error.code
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
const code = this.error.code
|
||||
switch (code) {
|
||||
case 'missing':
|
||||
return this.missingResourceMessage()
|
||||
case 'missing_field':
|
||||
return this.missingFieldMessage()
|
||||
case 'invalid':
|
||||
return this.invalidFieldMessage()
|
||||
case 'already_exists':
|
||||
return this.resourceAlreadyExists()
|
||||
default:
|
||||
return this.customErrorMessage()
|
||||
}
|
||||
}
|
||||
|
||||
private customErrorMessage(): string {
|
||||
const message = this.error.message;
|
||||
const documentation = this.error.documentation_url
|
||||
|
||||
let documentationMessage: string
|
||||
if (documentation) {
|
||||
documentationMessage = `\nPlease see ${documentation}.`
|
||||
} else {
|
||||
documentationMessage = ""
|
||||
}
|
||||
|
||||
return `${message}${documentationMessage}`
|
||||
}
|
||||
|
||||
private invalidFieldMessage(): string {
|
||||
const resource = this.error.resource
|
||||
const field = this.error.field
|
||||
|
||||
return `The ${field} field on ${resource} is an invalid format.`
|
||||
}
|
||||
|
||||
private missingResourceMessage(): string {
|
||||
const resource = this.error.resource
|
||||
return `${resource} does not exist.`
|
||||
}
|
||||
|
||||
private missingFieldMessage(): string {
|
||||
const resource = this.error.resource
|
||||
const field = this.error.field
|
||||
|
||||
return `The ${field} field on ${resource} is missing.`
|
||||
}
|
||||
|
||||
private resourceAlreadyExists(): string {
|
||||
const resource = this.error.resource
|
||||
return `${resource} already exists.`
|
||||
}
|
||||
}
|
||||
@@ -6,10 +6,12 @@ import {Artifact} from './Artifact';
|
||||
|
||||
export interface Inputs {
|
||||
readonly allowUpdates: boolean
|
||||
readonly artifactErrorsFailBuild: boolean
|
||||
readonly artifacts: Artifact[]
|
||||
readonly commit: string
|
||||
readonly createdReleaseBody?: string
|
||||
readonly createdReleaseName?: string
|
||||
readonly discussionCategory?: string
|
||||
readonly draft: boolean
|
||||
readonly owner: string
|
||||
readonly prerelease: boolean
|
||||
@@ -46,11 +48,16 @@ export class CoreInputs implements Inputs {
|
||||
contentType = 'raw'
|
||||
}
|
||||
return this.artifactGlobber
|
||||
.globArtifactString(artifacts, contentType)
|
||||
.globArtifactString(artifacts, contentType, this.artifactErrorsFailBuild)
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
get artifactErrorsFailBuild(): boolean {
|
||||
const allow = core.getInput('artifactErrorsFailBuild')
|
||||
return allow == 'true'
|
||||
}
|
||||
|
||||
get createdReleaseBody(): string | undefined {
|
||||
if (CoreInputs.omitBody) return undefined
|
||||
return this.body
|
||||
@@ -60,7 +67,7 @@ export class CoreInputs implements Inputs {
|
||||
return core.getInput('omitBody') == 'true'
|
||||
}
|
||||
|
||||
private get body() : string | undefined {
|
||||
private get body(): string | undefined {
|
||||
const body = core.getInput('body')
|
||||
if (body) {
|
||||
return body
|
||||
@@ -83,6 +90,14 @@ export class CoreInputs implements Inputs {
|
||||
return this.name
|
||||
}
|
||||
|
||||
get discussionCategory(): string | undefined {
|
||||
const category = core.getInput('discussionCategory')
|
||||
if (category) {
|
||||
return category
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
private static get omitName(): boolean {
|
||||
return core.getInput('omitName') == 'true'
|
||||
}
|
||||
@@ -156,7 +171,7 @@ export class CoreInputs implements Inputs {
|
||||
}
|
||||
|
||||
get updatedReleaseName(): string | undefined {
|
||||
if (CoreInputs.omitName || CoreInputs.omitNameDuringUpdate) return undefined
|
||||
if (CoreInputs.omitName || CoreInputs.omitNameDuringUpdate) return undefined
|
||||
return this.name
|
||||
}
|
||||
|
||||
|
||||
@@ -5,15 +5,15 @@ import { GithubReleases } from './Releases';
|
||||
import { Action } from './Action';
|
||||
import { GithubArtifactUploader } from './ArtifactUploader';
|
||||
import { FileArtifactGlobber } from './ArtifactGlobber';
|
||||
import { ErrorMessage } from './ErrorMessage';
|
||||
import { GithubError } from './GithubError';
|
||||
|
||||
async function run() {
|
||||
try {
|
||||
const action = createAction()
|
||||
await action.perform()
|
||||
} catch (error) {
|
||||
const errorMessage = new ErrorMessage(error)
|
||||
core.setFailed(errorMessage.toString());
|
||||
const githubError = new GithubError(error)
|
||||
core.setFailed(githubError.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ function createAction(): Action {
|
||||
|
||||
const inputs = new CoreInputs(globber, context)
|
||||
const releases = new GithubReleases(inputs, git)
|
||||
const uploader = new GithubArtifactUploader(releases, inputs.replacesArtifacts)
|
||||
const uploader = new GithubArtifactUploader(releases, inputs.replacesArtifacts, inputs.artifactErrorsFailBuild)
|
||||
return new Action(inputs, releases, uploader)
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ export interface Releases {
|
||||
tag: string,
|
||||
body?: string,
|
||||
commitHash?: string,
|
||||
discussionCategory?: string,
|
||||
draft?: boolean,
|
||||
name?: string,
|
||||
prerelease?: boolean
|
||||
@@ -33,6 +34,7 @@ export interface Releases {
|
||||
tag: string,
|
||||
body?: string,
|
||||
commitHash?: string,
|
||||
discussionCategory?: string,
|
||||
draft?: boolean,
|
||||
name?: string,
|
||||
prerelease?: boolean
|
||||
@@ -61,6 +63,7 @@ export class GithubReleases implements Releases {
|
||||
tag: string,
|
||||
body?: string,
|
||||
commitHash?: string,
|
||||
discussionCategory?: string,
|
||||
draft?: boolean,
|
||||
name?: string,
|
||||
prerelease?: boolean
|
||||
@@ -69,6 +72,7 @@ export class GithubReleases implements Releases {
|
||||
return this.git.repos.createRelease({
|
||||
body: body,
|
||||
name: name,
|
||||
discussion_category_name: discussionCategory,
|
||||
draft: draft,
|
||||
owner: this.inputs.owner,
|
||||
prerelease: prerelease,
|
||||
@@ -118,6 +122,7 @@ export class GithubReleases implements Releases {
|
||||
tag: string,
|
||||
body?: string,
|
||||
commitHash?: string,
|
||||
discussionCategory?: string,
|
||||
draft?: boolean,
|
||||
name?: string,
|
||||
prerelease?: boolean
|
||||
@@ -127,6 +132,7 @@ export class GithubReleases implements Releases {
|
||||
release_id: id,
|
||||
body: body,
|
||||
name: name,
|
||||
discussion_category_name: discussionCategory,
|
||||
draft: draft,
|
||||
owner: this.inputs.owner,
|
||||
prerelease: prerelease,
|
||||
|
||||
35
yarn.lock
35
yarn.lock
@@ -724,11 +724,6 @@ acorn@^7.1.1:
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
|
||||
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
|
||||
|
||||
add@^2.0.6:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/add/-/add-2.0.6.tgz#248f0a9f6e5a528ef2295dbeec30532130ae2235"
|
||||
integrity sha1-JI8Kn25aUo7yKV2+7DBTITCuIjU=
|
||||
|
||||
ajv@^6.12.3:
|
||||
version "6.12.6"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
|
||||
@@ -1299,11 +1294,6 @@ diff-sequences@^26.6.2:
|
||||
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1"
|
||||
integrity sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==
|
||||
|
||||
dom-walk@^0.1.0:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84"
|
||||
integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==
|
||||
|
||||
domexception@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304"
|
||||
@@ -1628,14 +1618,6 @@ glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4:
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
global@^4.4.0:
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406"
|
||||
integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==
|
||||
dependencies:
|
||||
min-document "^2.19.0"
|
||||
process "^0.11.10"
|
||||
|
||||
globals@^11.1.0:
|
||||
version "11.12.0"
|
||||
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
|
||||
@@ -2645,13 +2627,6 @@ mimic-fn@^2.1.0:
|
||||
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
|
||||
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
|
||||
|
||||
min-document@^2.19.0:
|
||||
version "2.19.0"
|
||||
resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685"
|
||||
integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=
|
||||
dependencies:
|
||||
dom-walk "^0.1.0"
|
||||
|
||||
minimatch@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||
@@ -2954,11 +2929,6 @@ pretty-format@^26.0.0, pretty-format@^26.6.2:
|
||||
ansi-styles "^4.0.0"
|
||||
react-is "^17.0.1"
|
||||
|
||||
process@^0.11.10:
|
||||
version "0.11.10"
|
||||
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
|
||||
integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI=
|
||||
|
||||
prompts@^2.0.1:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.0.tgz#4aa5de0723a231d1ee9121c40fdf663df73f61d7"
|
||||
@@ -3643,6 +3613,11 @@ unset-value@^1.0.0:
|
||||
has-value "^0.3.1"
|
||||
isobject "^3.0.0"
|
||||
|
||||
untildify@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b"
|
||||
integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==
|
||||
|
||||
uri-js@^4.2.2:
|
||||
version "4.4.1"
|
||||
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
|
||||
|
||||
Reference in New Issue
Block a user