Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4c1d33eaa1 |
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,38 +0,0 @@
|
||||
---
|
||||
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
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,20 +0,0 @@
|
||||
---
|
||||
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
28
.github/workflows/build.yml
vendored
@@ -1,28 +0,0 @@
|
||||
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
Normal file
25
.github/workflows/checkin.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
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
14
.github/workflows/test.yml
vendored
@@ -1,14 +0,0 @@
|
||||
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
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,4 +1,4 @@
|
||||
# node_modules/
|
||||
#node_modules/
|
||||
__tests__/runner/*
|
||||
|
||||
# Created by https://www.gitignore.io/api/webstorm
|
||||
|
||||
@@ -4,14 +4,12 @@ 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.
|
||||
@@ -25,11 +23,6 @@ This action will create a github release and optionally upload an artifact to it
|
||||
- **tag**: An optional tag for the release. If this is omitted the git ref will be used (if it is a tag).
|
||||
- **token**: (**Required**) The Github token. Typically this will be `${{ secrets.GITHUB_TOKEN }}`.
|
||||
|
||||
## Action Outputs
|
||||
- **id**: The identifier of the created release.
|
||||
- **html_url**: The HTML URL of the release.
|
||||
- **upload_url**: The URL for uploading assets to the release.
|
||||
|
||||
## Example
|
||||
This example will create a release when tag is pushed:
|
||||
|
||||
|
||||
@@ -3,9 +3,7 @@ import {Artifact} from "../src/Artifact";
|
||||
import {Inputs} from "../src/Inputs";
|
||||
import {Releases} from "../src/Releases";
|
||||
import {ArtifactUploader} from "../src/ArtifactUploader";
|
||||
import {Outputs} from "../src/Outputs";
|
||||
|
||||
const applyReleaseDataMock = jest.fn()
|
||||
const createMock = jest.fn()
|
||||
const deleteMock = jest.fn()
|
||||
const getMock = jest.fn()
|
||||
@@ -22,7 +20,6 @@ const artifacts = [
|
||||
const createBody = 'createBody'
|
||||
const createName = 'createName'
|
||||
const commit = 'commit'
|
||||
const discussionCategory = 'discussionCategory'
|
||||
const draft = true
|
||||
const id = 100
|
||||
const prerelease = true
|
||||
@@ -48,9 +45,8 @@ describe("Action", () => {
|
||||
|
||||
await action.perform()
|
||||
|
||||
expect(createMock).toBeCalledWith(tag, createBody, commit, discussionCategory, draft, createName, prerelease)
|
||||
expect(createMock).toBeCalledWith(tag, createBody, commit, draft, createName, prerelease)
|
||||
expect(uploadMock).not.toBeCalled()
|
||||
assertOutputApplied()
|
||||
})
|
||||
|
||||
it('creates release if no release exists to update', async () => {
|
||||
@@ -60,9 +56,8 @@ describe("Action", () => {
|
||||
|
||||
await action.perform()
|
||||
|
||||
expect(createMock).toBeCalledWith(tag, createBody, commit, discussionCategory, draft, createName, prerelease)
|
||||
expect(createMock).toBeCalledWith(tag, createBody, commit, draft, createName, prerelease)
|
||||
expect(uploadMock).toBeCalledWith(artifacts, releaseId, url)
|
||||
assertOutputApplied()
|
||||
})
|
||||
|
||||
it('creates release if no draft releases', async () => {
|
||||
@@ -77,9 +72,8 @@ describe("Action", () => {
|
||||
|
||||
await action.perform()
|
||||
|
||||
expect(createMock).toBeCalledWith(tag, createBody, commit, discussionCategory, draft, createName, prerelease)
|
||||
expect(createMock).toBeCalledWith(tag, createBody, commit, draft, createName, prerelease)
|
||||
expect(uploadMock).toBeCalledWith(artifacts, releaseId, url)
|
||||
assertOutputApplied()
|
||||
|
||||
})
|
||||
|
||||
@@ -88,9 +82,8 @@ describe("Action", () => {
|
||||
|
||||
await action.perform()
|
||||
|
||||
expect(createMock).toBeCalledWith(tag, createBody, commit, discussionCategory, draft, createName, prerelease)
|
||||
expect(createMock).toBeCalledWith(tag, createBody, commit, draft, createName, prerelease)
|
||||
expect(uploadMock).toBeCalledWith(artifacts, releaseId, url)
|
||||
assertOutputApplied()
|
||||
})
|
||||
|
||||
it('throws error when create fails', async () => {
|
||||
@@ -104,7 +97,7 @@ describe("Action", () => {
|
||||
expect(error).toEqual("error")
|
||||
}
|
||||
|
||||
expect(createMock).toBeCalledWith(tag, createBody, commit, discussionCategory, draft, createName, prerelease)
|
||||
expect(createMock).toBeCalledWith(tag, createBody, commit, draft, createName, prerelease)
|
||||
expect(uploadMock).not.toBeCalled()
|
||||
})
|
||||
|
||||
@@ -145,32 +138,22 @@ describe("Action", () => {
|
||||
expect(error).toEqual("error")
|
||||
}
|
||||
|
||||
expect(updateMock).toBeCalledWith(
|
||||
id,
|
||||
tag,
|
||||
updateBody,
|
||||
commit,
|
||||
discussionCategory,
|
||||
draft,
|
||||
updateName,
|
||||
prerelease
|
||||
)
|
||||
expect(updateMock).toBeCalledWith(id, tag, updateBody, commit, draft, updateName, prerelease)
|
||||
expect(uploadMock).not.toBeCalled()
|
||||
})
|
||||
|
||||
it('throws error when upload fails', async () => {
|
||||
const action = createAction(false, true)
|
||||
const expectedError = {status: 404}
|
||||
uploadMock.mockRejectedValue(expectedError)
|
||||
uploadMock.mockRejectedValue("error")
|
||||
|
||||
expect.hasAssertions()
|
||||
try {
|
||||
await action.perform()
|
||||
} catch (error) {
|
||||
expect(error).toEqual(expectedError)
|
||||
expect(error).toEqual("error")
|
||||
}
|
||||
|
||||
expect(createMock).toBeCalledWith(tag, createBody, commit, discussionCategory, draft, createName, prerelease)
|
||||
expect(createMock).toBeCalledWith(tag, createBody, commit, draft, createName, prerelease)
|
||||
expect(uploadMock).toBeCalledWith(artifacts, releaseId, url)
|
||||
})
|
||||
|
||||
@@ -187,18 +170,9 @@ describe("Action", () => {
|
||||
|
||||
await action.perform()
|
||||
|
||||
expect(updateMock).toBeCalledWith(
|
||||
id,
|
||||
tag,
|
||||
updateBody,
|
||||
commit,
|
||||
discussionCategory,
|
||||
draft,
|
||||
updateName,
|
||||
prerelease
|
||||
)
|
||||
expect(updateMock).toBeCalledWith(id, tag, updateBody, commit, draft, updateName, prerelease)
|
||||
expect(uploadMock).toBeCalledWith(artifacts, releaseId, url)
|
||||
assertOutputApplied()
|
||||
|
||||
})
|
||||
|
||||
it('updates release but does not upload if no artifact', async () => {
|
||||
@@ -206,18 +180,9 @@ describe("Action", () => {
|
||||
|
||||
await action.perform()
|
||||
|
||||
expect(updateMock).toBeCalledWith(
|
||||
id,
|
||||
tag,
|
||||
updateBody,
|
||||
commit,
|
||||
discussionCategory,
|
||||
draft,
|
||||
updateName,
|
||||
prerelease
|
||||
)
|
||||
expect(updateMock).toBeCalledWith(id, tag, updateBody, commit, draft, updateName, prerelease)
|
||||
expect(uploadMock).not.toBeCalled()
|
||||
assertOutputApplied()
|
||||
|
||||
})
|
||||
|
||||
it('updates release then uploads artifact', async () => {
|
||||
@@ -225,23 +190,10 @@ describe("Action", () => {
|
||||
|
||||
await action.perform()
|
||||
|
||||
expect(updateMock).toBeCalledWith(
|
||||
id,
|
||||
tag,
|
||||
updateBody,
|
||||
commit,
|
||||
discussionCategory,
|
||||
draft,
|
||||
updateName,
|
||||
prerelease
|
||||
)
|
||||
expect(updateMock).toBeCalledWith(id, tag, updateBody, commit, draft, updateName, prerelease)
|
||||
expect(uploadMock).toBeCalledWith(artifacts, releaseId, url)
|
||||
assertOutputApplied()
|
||||
})
|
||||
|
||||
function assertOutputApplied() {
|
||||
expect(applyReleaseDataMock).toBeCalledWith({id: releaseId, upload_url: url})
|
||||
}
|
||||
})
|
||||
|
||||
function createAction(allowUpdates: boolean, hasArtifact: boolean): Action {
|
||||
let inputArtifact: Artifact[]
|
||||
@@ -287,12 +239,10 @@ 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,
|
||||
@@ -304,11 +254,6 @@ describe("Action", () => {
|
||||
updatedReleaseName: updateName
|
||||
}
|
||||
})
|
||||
const MockOutputs = jest.fn<Outputs, any>(() => {
|
||||
return {
|
||||
applyReleaseData: applyReleaseDataMock
|
||||
}
|
||||
})
|
||||
const MockUploader = jest.fn<ArtifactUploader, any>(() => {
|
||||
return {
|
||||
uploadArtifacts: uploadMock
|
||||
@@ -316,10 +261,9 @@ describe("Action", () => {
|
||||
})
|
||||
|
||||
const inputs = new MockInputs()
|
||||
const outputs = new MockOutputs()
|
||||
const releases = new MockReleases()
|
||||
const uploader = new MockUploader()
|
||||
|
||||
return new Action(inputs, outputs, releases, uploader)
|
||||
return new Action(inputs, releases, uploader)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,57 +1,19 @@
|
||||
const warnMock = jest.fn()
|
||||
|
||||
import {FileArtifactGlobber} from "../src/ArtifactGlobber"
|
||||
import {Globber} from "../src/Globber";
|
||||
import {Artifact} from "../src/Artifact";
|
||||
import untildify = require("untildify");
|
||||
import { FileArtifactGlobber } from "../src/ArtifactGlobber"
|
||||
import { Globber } from "../src/Globber";
|
||||
import { Artifact } from "../src/Artifact";
|
||||
|
||||
const contentType = "raw"
|
||||
const globMock = jest.fn()
|
||||
const globResults = ["file1", "file2"]
|
||||
|
||||
jest.mock('@actions/core', () => {
|
||||
return {warning: warnMock};
|
||||
})
|
||||
|
||||
jest.mock('fs', () => {
|
||||
return {
|
||||
statSync: () => {
|
||||
return {
|
||||
isDirectory(): boolean {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
})
|
||||
|
||||
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', false))
|
||||
expect(globber.globArtifactString('path', 'raw'))
|
||||
.toEqual(expectedArtifacts)
|
||||
expect(globMock).toBeCalledWith('path')
|
||||
expect(warnMock).not.toBeCalled()
|
||||
})
|
||||
|
||||
it("splits multiple paths", () => {
|
||||
@@ -62,35 +24,16 @@ describe("ArtifactGlobber", () => {
|
||||
.concat(globResults)
|
||||
.map((path) => new Artifact(path, contentType))
|
||||
|
||||
expect(globber.globArtifactString('path1,path2', 'raw', false))
|
||||
expect(globber.globArtifactString('path1,path2', 'raw'))
|
||||
.toEqual(expectedArtifacts)
|
||||
expect(globMock).toBeCalledWith('path1')
|
||||
expect(globMock).toBeCalledWith('path2')
|
||||
expect(warnMock).not.toBeCalled()
|
||||
})
|
||||
|
||||
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 {
|
||||
function createArtifactGlobber(): FileArtifactGlobber {
|
||||
const MockGlobber = jest.fn<Globber, any>(() => {
|
||||
return {
|
||||
glob: globMock
|
||||
glob: () => globResults
|
||||
}
|
||||
})
|
||||
globMock.mockReturnValue(results)
|
||||
return new FileArtifactGlobber(new MockGlobber())
|
||||
}
|
||||
})
|
||||
@@ -1,60 +0,0 @@
|
||||
const directoryMock = jest.fn()
|
||||
const warnMock = jest.fn()
|
||||
|
||||
import {ArtifactPathValidator} from "../src/ArtifactPathValidator";
|
||||
|
||||
const pattern = 'pattern'
|
||||
|
||||
jest.mock('@actions/core', () => {
|
||||
return {warning: warnMock};
|
||||
})
|
||||
|
||||
jest.mock('fs', () => {
|
||||
return {
|
||||
statSync: () => {
|
||||
return {isDirectory: directoryMock}
|
||||
}
|
||||
};
|
||||
})
|
||||
|
||||
describe("ArtifactPathValidator", () => {
|
||||
beforeEach(() => {
|
||||
warnMock.mockClear()
|
||||
directoryMock.mockClear()
|
||||
})
|
||||
|
||||
it("warns and filters out path which points to a directory", () => {
|
||||
const paths = ['path1', 'path2']
|
||||
directoryMock.mockReturnValueOnce(true).mockReturnValueOnce(false)
|
||||
|
||||
const validator = new ArtifactPathValidator(false, paths, pattern)
|
||||
|
||||
const result = validator.validate()
|
||||
expect(warnMock).toBeCalled()
|
||||
expect(result).toEqual(['path2'])
|
||||
})
|
||||
|
||||
it("warns when no glob results are produced and empty results shouldn't throw", () => {
|
||||
const validator = new ArtifactPathValidator(false, [], pattern)
|
||||
const result = validator.validate()
|
||||
expect(warnMock).toBeCalled()
|
||||
})
|
||||
|
||||
it("throws when no glob results are produced and empty results shouild throw", () => {
|
||||
const validator = new ArtifactPathValidator(true, [], pattern)
|
||||
expect(() => {
|
||||
validator.validate()
|
||||
}).toThrow()
|
||||
})
|
||||
|
||||
it("throws when path points to directory", () => {
|
||||
const paths = ['path1', 'path2']
|
||||
directoryMock.mockReturnValueOnce(true).mockReturnValueOnce(false)
|
||||
|
||||
const validator = new ArtifactPathValidator(true, paths, pattern)
|
||||
|
||||
expect(() => {
|
||||
validator.validate()
|
||||
}).toThrow()
|
||||
})
|
||||
})
|
||||
@@ -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,9 +19,7 @@ const uploadMock = jest.fn()
|
||||
jest.mock('fs', () => {
|
||||
return {
|
||||
readFileSync: () => fileContents,
|
||||
statSync: () => {
|
||||
return {size: contentLength}
|
||||
}
|
||||
statSync: () => { return { size: contentLength } }
|
||||
};
|
||||
})
|
||||
|
||||
@@ -126,19 +124,6 @@ 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()
|
||||
@@ -170,7 +155,7 @@ describe('ArtifactUploader', () => {
|
||||
expect(deleteMock).toBeCalledTimes(0)
|
||||
})
|
||||
|
||||
function createUploader(replaces: boolean, throws: boolean = false): GithubArtifactUploader {
|
||||
function createUploader(replaces: boolean): GithubArtifactUploader {
|
||||
const MockReleases = jest.fn<Releases, any>(() => {
|
||||
return {
|
||||
create: jest.fn(),
|
||||
@@ -182,7 +167,7 @@ describe('ArtifactUploader', () => {
|
||||
uploadArtifact: uploadMock
|
||||
}
|
||||
})
|
||||
return new GithubArtifactUploader(new MockReleases(), replaces, throws)
|
||||
return new GithubArtifactUploader(new MockReleases(), replaces)
|
||||
}
|
||||
|
||||
function mockDeleteError(): any {
|
||||
@@ -194,37 +179,29 @@ describe('ArtifactUploader', () => {
|
||||
}
|
||||
|
||||
function mockListWithAssets() {
|
||||
listArtifactsMock.mockResolvedValue([
|
||||
{
|
||||
name: "art1",
|
||||
id: 1
|
||||
},
|
||||
{
|
||||
name: "art2",
|
||||
id: 2
|
||||
}
|
||||
])
|
||||
listArtifactsMock.mockResolvedValue({
|
||||
data: [
|
||||
{
|
||||
name: "art1",
|
||||
id: 1
|
||||
},
|
||||
{
|
||||
name: "art2",
|
||||
id: 2
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
function mockListWithoutAssets() {
|
||||
listArtifactsMock.mockResolvedValue([])
|
||||
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
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
70
__tests__/ErrorMessage.test.ts
Normal file
70
__tests__/ErrorMessage.test.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
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,70 +1,99 @@
|
||||
import { GithubError } from "../src/GithubError"
|
||||
|
||||
describe('ErrorMessage', () => {
|
||||
describe('GithubError', () => {
|
||||
|
||||
describe('has error with code', () => {
|
||||
it('provides error code', () => {
|
||||
const error = {
|
||||
message: 'something bad happened',
|
||||
errors: [
|
||||
{
|
||||
code: 'missing',
|
||||
resource: 'release'
|
||||
},
|
||||
{
|
||||
code: 'already_exists',
|
||||
resource: 'release'
|
||||
}
|
||||
],
|
||||
status: 422
|
||||
code: "missing"
|
||||
}
|
||||
|
||||
it('does not have error', () => {
|
||||
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
|
||||
}
|
||||
|
||||
const githubError = new GithubError(error)
|
||||
expect(githubError.hasErrorWithCode('missing_field')).toBeFalsy()
|
||||
const message = githubError.toString()
|
||||
|
||||
expect(message).toBe(`foo\nPlease see ${url}.`)
|
||||
})
|
||||
|
||||
it('has error', () => {
|
||||
it('without documentation url', () => {
|
||||
const error = {
|
||||
code: "custom",
|
||||
message: "foo"
|
||||
}
|
||||
|
||||
const githubError = new GithubError(error)
|
||||
expect(githubError.hasErrorWithCode('missing')).toBeTruthy()
|
||||
const message = githubError.toString()
|
||||
|
||||
expect(message).toBe('foo')
|
||||
})
|
||||
})
|
||||
|
||||
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)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1,98 +0,0 @@
|
||||
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,28 +59,7 @@ 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('')
|
||||
@@ -92,32 +71,28 @@ 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', false)
|
||||
expect(mockGlob).toBeCalledWith('art1', 'contentType')
|
||||
})
|
||||
|
||||
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', false)
|
||||
expect(mockGlob).toBeCalledWith('art1', 'raw')
|
||||
})
|
||||
|
||||
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', false)
|
||||
expect(mockGlob).toBeCalledWith('art2', 'contentType')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -179,18 +154,6 @@ 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)
|
||||
@@ -201,7 +164,7 @@ describe('Inputs', () => {
|
||||
expect(inputs.draft).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
describe('owner', () => {
|
||||
it('returns owner from context', function () {
|
||||
process.env.GITHUB_REPOSITORY = "owner/repo"
|
||||
@@ -212,7 +175,7 @@ describe('Inputs', () => {
|
||||
mockGetInput.mockReturnValue("owner")
|
||||
expect(inputs.owner).toBe("owner")
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
describe('prerelase', () => {
|
||||
it('returns false', () => {
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import {Action} from "../src/Action";
|
||||
import * as github from "@actions/github";
|
||||
import {Inputs} from "../src/Inputs";
|
||||
import {GithubReleases, ReleaseData} from "../src/Releases";
|
||||
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";
|
||||
import {Outputs} from "../src/Outputs";
|
||||
|
||||
// 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,14 +17,9 @@ describe.skip('Integration Test', () => {
|
||||
const git = github.getOctokit(token)
|
||||
|
||||
const inputs = getInputs()
|
||||
const outputs = getOutputs()
|
||||
const releases = new GithubReleases(inputs, git)
|
||||
const uploader = new GithubArtifactUploader(
|
||||
releases,
|
||||
inputs.replacesArtifacts,
|
||||
inputs.artifactErrorsFailBuild,
|
||||
)
|
||||
action = new Action(inputs, outputs, releases, uploader)
|
||||
const uploader = new GithubArtifactUploader(releases, inputs.replacesArtifacts)
|
||||
action = new Action(inputs, releases, uploader)
|
||||
})
|
||||
|
||||
it('Performs action', async () => {
|
||||
@@ -33,47 +27,29 @@ 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,
|
||||
artifactErrorsFailBuild: false,
|
||||
artifacts: artifacts(),
|
||||
createdReleaseBody: "This release was generated by release-action's integration test",
|
||||
createdReleaseName: "Releases Action Integration Test 2",
|
||||
artifacts: [new Artifact(artifactPath)],
|
||||
createdReleaseBody: "release body",
|
||||
createdReleaseName: "release name",
|
||||
commit: "",
|
||||
discussionCategory: 'Release',
|
||||
draft: false,
|
||||
owner: "ncipollo",
|
||||
prerelease: false,
|
||||
prerelease: true,
|
||||
replacesArtifacts: true,
|
||||
repo: "actions-playground",
|
||||
tag: "release-action-test",
|
||||
tag: "0.0.71",
|
||||
token: getToken(),
|
||||
updatedReleaseBody: "This release was generated by release-action's integration test",
|
||||
updatedReleaseName: "Releases Action Integration Test 2"
|
||||
updatedReleaseBody: "updated body",
|
||||
updatedReleaseName: "updated name"
|
||||
}
|
||||
})
|
||||
return new MockInputs();
|
||||
}
|
||||
|
||||
function getOutputs(): Outputs {
|
||||
const MockOutputs = jest.fn<Outputs, any>(() => {
|
||||
return {
|
||||
applyReleaseData(releaseData: ReleaseData) {
|
||||
console.log(`Release Data: ${releaseData}`)
|
||||
}
|
||||
}
|
||||
})
|
||||
return new MockOutputs()
|
||||
}
|
||||
|
||||
function artifacts() {
|
||||
const globber = new FileArtifactGlobber()
|
||||
const artifactPath = path.join(__dirname, 'Integration.test.ts')
|
||||
const artifactString = `~/Desktop,~/Desktop/test.txt,blarg.tx, ${artifactPath}`
|
||||
return globber.globArtifactString(artifactString, "raw", false)
|
||||
}
|
||||
|
||||
function getToken(): string {
|
||||
return process.env.GITHUB_TOKEN ?? ""
|
||||
}
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
const mockSetOutput = jest.fn();
|
||||
|
||||
import {CoreOutputs, Outputs} from "../src/Outputs";
|
||||
import {ReleaseData} from "../src/Releases";
|
||||
|
||||
jest.mock('@actions/core', () => {
|
||||
return {setOutput: mockSetOutput};
|
||||
})
|
||||
|
||||
describe('Outputs', () => {
|
||||
let outputs: Outputs;
|
||||
let releaseData: ReleaseData
|
||||
|
||||
beforeEach(() => {
|
||||
outputs = new CoreOutputs()
|
||||
releaseData = {
|
||||
id: 1,
|
||||
html_url: 'https://api.example.com/assets',
|
||||
upload_url: 'https://api.example.com'
|
||||
}
|
||||
})
|
||||
|
||||
it('Applies the release data to the action output', () => {
|
||||
outputs.applyReleaseData(releaseData)
|
||||
expect(mockSetOutput).toBeCalledWith('id', releaseData.id)
|
||||
expect(mockSetOutput).toBeCalledWith('html_url', releaseData.html_url)
|
||||
expect(mockSetOutput).toBeCalledWith('upload_url', releaseData.upload_url)
|
||||
})
|
||||
})
|
||||
15
action.yml
15
action.yml
@@ -6,10 +6,6 @@ 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)'
|
||||
@@ -34,10 +30,6 @@ 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."
|
||||
@@ -87,13 +79,6 @@ inputs:
|
||||
description: 'The Github token.'
|
||||
required: true
|
||||
default: ''
|
||||
outputs:
|
||||
id:
|
||||
description: 'The identifier of the created release.'
|
||||
html_url:
|
||||
description: 'The HTML URL of the release.'
|
||||
upload_url:
|
||||
description: 'The URL for uploading assets to the release.'
|
||||
runs:
|
||||
using: 'node12'
|
||||
main: 'lib/Main.js'
|
||||
|
||||
@@ -10,62 +10,53 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Action = void 0;
|
||||
const GithubError_1 = require("./GithubError");
|
||||
const ErrorMessage_1 = require("./ErrorMessage");
|
||||
class Action {
|
||||
constructor(inputs, outputs, releases, uploader) {
|
||||
constructor(inputs, releases, uploader) {
|
||||
this.inputs = inputs;
|
||||
this.outputs = outputs;
|
||||
this.releases = releases;
|
||||
this.uploader = uploader;
|
||||
}
|
||||
perform() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const releaseResponse = yield this.createOrUpdateRelease();
|
||||
const releaseData = releaseResponse.data;
|
||||
const releaseId = releaseData.id;
|
||||
const uploadUrl = releaseData.upload_url;
|
||||
const releaseId = releaseResponse.data.id;
|
||||
const uploadUrl = releaseResponse.data.upload_url;
|
||||
const artifacts = this.inputs.artifacts;
|
||||
if (artifacts.length > 0) {
|
||||
yield this.uploader.uploadArtifacts(artifacts, releaseId, uploadUrl);
|
||||
}
|
||||
this.outputs.applyReleaseData(releaseData);
|
||||
});
|
||||
}
|
||||
createOrUpdateRelease() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (this.inputs.allowUpdates) {
|
||||
let getResponse;
|
||||
try {
|
||||
getResponse = yield this.releases.getByTag(this.inputs.tag);
|
||||
const getResponse = yield this.releases.getByTag(this.inputs.tag);
|
||||
return yield this.updateRelease(getResponse.data.id);
|
||||
}
|
||||
catch (error) {
|
||||
return yield this.checkForMissingReleaseError(error);
|
||||
if (Action.noPublishedRelease(error)) {
|
||||
return yield this.updateDraftOrCreateRelease();
|
||||
}
|
||||
else {
|
||||
throw 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.discussionCategory, 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.draft, this.inputs.updatedReleaseName, this.inputs.prerelease);
|
||||
});
|
||||
}
|
||||
static noPublishedRelease(error) {
|
||||
const githubError = new GithubError_1.GithubError(error);
|
||||
return githubError.status == 404;
|
||||
const errorMessage = new ErrorMessage_1.ErrorMessage(error);
|
||||
return errorMessage.status == 404;
|
||||
}
|
||||
updateDraftOrCreateRelease() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
@@ -89,7 +80,8 @@ class Action {
|
||||
}
|
||||
createRelease() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
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);
|
||||
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;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,69 +1,17 @@
|
||||
"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"));
|
||||
const ArtifactPathValidator_1 = require("./ArtifactPathValidator");
|
||||
class FileArtifactGlobber {
|
||||
constructor(globber = new Globber_1.FileGlobber()) {
|
||||
this.globber = globber;
|
||||
}
|
||||
globArtifactString(artifact, contentType, errorsFailBuild) {
|
||||
globArtifactString(artifact, contentType) {
|
||||
return artifact.split(',')
|
||||
.map(path => FileArtifactGlobber.expandPath(path))
|
||||
.map(pattern => this.globPattern(pattern, errorsFailBuild))
|
||||
.map((globResult) => FileArtifactGlobber.validatePattern(errorsFailBuild, globResult[1], globResult[0]))
|
||||
.map((path) => this.globber.glob(path))
|
||||
.reduce((accumulated, current) => accumulated.concat(current))
|
||||
.map(path => new Artifact_1.Artifact(path, contentType));
|
||||
}
|
||||
globPattern(pattern, errorsFailBuild) {
|
||||
const paths = this.globber.glob(pattern);
|
||||
if (paths.length == 0) {
|
||||
if (errorsFailBuild) {
|
||||
FileArtifactGlobber.throwGlobError(pattern);
|
||||
}
|
||||
else {
|
||||
FileArtifactGlobber.reportGlobWarning(pattern);
|
||||
}
|
||||
}
|
||||
return [pattern, paths];
|
||||
}
|
||||
static validatePattern(errorsFailBuild, paths, pattern) {
|
||||
const validator = new ArtifactPathValidator_1.ArtifactPathValidator(errorsFailBuild, paths, pattern);
|
||||
return validator.validate();
|
||||
}
|
||||
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);
|
||||
.map((path) => new Artifact_1.Artifact(path, contentType));
|
||||
}
|
||||
}
|
||||
exports.FileArtifactGlobber = FileArtifactGlobber;
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
"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;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ArtifactPathValidator = void 0;
|
||||
const core = __importStar(require("@actions/core"));
|
||||
const fs_1 = require("fs");
|
||||
class ArtifactPathValidator {
|
||||
constructor(errorsFailBuild, paths, pattern) {
|
||||
this.paths = paths;
|
||||
this.pattern = pattern;
|
||||
this.errorsFailBuild = errorsFailBuild;
|
||||
}
|
||||
validate() {
|
||||
this.verifyPathsNotEmpty();
|
||||
return this.paths.filter((path) => this.verifyNotDirectory(path));
|
||||
}
|
||||
verifyPathsNotEmpty() {
|
||||
if (this.paths.length == 0) {
|
||||
const message = `Artifact pattern:${this.pattern} did not match any files`;
|
||||
this.reportError(message);
|
||||
}
|
||||
}
|
||||
verifyNotDirectory(path) {
|
||||
const isDir = fs_1.statSync(path).isDirectory();
|
||||
if (isDir) {
|
||||
const message = `Artifact is a directory:${path}. Directories can not be uploaded to a release.`;
|
||||
this.reportError(message);
|
||||
}
|
||||
return !isDir;
|
||||
}
|
||||
reportError(message) {
|
||||
if (this.errorsFailBuild) {
|
||||
throw Error(message);
|
||||
}
|
||||
else {
|
||||
core.warning(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.ArtifactPathValidator = ArtifactPathValidator;
|
||||
@@ -31,10 +31,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.GithubArtifactUploader = void 0;
|
||||
const core = __importStar(require("@actions/core"));
|
||||
class GithubArtifactUploader {
|
||||
constructor(releases, replacesExistingArtifacts = true, throwsUploadErrors = false) {
|
||||
constructor(releases, replacesExistingArtifacts = true) {
|
||||
this.releases = releases;
|
||||
this.replacesExistingArtifacts = replacesExistingArtifacts;
|
||||
this.throwsUploadErrors = throwsUploadErrors;
|
||||
}
|
||||
uploadArtifacts(artifacts, releaseId, uploadUrl) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
@@ -58,19 +57,15 @@ class GithubArtifactUploader {
|
||||
yield this.uploadArtifact(artifact, releaseId, uploadUrl, retry - 1);
|
||||
}
|
||||
else {
|
||||
if (this.throwsUploadErrors) {
|
||||
throw Error(`Failed to upload artifact ${artifact.name}. ${error.message}.`);
|
||||
}
|
||||
else {
|
||||
core.warning(`Failed to upload artifact ${artifact.name}. ${error.message}.`);
|
||||
}
|
||||
core.warning(`Failed to upload artifact ${artifact.name}. ${error.message}.`);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
deleteUpdatedArtifacts(artifacts, releaseId) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const releaseAssets = yield this.releases.listArtifactsForRelease(releaseId);
|
||||
const response = yield this.releases.listArtifactsForRelease(releaseId);
|
||||
const releaseAssets = response.data;
|
||||
const assetByName = {};
|
||||
releaseAssets.forEach(asset => {
|
||||
assetByName[asset.name] = asset;
|
||||
|
||||
40
lib/ErrorMessage.js
Normal file
40
lib/ErrorMessage.js
Normal file
@@ -0,0 +1,40 @@
|
||||
"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,40 +1,57 @@
|
||||
"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();
|
||||
}
|
||||
generateGithubErrors() {
|
||||
const errors = this.error.errors;
|
||||
if (errors instanceof Array) {
|
||||
return errors.map((err) => new GithubErrorDetail_1.GithubErrorDetail(err));
|
||||
}
|
||||
else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
get status() {
|
||||
return this.error.status;
|
||||
}
|
||||
hasErrorWithCode(code) {
|
||||
return this.githubErrors.some((err) => err.code == code);
|
||||
get code() {
|
||||
return this.error.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}`;
|
||||
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();
|
||||
}
|
||||
}
|
||||
errorBulletedList(errors) {
|
||||
return errors.map((err) => `- ${err}`).join("\n");
|
||||
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.GithubError = GithubError;
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
"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,14 +42,10 @@ class CoreInputs {
|
||||
contentType = 'raw';
|
||||
}
|
||||
return this.artifactGlobber
|
||||
.globArtifactString(artifacts, contentType, this.artifactErrorsFailBuild);
|
||||
.globArtifactString(artifacts, contentType);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
get artifactErrorsFailBuild() {
|
||||
const allow = core.getInput('artifactErrorsFailBuild');
|
||||
return allow == 'true';
|
||||
}
|
||||
get createdReleaseBody() {
|
||||
if (CoreInputs.omitBody)
|
||||
return undefined;
|
||||
@@ -77,13 +73,6 @@ 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';
|
||||
}
|
||||
|
||||
12
lib/Main.js
12
lib/Main.js
@@ -35,8 +35,7 @@ const Releases_1 = require("./Releases");
|
||||
const Action_1 = require("./Action");
|
||||
const ArtifactUploader_1 = require("./ArtifactUploader");
|
||||
const ArtifactGlobber_1 = require("./ArtifactGlobber");
|
||||
const GithubError_1 = require("./GithubError");
|
||||
const Outputs_1 = require("./Outputs");
|
||||
const ErrorMessage_1 = require("./ErrorMessage");
|
||||
function run() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
@@ -44,8 +43,8 @@ function run() {
|
||||
yield action.perform();
|
||||
}
|
||||
catch (error) {
|
||||
const githubError = new GithubError_1.GithubError(error);
|
||||
core.setFailed(githubError.toString());
|
||||
const errorMessage = new ErrorMessage_1.ErrorMessage(error);
|
||||
core.setFailed(errorMessage.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -55,9 +54,8 @@ function createAction() {
|
||||
const git = github.getOctokit(token);
|
||||
const globber = new ArtifactGlobber_1.FileArtifactGlobber();
|
||||
const inputs = new Inputs_1.CoreInputs(globber, context);
|
||||
const outputs = new Outputs_1.CoreOutputs();
|
||||
const releases = new Releases_1.GithubReleases(inputs, git);
|
||||
const uploader = new ArtifactUploader_1.GithubArtifactUploader(releases, inputs.replacesArtifacts, inputs.artifactErrorsFailBuild);
|
||||
return new Action_1.Action(inputs, outputs, releases, uploader);
|
||||
const uploader = new ArtifactUploader_1.GithubArtifactUploader(releases, inputs.replacesArtifacts);
|
||||
return new Action_1.Action(inputs, releases, uploader);
|
||||
}
|
||||
run();
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
"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;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CoreOutputs = void 0;
|
||||
const core = __importStar(require("@actions/core"));
|
||||
class CoreOutputs {
|
||||
applyReleaseData(releaseData) {
|
||||
core.setOutput('id', releaseData.id);
|
||||
core.setOutput('html_url', releaseData.html_url);
|
||||
core.setOutput('upload_url', releaseData.upload_url);
|
||||
}
|
||||
}
|
||||
exports.CoreOutputs = CoreOutputs;
|
||||
@@ -15,13 +15,12 @@ class GithubReleases {
|
||||
this.inputs = inputs;
|
||||
this.git = git;
|
||||
}
|
||||
create(tag, body, commitHash, discussionCategory, draft, name, prerelease) {
|
||||
create(tag, body, commitHash, 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,
|
||||
@@ -51,7 +50,7 @@ class GithubReleases {
|
||||
}
|
||||
listArtifactsForRelease(releaseId) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
return this.git.paginate(this.git.repos.listReleaseAssets, {
|
||||
return this.git.repos.listReleaseAssets({
|
||||
owner: this.inputs.owner,
|
||||
release_id: releaseId,
|
||||
repo: this.inputs.repo
|
||||
@@ -66,14 +65,13 @@ class GithubReleases {
|
||||
});
|
||||
});
|
||||
}
|
||||
update(id, tag, body, commitHash, discussionCategory, draft, name, prerelease) {
|
||||
update(id, tag, body, commitHash, 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,
|
||||
|
||||
26
node_modules/.yarn-integrity
generated
vendored
26
node_modules/.yarn-integrity
generated
vendored
@@ -13,12 +13,13 @@
|
||||
"@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.6.3",
|
||||
"ts-jest@^26.5.6",
|
||||
"typescript@^4.1.4",
|
||||
"untildify@^4.0.0"
|
||||
"jest@^26.1.0",
|
||||
"ts-jest@^26.5.1",
|
||||
"typescript@^4.1.4"
|
||||
],
|
||||
"lockfileEntries": {
|
||||
"@actions/core@^1.2.6": "https://registry.yarnpkg.com/@actions/core/-/core-1.2.6.tgz#a78d49f41a4def18e88ce47c2cac615d5694bf09",
|
||||
@@ -112,6 +113,7 @@
|
||||
"@types/istanbul-lib-coverage@^2.0.1": "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762",
|
||||
"@types/istanbul-lib-report@*": "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686",
|
||||
"@types/istanbul-reports@^3.0.0": "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz#508b13aa344fa4976234e75dddcc34925737d821",
|
||||
"@types/jest@26.x": "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.20.tgz#cd2f2702ecf69e86b586e1f5223a60e454056307",
|
||||
"@types/jest@^26.0.20": "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.20.tgz#cd2f2702ecf69e86b586e1f5223a60e454056307",
|
||||
"@types/minimatch@*": "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d",
|
||||
"@types/node@*": "https://registry.yarnpkg.com/@types/node/-/node-14.14.25.tgz#15967a7b577ff81383f9b888aa6705d43fbbae93",
|
||||
@@ -126,6 +128,7 @@
|
||||
"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",
|
||||
@@ -219,6 +222,7 @@
|
||||
"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",
|
||||
@@ -273,6 +277,7 @@
|
||||
"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",
|
||||
@@ -285,7 +290,7 @@
|
||||
"has-values@^0.1.4": "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771",
|
||||
"has-values@^1.0.0": "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f",
|
||||
"has@^1.0.3": "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796",
|
||||
"hosted-git-info@^2.1.4": "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9",
|
||||
"hosted-git-info@^2.1.4": "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488",
|
||||
"html-encoding-sniffer@^2.0.1": "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3",
|
||||
"html-escaper@^2.0.0": "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453",
|
||||
"http-signature@~1.2.0": "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1",
|
||||
@@ -367,7 +372,7 @@
|
||||
"jest-validate@^26.6.2": "https://registry.yarnpkg.com/jest-validate/-/jest-validate-26.6.2.tgz#23d380971587150467342911c3d7b4ac57ab20ec",
|
||||
"jest-watcher@^26.6.2": "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-26.6.2.tgz#a5b683b8f9d68dbcb1d7dae32172d2cca0592975",
|
||||
"jest-worker@^26.6.2": "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed",
|
||||
"jest@^26.6.3": "https://registry.yarnpkg.com/jest/-/jest-26.6.3.tgz#40e8fdbe48f00dfa1f0ce8121ca74b88ac9148ef",
|
||||
"jest@^26.1.0": "https://registry.yarnpkg.com/jest/-/jest-26.6.3.tgz#40e8fdbe48f00dfa1f0ce8121ca74b88ac9148ef",
|
||||
"js-tokens@^4.0.0": "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499",
|
||||
"js-yaml@^3.13.1": "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537",
|
||||
"jsbn@~0.1.0": "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513",
|
||||
@@ -393,8 +398,8 @@
|
||||
"lines-and-columns@^1.1.6": "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00",
|
||||
"locate-path@^5.0.0": "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0",
|
||||
"lodash.sortby@^4.7.0": "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438",
|
||||
"lodash@4.x": "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c",
|
||||
"lodash@^4.17.19": "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c",
|
||||
"lodash@4.x": "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52",
|
||||
"lodash@^4.17.19": "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52",
|
||||
"lru-cache@^6.0.0": "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94",
|
||||
"make-dir@^3.0.0": "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f",
|
||||
"make-error@1.x": "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2",
|
||||
@@ -408,6 +413,7 @@
|
||||
"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",
|
||||
@@ -462,6 +468,7 @@
|
||||
"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",
|
||||
@@ -567,7 +574,7 @@
|
||||
"tough-cookie@^3.0.1": "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-3.0.1.tgz#9df4f57e739c26930a018184887f4adb7dca73b2",
|
||||
"tough-cookie@~2.5.0": "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2",
|
||||
"tr46@^2.0.2": "https://registry.yarnpkg.com/tr46/-/tr46-2.0.2.tgz#03273586def1595ae08fedb38d7733cee91d2479",
|
||||
"ts-jest@^26.5.6": "https://registry.yarnpkg.com/ts-jest/-/ts-jest-26.5.6.tgz#c32e0746425274e1dfe333f43cd3c800e014ec35",
|
||||
"ts-jest@^26.5.1": "https://registry.yarnpkg.com/ts-jest/-/ts-jest-26.5.1.tgz#4d53ee4481552f57c1624f0bd3425c8b17996150",
|
||||
"tunnel-agent@^0.6.0": "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd",
|
||||
"tunnel@0.0.6": "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c",
|
||||
"tweetnacl@^0.14.3": "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64",
|
||||
@@ -582,7 +589,6 @@
|
||||
"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
Normal file
2
node_modules/add/.npmignore
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
node_modules
|
||||
|
||||
7
node_modules/add/.travis.yml
generated
vendored
Normal file
7
node_modules/add/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.11"
|
||||
- "0.10"
|
||||
- "0.8"
|
||||
- "0.6"
|
||||
|
||||
47
node_modules/add/Readme.md
generated
vendored
Normal file
47
node_modules/add/Readme.md
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
# 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
Normal file
36
node_modules/add/bower.json
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"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
Normal file
177
node_modules/add/index.js
generated
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
(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
Normal file
48
node_modules/add/package.json
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"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
Normal file
41
node_modules/add/test.js
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* 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
Normal file
19
node_modules/dom-walk/LICENCE
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
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
Normal file
2
node_modules/dom-walk/Makefile
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
run:
|
||||
./node_modules/.bin/browserify-server --cwd example
|
||||
23
node_modules/dom-walk/README.md
generated
vendored
Normal file
23
node_modules/dom-walk/README.md
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
# 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
Normal file
5
node_modules/dom-walk/example/index.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
var walk = require("../index")
|
||||
|
||||
walk(document, function (node) {
|
||||
console.log("node", node)
|
||||
})
|
||||
24
node_modules/dom-walk/index.js
generated
vendored
Normal file
24
node_modules/dom-walk/index.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
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
Normal file
32
node_modules/dom-walk/package.json
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"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
Normal file
4
node_modules/global/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 0.8
|
||||
- 0.9
|
||||
19
node_modules/global/LICENSE
generated
vendored
Normal file
19
node_modules/global/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
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
Normal file
30
node_modules/global/README.md
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
# 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
Normal file
1
node_modules/global/console.js
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = console;
|
||||
17
node_modules/global/document.js
generated
vendored
Normal file
17
node_modules/global/document.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
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
Normal file
63
node_modules/global/package.json
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
{
|
||||
"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
Normal file
1
node_modules/global/process.js
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = require('process');
|
||||
13
node_modules/global/window.js
generated
vendored
Normal file
13
node_modules/global/window.js
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
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
Normal file
30
node_modules/min-document/.jshintrc
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"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
Normal file
15
node_modules/min-document/.npmignore
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
.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
Normal file
14
node_modules/min-document/.testem.json
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"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
Normal file
6
node_modules/min-document/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
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
Normal file
48
node_modules/min-document/CONTRIBUTION.md
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
# 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
Normal file
19
node_modules/min-document/LICENCE
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
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
Normal file
43
node_modules/min-document/README.md
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
# 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
Normal file
156
node_modules/min-document/docs.mli
generated
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
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
Normal file
72
node_modules/min-document/document.js
generated
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
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
Normal file
19
node_modules/min-document/dom-comment.js
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
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
Normal file
209
node_modules/min-document/dom-element.js
generated
vendored
Normal file
@@ -0,0 +1,209 @@
|
||||
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
Normal file
28
node_modules/min-document/dom-fragment.js
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
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
Normal file
27
node_modules/min-document/dom-text.js
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
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
Normal file
13
node_modules/min-document/event.js
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
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
Normal file
17
node_modules/min-document/event/add-event-listener.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
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
Normal file
31
node_modules/min-document/event/dispatch-event.js
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
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
Normal file
19
node_modules/min-document/event/remove-event-listener.js
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
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
Normal file
3
node_modules/min-document/index.js
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
var Document = require('./document.js');
|
||||
|
||||
module.exports = new Document();
|
||||
58
node_modules/min-document/package.json
generated
vendored
Normal file
58
node_modules/min-document/package.json
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"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
Normal file
139
node_modules/min-document/serialize.js
generated
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
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
Normal file
13
node_modules/min-document/test/cleanup.js
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
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
Normal file
14
node_modules/min-document/test/index.js
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
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
Normal file
11
node_modules/min-document/test/static/index.html
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
<!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
Normal file
49
node_modules/min-document/test/static/test-adapter.js
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
(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
Normal file
564
node_modules/min-document/test/test-document.js
generated
vendored
Normal file
@@ -0,0 +1,564 @@
|
||||
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
Normal file
20
node_modules/min-document/test/test-dom-comment.js
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
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
Normal file
219
node_modules/min-document/test/test-dom-element.js
generated
vendored
Normal file
@@ -0,0 +1,219 @@
|
||||
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
Normal file
21
node_modules/process/.eslintrc
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
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
Normal file
22
node_modules/process/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
(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
Normal file
26
node_modules/process/README.md
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
# 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
Normal file
184
node_modules/process/browser.js
generated
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
// 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
Normal file
2
node_modules/process/index.js
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
// for now just expose the builtin process global from node.js
|
||||
module.exports = global.process;
|
||||
27
node_modules/process/package.json
generated
vendored
Normal file
27
node_modules/process/package.json
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"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
Normal file
199
node_modules/process/test.js
generated
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
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
14
node_modules/untildify/index.d.ts
generated
vendored
@@ -1,14 +0,0 @@
|
||||
/**
|
||||
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
12
node_modules/untildify/index.js
generated
vendored
@@ -1,12 +0,0 @@
|
||||
'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
9
node_modules/untildify/license
generated
vendored
@@ -1,9 +0,0 @@
|
||||
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
43
node_modules/untildify/package.json
generated
vendored
@@ -1,43 +0,0 @@
|
||||
{
|
||||
"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
30
node_modules/untildify/readme.md
generated
vendored
@@ -1,30 +0,0 @@
|
||||
# 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,15 +26,16 @@
|
||||
"@actions/core": "^1.2.6",
|
||||
"@actions/github": "^4.0.0",
|
||||
"@types/glob": "^7.1.3",
|
||||
"add": "^2.0.6",
|
||||
"glob": "^7.1.4",
|
||||
"untildify": "^4.0.0"
|
||||
"global": "^4.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^26.0.20",
|
||||
"@types/node": "^14.14.25",
|
||||
"jest": "^26.6.3",
|
||||
"jest": "^26.1.0",
|
||||
"jest-circus": "^26.6.3",
|
||||
"ts-jest": "^26.5.6",
|
||||
"ts-jest": "^26.5.1",
|
||||
"typescript": "^4.1.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,72 +1,53 @@
|
||||
import {Inputs} from "./Inputs";
|
||||
import {
|
||||
CreateOrUpdateReleaseResponse,
|
||||
CreateReleaseResponse,
|
||||
ReleaseByTagResponse,
|
||||
Releases,
|
||||
UpdateReleaseResponse
|
||||
} from "./Releases";
|
||||
import {CreateReleaseResponse, Releases, UpdateReleaseResponse} from "./Releases";
|
||||
import {ArtifactUploader} from "./ArtifactUploader";
|
||||
import {GithubError} from "./GithubError";
|
||||
import {Outputs} from "./Outputs";
|
||||
import {ErrorMessage} from "./ErrorMessage";
|
||||
|
||||
export class Action {
|
||||
private inputs: Inputs
|
||||
private outputs: Outputs
|
||||
private releases: Releases
|
||||
private uploader: ArtifactUploader
|
||||
|
||||
constructor(inputs: Inputs, outputs: Outputs, releases: Releases, uploader: ArtifactUploader) {
|
||||
constructor(inputs: Inputs, releases: Releases, uploader: ArtifactUploader) {
|
||||
this.inputs = inputs
|
||||
this.outputs = outputs
|
||||
this.releases = releases
|
||||
this.uploader = uploader
|
||||
}
|
||||
|
||||
async perform() {
|
||||
const releaseResponse = await this.createOrUpdateRelease();
|
||||
const releaseData = releaseResponse.data
|
||||
const releaseId = releaseData.id
|
||||
const uploadUrl = releaseData.upload_url
|
||||
const releaseId = releaseResponse.data.id
|
||||
const uploadUrl = releaseResponse.data.upload_url
|
||||
|
||||
const artifacts = this.inputs.artifacts
|
||||
if (artifacts.length > 0) {
|
||||
await this.uploader.uploadArtifacts(artifacts, releaseId, uploadUrl)
|
||||
}
|
||||
|
||||
this.outputs.applyReleaseData(releaseData)
|
||||
}
|
||||
|
||||
private async createOrUpdateRelease(): Promise<CreateOrUpdateReleaseResponse> {
|
||||
private async createOrUpdateRelease(): Promise<CreateReleaseResponse | UpdateReleaseResponse> {
|
||||
if (this.inputs.allowUpdates) {
|
||||
let getResponse: ReleaseByTagResponse
|
||||
try {
|
||||
getResponse = await this.releases.getByTag(this.inputs.tag)
|
||||
const getResponse = await this.releases.getByTag(this.inputs.tag)
|
||||
return await this.updateRelease(getResponse.data.id)
|
||||
} catch (error) {
|
||||
return await this.checkForMissingReleaseError(error)
|
||||
if (Action.noPublishedRelease(error)) {
|
||||
return await this.updateDraftOrCreateRelease()
|
||||
} else {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
return await this.updateRelease(getResponse.data.id)
|
||||
} else {
|
||||
return await this.createRelease()
|
||||
}
|
||||
}
|
||||
|
||||
private async checkForMissingReleaseError(error: Error): Promise<CreateOrUpdateReleaseResponse> {
|
||||
if (Action.noPublishedRelease(error)) {
|
||||
return await this.updateDraftOrCreateRelease()
|
||||
} else {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
private async updateRelease(id: number): Promise<UpdateReleaseResponse> {
|
||||
return await 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
|
||||
@@ -74,8 +55,8 @@ export class Action {
|
||||
}
|
||||
|
||||
private static noPublishedRelease(error: any): boolean {
|
||||
const githubError = new GithubError(error)
|
||||
return githubError.status == 404
|
||||
const errorMessage = new ErrorMessage(error)
|
||||
return errorMessage.status == 404
|
||||
}
|
||||
|
||||
private async updateDraftOrCreateRelease(): Promise<CreateReleaseResponse | UpdateReleaseResponse> {
|
||||
@@ -97,14 +78,15 @@ export class Action {
|
||||
}
|
||||
|
||||
private async createRelease(): Promise<CreateReleaseResponse> {
|
||||
return await this.releases.create(
|
||||
const response = 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,11 +1,8 @@
|
||||
import * as core from '@actions/core';
|
||||
import {Globber, FileGlobber} from "./Globber";
|
||||
import {Artifact} from "./Artifact";
|
||||
import untildify from "untildify";
|
||||
import {ArtifactPathValidator} from "./ArtifactPathValidator";
|
||||
import { Globber, FileGlobber } from "./Globber";
|
||||
import { Artifact } from "./Artifact";
|
||||
|
||||
export interface ArtifactGlobber {
|
||||
globArtifactString(artifact: string, contentType: string, errorsFailBuild: boolean): Artifact[]
|
||||
globArtifactString(artifact: string, contentType: string): Artifact[]
|
||||
}
|
||||
|
||||
export class FileArtifactGlobber implements ArtifactGlobber {
|
||||
@@ -15,41 +12,11 @@ export class FileArtifactGlobber implements ArtifactGlobber {
|
||||
this.globber = globber
|
||||
}
|
||||
|
||||
globArtifactString(artifact: string, contentType: string, errorsFailBuild: boolean): Artifact[] {
|
||||
globArtifactString(artifact: string, contentType: string): Artifact[] {
|
||||
return artifact.split(',')
|
||||
.map(path => FileArtifactGlobber.expandPath(path))
|
||||
.map(pattern => this.globPattern(pattern, errorsFailBuild))
|
||||
.map((globResult) => FileArtifactGlobber.validatePattern(errorsFailBuild, globResult[1], globResult[0]))
|
||||
.map((path) => this.globber.glob(path))
|
||||
.reduce((accumulated, current) => accumulated.concat(current))
|
||||
.map(path => new Artifact(path, contentType))
|
||||
.map((path) => new Artifact(path, contentType))
|
||||
}
|
||||
}
|
||||
|
||||
private globPattern(pattern: string, errorsFailBuild: boolean): [string, string[]] {
|
||||
const paths = this.globber.glob(pattern)
|
||||
if (paths.length == 0) {
|
||||
if (errorsFailBuild) {
|
||||
FileArtifactGlobber.throwGlobError(pattern)
|
||||
} else {
|
||||
FileArtifactGlobber.reportGlobWarning(pattern)
|
||||
}
|
||||
}
|
||||
return [pattern, paths]
|
||||
}
|
||||
|
||||
private static validatePattern(errorsFailBuild: boolean, paths: string[], pattern: string): string[] {
|
||||
const validator = new ArtifactPathValidator(errorsFailBuild, paths, pattern)
|
||||
return validator.validate()
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
import * as core from "@actions/core";
|
||||
import {statSync} from "fs";
|
||||
|
||||
export class ArtifactPathValidator {
|
||||
private readonly errorsFailBuild: boolean;
|
||||
private paths: string[];
|
||||
private readonly pattern: string
|
||||
|
||||
constructor(errorsFailBuild: boolean, paths: string[], pattern: string) {
|
||||
this.paths = paths;
|
||||
this.pattern = pattern
|
||||
this.errorsFailBuild = errorsFailBuild;
|
||||
}
|
||||
|
||||
validate(): string[] {
|
||||
this.verifyPathsNotEmpty()
|
||||
return this.paths.filter((path) => this.verifyNotDirectory(path))
|
||||
}
|
||||
|
||||
private verifyPathsNotEmpty() {
|
||||
if (this.paths.length == 0) {
|
||||
const message = `Artifact pattern:${this.pattern} did not match any files`
|
||||
this.reportError(message)
|
||||
}
|
||||
}
|
||||
|
||||
private verifyNotDirectory(path: string): boolean {
|
||||
const isDir = statSync(path).isDirectory()
|
||||
if (isDir) {
|
||||
const message = `Artifact is a directory:${path}. Directories can not be uploaded to a release.`
|
||||
this.reportError(message)
|
||||
}
|
||||
return !isDir
|
||||
}
|
||||
|
||||
private reportError(message: string) {
|
||||
if (this.errorsFailBuild) {
|
||||
throw Error(message)
|
||||
} else {
|
||||
core.warning(message)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,6 @@ export class GithubArtifactUploader implements ArtifactUploader {
|
||||
constructor(
|
||||
private releases: Releases,
|
||||
private replacesExistingArtifacts: boolean = true,
|
||||
private throwsUploadErrors: boolean = false,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -42,17 +41,14 @@ 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 {
|
||||
if (this.throwsUploadErrors) {
|
||||
throw Error(`Failed to upload artifact ${artifact.name}. ${error.message}.`)
|
||||
} else {
|
||||
core.warning(`Failed to upload artifact ${artifact.name}. ${error.message}.`)
|
||||
}
|
||||
core.warning(`Failed to upload artifact ${artifact.name}. ${error.message}.`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async deleteUpdatedArtifacts(artifacts: Artifact[], releaseId: number): Promise<void> {
|
||||
const releaseAssets = await this.releases.listArtifactsForRelease(releaseId)
|
||||
const response = await this.releases.listArtifactsForRelease(releaseId)
|
||||
const releaseAssets = response.data
|
||||
const assetByName: Record<string, { id: number; name: string }> = {}
|
||||
releaseAssets.forEach(asset => {
|
||||
assetByName[asset.name] = asset
|
||||
|
||||
44
src/ErrorMessage.ts
Normal file
44
src/ErrorMessage.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
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,44 +1,65 @@
|
||||
import {GithubErrorDetail} from "./GithubErrorDetail"
|
||||
|
||||
export class GithubError {
|
||||
private error: any
|
||||
private readonly githubErrors: GithubErrorDetail[]
|
||||
private error: any;
|
||||
|
||||
constructor(error: any) {
|
||||
this.error = error
|
||||
this.githubErrors = this.generateGithubErrors()
|
||||
}
|
||||
|
||||
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)
|
||||
get code(): string {
|
||||
return this.error.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}`
|
||||
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 errorBulletedList(errors: GithubErrorDetail[]): string {
|
||||
return errors.map((err) => `- ${err}`).join("\n")
|
||||
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.`
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
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,12 +6,10 @@ 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
|
||||
@@ -48,16 +46,11 @@ export class CoreInputs implements Inputs {
|
||||
contentType = 'raw'
|
||||
}
|
||||
return this.artifactGlobber
|
||||
.globArtifactString(artifacts, contentType, this.artifactErrorsFailBuild)
|
||||
.globArtifactString(artifacts, contentType)
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
get artifactErrorsFailBuild(): boolean {
|
||||
const allow = core.getInput('artifactErrorsFailBuild')
|
||||
return allow == 'true'
|
||||
}
|
||||
|
||||
get createdReleaseBody(): string | undefined {
|
||||
if (CoreInputs.omitBody) return undefined
|
||||
return this.body
|
||||
@@ -67,7 +60,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
|
||||
@@ -90,14 +83,6 @@ 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'
|
||||
}
|
||||
@@ -171,7 +156,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
|
||||
}
|
||||
|
||||
|
||||
44
src/Main.ts
44
src/Main.ts
@@ -1,34 +1,32 @@
|
||||
import * as github from '@actions/github';
|
||||
import * as core from '@actions/core';
|
||||
import {CoreInputs} from './Inputs';
|
||||
import {GithubReleases} from './Releases';
|
||||
import {Action} from './Action';
|
||||
import {GithubArtifactUploader} from './ArtifactUploader';
|
||||
import {FileArtifactGlobber} from './ArtifactGlobber';
|
||||
import {GithubError} from './GithubError';
|
||||
import {CoreOutputs} from "./Outputs";
|
||||
import { CoreInputs } from './Inputs';
|
||||
import { GithubReleases } from './Releases';
|
||||
import { Action } from './Action';
|
||||
import { GithubArtifactUploader } from './ArtifactUploader';
|
||||
import { FileArtifactGlobber } from './ArtifactGlobber';
|
||||
import { ErrorMessage } from './ErrorMessage';
|
||||
|
||||
async function run() {
|
||||
try {
|
||||
const action = createAction()
|
||||
await action.perform()
|
||||
} catch (error) {
|
||||
const githubError = new GithubError(error)
|
||||
core.setFailed(githubError.toString());
|
||||
}
|
||||
try {
|
||||
const action = createAction()
|
||||
await action.perform()
|
||||
} catch (error) {
|
||||
const errorMessage = new ErrorMessage(error)
|
||||
core.setFailed(errorMessage.toString());
|
||||
}
|
||||
}
|
||||
|
||||
function createAction(): Action {
|
||||
const token = core.getInput('token')
|
||||
const context = github.context
|
||||
const git = github.getOctokit(token)
|
||||
const globber = new FileArtifactGlobber()
|
||||
const token = core.getInput('token')
|
||||
const context = github.context
|
||||
const git = github.getOctokit(token)
|
||||
const globber = new FileArtifactGlobber()
|
||||
|
||||
const inputs = new CoreInputs(globber, context)
|
||||
const outputs = new CoreOutputs()
|
||||
const releases = new GithubReleases(inputs, git)
|
||||
const uploader = new GithubArtifactUploader(releases, inputs.replacesArtifacts, inputs.artifactErrorsFailBuild)
|
||||
return new Action(inputs, outputs, releases, uploader)
|
||||
const inputs = new CoreInputs(globber, context)
|
||||
const releases = new GithubReleases(inputs, git)
|
||||
const uploader = new GithubArtifactUploader(releases, inputs.replacesArtifacts)
|
||||
return new Action(inputs, releases, uploader)
|
||||
}
|
||||
|
||||
run();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user