nx 18.0.4 → 18.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +13 -12
- package/src/command-line/add/add.js +3 -1
- package/src/command-line/graph/graph.js +1 -1
- package/src/command-line/init/init-v2.js +16 -11
- package/src/command-line/migrate/command-object.js +17 -2
- package/src/command-line/migrate/migrate.js +13 -1
- package/src/command-line/release/changelog.d.ts +16 -1
- package/src/command-line/release/changelog.js +104 -194
- package/src/command-line/release/command-object.d.ts +1 -0
- package/src/command-line/release/release.js +56 -3
- package/src/command-line/release/utils/git.d.ts +5 -1
- package/src/command-line/release/utils/git.js +26 -11
- package/src/command-line/release/utils/github.d.ts +4 -8
- package/src/command-line/release/utils/github.js +61 -2
- package/src/command-line/release/utils/shared.d.ts +1 -0
- package/src/command-line/release/utils/shared.js +3 -1
- package/src/core/graph/3rdpartylicenses.txt +0 -51
- package/src/core/graph/main.js +1 -1
- package/src/core/graph/polyfills.js +1 -1
- package/src/core/graph/runtime.js +1 -1
- package/src/core/graph/styles.js +1 -1
- package/src/migrations/update-17-0-0/rm-default-collection-npm-scope.js +3 -3
- package/src/plugins/js/utils/register.js +1 -0
- package/src/plugins/target-defaults/target-defaults-plugin.d.ts +2 -3
- package/src/plugins/target-defaults/target-defaults-plugin.js +24 -32
- package/src/project-graph/utils/project-configuration-utils.js +13 -6
- package/src/tasks-runner/life-cycles/dynamic-run-many-terminal-output-life-cycle.js +20 -23
- package/src/tasks-runner/life-cycles/dynamic-run-one-terminal-output-life-cycle.js +16 -16
- package/src/tasks-runner/life-cycles/static-run-many-terminal-output-life-cycle.js +1 -1
- package/src/tasks-runner/life-cycles/view-logs-utils.js +1 -1
- package/src/tasks-runner/task-orchestrator.js +23 -1
- package/src/utils/json.js +3 -1
- package/src/utils/logger.js +1 -1
- package/src/utils/output.d.ts +0 -1
- package/src/utils/output.js +6 -7
- package/src/utils/package-json.d.ts +1 -1
- package/src/utils/package-json.js +12 -11
- package/src/utils/plugins/core-plugins.js +4 -0
|
@@ -11,6 +11,7 @@ const config_1 = require("./config/config");
|
|
|
11
11
|
const filter_release_groups_1 = require("./config/filter-release-groups");
|
|
12
12
|
const publish_1 = require("./publish");
|
|
13
13
|
const git_1 = require("./utils/git");
|
|
14
|
+
const github_1 = require("./utils/github");
|
|
14
15
|
const resolve_nx_json_error_message_1 = require("./utils/resolve-nx-json-error-message");
|
|
15
16
|
const shared_1 = require("./utils/shared");
|
|
16
17
|
const version_1 = require("./version");
|
|
@@ -51,13 +52,14 @@ async function release(args) {
|
|
|
51
52
|
gitCommit: false,
|
|
52
53
|
gitTag: false,
|
|
53
54
|
});
|
|
54
|
-
await (0, changelog_1.releaseChangelog)({
|
|
55
|
+
const changelogResult = await (0, changelog_1.releaseChangelog)({
|
|
55
56
|
...args,
|
|
56
57
|
versionData: versionResult.projectsVersionData,
|
|
57
58
|
version: versionResult.workspaceVersion,
|
|
58
59
|
stageChanges: shouldStage,
|
|
59
60
|
gitCommit: false,
|
|
60
61
|
gitTag: false,
|
|
62
|
+
createRelease: false,
|
|
61
63
|
});
|
|
62
64
|
const { error: filterError, releaseGroups, releaseGroupToFilteredProjects, } = (0, filter_release_groups_1.filterReleaseGroups)(projectGraph, nxReleaseConfig, args.projects, args.groups);
|
|
63
65
|
if (filterError) {
|
|
@@ -90,8 +92,59 @@ async function release(args) {
|
|
|
90
92
|
});
|
|
91
93
|
}
|
|
92
94
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
+
const shouldCreateWorkspaceRelease = (0, changelog_1.shouldCreateGitHubRelease)(nxReleaseConfig.changelog.workspaceChangelog);
|
|
96
|
+
let hasPushedChanges = false;
|
|
97
|
+
let latestCommit;
|
|
98
|
+
if (shouldCreateWorkspaceRelease && changelogResult.workspaceChangelog) {
|
|
99
|
+
devkit_exports_1.output.logSingleLine(`Pushing to git remote`);
|
|
100
|
+
// Before we can create/update the release we need to ensure the commit exists on the remote
|
|
101
|
+
await (0, git_1.gitPush)({
|
|
102
|
+
dryRun: args.dryRun,
|
|
103
|
+
verbose: args.verbose,
|
|
104
|
+
});
|
|
105
|
+
hasPushedChanges = true;
|
|
106
|
+
devkit_exports_1.output.logSingleLine(`Creating GitHub Release`);
|
|
107
|
+
latestCommit = await (0, git_1.getCommitHash)('HEAD');
|
|
108
|
+
await (0, github_1.createOrUpdateGithubRelease)(changelogResult.workspaceChangelog.releaseVersion, changelogResult.workspaceChangelog.contents, latestCommit, { dryRun: args.dryRun });
|
|
109
|
+
}
|
|
110
|
+
for (const releaseGroup of releaseGroups) {
|
|
111
|
+
const shouldCreateProjectReleases = (0, changelog_1.shouldCreateGitHubRelease)(releaseGroup.changelog);
|
|
112
|
+
if (shouldCreateProjectReleases && changelogResult.projectChangelogs) {
|
|
113
|
+
const projects = args.projects?.length
|
|
114
|
+
? // If the user has passed a list of projects, we need to use the filtered list of projects within the release group
|
|
115
|
+
Array.from(releaseGroupToFilteredProjects.get(releaseGroup))
|
|
116
|
+
: // Otherwise, we use the full list of projects within the release group
|
|
117
|
+
releaseGroup.projects;
|
|
118
|
+
const projectNodes = projects.map((name) => projectGraph.nodes[name]);
|
|
119
|
+
for (const project of projectNodes) {
|
|
120
|
+
const changelog = changelogResult.projectChangelogs[project.name];
|
|
121
|
+
if (!changelog) {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
if (!hasPushedChanges) {
|
|
125
|
+
devkit_exports_1.output.logSingleLine(`Pushing to git remote`);
|
|
126
|
+
// Before we can create/update the release we need to ensure the commit exists on the remote
|
|
127
|
+
await (0, git_1.gitPush)({
|
|
128
|
+
dryRun: args.dryRun,
|
|
129
|
+
verbose: args.verbose,
|
|
130
|
+
});
|
|
131
|
+
hasPushedChanges = true;
|
|
132
|
+
}
|
|
133
|
+
devkit_exports_1.output.logSingleLine(`Creating GitHub Release`);
|
|
134
|
+
if (!latestCommit) {
|
|
135
|
+
latestCommit = await (0, git_1.getCommitHash)('HEAD');
|
|
136
|
+
}
|
|
137
|
+
await (0, github_1.createOrUpdateGithubRelease)(changelog.releaseVersion, changelog.contents, latestCommit, { dryRun: args.dryRun });
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
let hasNewVersion = false;
|
|
142
|
+
// null means that all projects are versioned together but there were no changes
|
|
143
|
+
if (versionResult.workspaceVersion !== null) {
|
|
144
|
+
hasNewVersion = Object.values(versionResult.projectsVersionData).some((version) => version.newVersion !== null);
|
|
145
|
+
}
|
|
146
|
+
let shouldPublish = !!args.yes && !args.skipPublish && hasNewVersion;
|
|
147
|
+
const shouldPromptPublishing = !args.yes && !args.skipPublish && !args.dryRun && hasNewVersion;
|
|
95
148
|
if (shouldPromptPublishing) {
|
|
96
149
|
shouldPublish = await promptForPublish();
|
|
97
150
|
}
|
|
@@ -48,7 +48,11 @@ export declare function gitTag({ tag, message, additionalArgs, dryRun, verbose,
|
|
|
48
48
|
verbose?: boolean;
|
|
49
49
|
logFn?: (message: string) => void;
|
|
50
50
|
}): Promise<string>;
|
|
51
|
-
export declare function gitPush(gitRemote
|
|
51
|
+
export declare function gitPush({ gitRemote, dryRun, verbose, }: {
|
|
52
|
+
gitRemote?: string;
|
|
53
|
+
dryRun?: boolean;
|
|
54
|
+
verbose?: boolean;
|
|
55
|
+
}): Promise<void>;
|
|
52
56
|
export declare function parseCommits(commits: RawGitCommit[]): GitCommit[];
|
|
53
57
|
export declare function parseGitCommit(commit: RawGitCommit): GitCommit | null;
|
|
54
58
|
export declare function getCommitHash(ref: string): Promise<string>;
|
|
@@ -155,17 +155,27 @@ async function gitTag({ tag, message, additionalArgs, dryRun, verbose, logFn, })
|
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
157
|
exports.gitTag = gitTag;
|
|
158
|
-
async function gitPush(gitRemote) {
|
|
158
|
+
async function gitPush({ gitRemote, dryRun, verbose, }) {
|
|
159
|
+
const commandArgs = [
|
|
160
|
+
'push',
|
|
161
|
+
// NOTE: It's important we use --follow-tags, and not --tags, so that we are precise about what we are pushing
|
|
162
|
+
'--follow-tags',
|
|
163
|
+
'--no-verify',
|
|
164
|
+
'--atomic',
|
|
165
|
+
// Set custom git remote if provided
|
|
166
|
+
...(gitRemote ? [gitRemote] : []),
|
|
167
|
+
];
|
|
168
|
+
if (verbose) {
|
|
169
|
+
console.log(dryRun
|
|
170
|
+
? `Would push the current branch to the remote with the following command, but --dry-run was set:`
|
|
171
|
+
: `Pushing the current branch to the remote with the following command:`);
|
|
172
|
+
console.log(`git ${commandArgs.join(' ')}`);
|
|
173
|
+
}
|
|
174
|
+
if (dryRun) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
159
177
|
try {
|
|
160
|
-
await (0, exec_command_1.execCommand)('git',
|
|
161
|
-
'push',
|
|
162
|
-
// NOTE: It's important we use --follow-tags, and not --tags, so that we are precise about what we are pushing
|
|
163
|
-
'--follow-tags',
|
|
164
|
-
'--no-verify',
|
|
165
|
-
'--atomic',
|
|
166
|
-
// Set custom git remote if provided
|
|
167
|
-
...(gitRemote ? [gitRemote] : []),
|
|
168
|
-
]);
|
|
178
|
+
await (0, exec_command_1.execCommand)('git', commandArgs);
|
|
169
179
|
}
|
|
170
180
|
catch (err) {
|
|
171
181
|
throw new Error(`Unexpected git push error: ${err}`);
|
|
@@ -252,7 +262,12 @@ async function getCommitHash(ref) {
|
|
|
252
262
|
exports.getCommitHash = getCommitHash;
|
|
253
263
|
async function getFirstGitCommit() {
|
|
254
264
|
try {
|
|
255
|
-
return (await (0, exec_command_1.execCommand)('git', [
|
|
265
|
+
return (await (0, exec_command_1.execCommand)('git', [
|
|
266
|
+
'rev-list',
|
|
267
|
+
'--max-parents=0',
|
|
268
|
+
'HEAD',
|
|
269
|
+
'--first-parent',
|
|
270
|
+
])).trim();
|
|
256
271
|
}
|
|
257
272
|
catch (e) {
|
|
258
273
|
throw new Error(`Unable to find first commit in git history`);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Reference } from './git';
|
|
2
|
+
import { ReleaseVersion } from './shared';
|
|
2
3
|
export type RepoSlug = `${string}/${string}`;
|
|
3
4
|
export interface GithubRequestConfig {
|
|
4
5
|
repo: string;
|
|
@@ -14,14 +15,9 @@ export interface GithubRelease {
|
|
|
14
15
|
prerelease?: boolean;
|
|
15
16
|
}
|
|
16
17
|
export declare function getGitHubRepoSlug(remoteName?: string): RepoSlug;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
prerelease: boolean;
|
|
21
|
-
commit: string;
|
|
22
|
-
}
|
|
23
|
-
export declare function createOrUpdateGithubRelease(githubRequestConfig: GithubRequestConfig, release: GithubReleaseOptions, existingGithubReleaseForVersion?: GithubRelease): Promise<void>;
|
|
18
|
+
export declare function createOrUpdateGithubRelease(releaseVersion: ReleaseVersion, changelogContents: string, latestCommit: string, { dryRun }: {
|
|
19
|
+
dryRun: boolean;
|
|
20
|
+
}): Promise<void>;
|
|
24
21
|
export declare function resolveGithubToken(): Promise<string | null>;
|
|
25
22
|
export declare function getGithubReleaseByTag(config: GithubRequestConfig, tag: string): Promise<GithubRelease>;
|
|
26
23
|
export declare function formatReferences(references: Reference[], repoSlug: RepoSlug): string;
|
|
27
|
-
export {};
|
|
@@ -8,6 +8,8 @@ const node_fs_1 = require("node:fs");
|
|
|
8
8
|
const node_os_1 = require("node:os");
|
|
9
9
|
const output_1 = require("../../../utils/output");
|
|
10
10
|
const path_1 = require("../../../utils/path");
|
|
11
|
+
const print_changes_1 = require("./print-changes");
|
|
12
|
+
const shared_1 = require("./shared");
|
|
11
13
|
// axios types and values don't seem to match
|
|
12
14
|
const _axios = require("axios");
|
|
13
15
|
const axios = _axios;
|
|
@@ -32,7 +34,65 @@ function getGitHubRepoSlug(remoteName = 'origin') {
|
|
|
32
34
|
}
|
|
33
35
|
}
|
|
34
36
|
exports.getGitHubRepoSlug = getGitHubRepoSlug;
|
|
35
|
-
async function createOrUpdateGithubRelease(
|
|
37
|
+
async function createOrUpdateGithubRelease(releaseVersion, changelogContents, latestCommit, { dryRun }) {
|
|
38
|
+
const githubRepoSlug = getGitHubRepoSlug();
|
|
39
|
+
if (!githubRepoSlug) {
|
|
40
|
+
output_1.output.error({
|
|
41
|
+
title: `Unable to create a GitHub release because the GitHub repo slug could not be determined.`,
|
|
42
|
+
bodyLines: [
|
|
43
|
+
`Please ensure you have a valid GitHub remote configured. You can run \`git remote -v\` to list your current remotes.`,
|
|
44
|
+
],
|
|
45
|
+
});
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
const token = await resolveGithubToken();
|
|
49
|
+
const githubRequestConfig = {
|
|
50
|
+
repo: githubRepoSlug,
|
|
51
|
+
token,
|
|
52
|
+
};
|
|
53
|
+
let existingGithubReleaseForVersion;
|
|
54
|
+
try {
|
|
55
|
+
existingGithubReleaseForVersion = await getGithubReleaseByTag(githubRequestConfig, releaseVersion.gitTag);
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
if (err.response?.status === 401) {
|
|
59
|
+
output_1.output.error({
|
|
60
|
+
title: `Unable to resolve data via the GitHub API. You can use any of the following options to resolve this:`,
|
|
61
|
+
bodyLines: [
|
|
62
|
+
'- Set the `GITHUB_TOKEN` or `GH_TOKEN` environment variable to a valid GitHub token with `repo` scope',
|
|
63
|
+
'- Have an active session via the official gh CLI tool (https://cli.github.com) in your current terminal',
|
|
64
|
+
],
|
|
65
|
+
});
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
if (err.response?.status === 404) {
|
|
69
|
+
// No existing release found, this is fine
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
// Rethrow unknown errors for now
|
|
73
|
+
throw err;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const logTitle = `https://github.com/${githubRepoSlug}/releases/tag/${releaseVersion.gitTag}`;
|
|
77
|
+
if (existingGithubReleaseForVersion) {
|
|
78
|
+
console.error(`${chalk.white('UPDATE')} ${logTitle}${dryRun ? chalk.keyword('orange')(' [dry-run]') : ''}`);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
console.error(`${chalk.green('CREATE')} ${logTitle}${dryRun ? chalk.keyword('orange')(' [dry-run]') : ''}`);
|
|
82
|
+
}
|
|
83
|
+
console.log('');
|
|
84
|
+
(0, print_changes_1.printDiff)(existingGithubReleaseForVersion ? existingGithubReleaseForVersion.body : '', changelogContents, 3, shared_1.noDiffInChangelogMessage);
|
|
85
|
+
if (!dryRun) {
|
|
86
|
+
await createOrUpdateGithubReleaseInternal(githubRequestConfig, {
|
|
87
|
+
version: releaseVersion.gitTag,
|
|
88
|
+
prerelease: releaseVersion.isPrerelease,
|
|
89
|
+
body: changelogContents,
|
|
90
|
+
commit: latestCommit,
|
|
91
|
+
}, existingGithubReleaseForVersion);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
exports.createOrUpdateGithubRelease = createOrUpdateGithubRelease;
|
|
95
|
+
async function createOrUpdateGithubReleaseInternal(githubRequestConfig, release, existingGithubReleaseForVersion) {
|
|
36
96
|
const result = await syncGithubRelease(githubRequestConfig, release, existingGithubReleaseForVersion);
|
|
37
97
|
/**
|
|
38
98
|
* If something went wrong POSTing to Github we can still pre-populate the web form on github.com
|
|
@@ -98,7 +158,6 @@ async function createOrUpdateGithubRelease(githubRequestConfig, release, existin
|
|
|
98
158
|
});
|
|
99
159
|
}
|
|
100
160
|
}
|
|
101
|
-
exports.createOrUpdateGithubRelease = createOrUpdateGithubRelease;
|
|
102
161
|
async function promptForContinueInGitHub() {
|
|
103
162
|
try {
|
|
104
163
|
const reply = await (0, enquirer_1.prompt)([
|
|
@@ -2,6 +2,7 @@ import { ProjectGraph } from '../../../config/project-graph';
|
|
|
2
2
|
import { Tree } from '../../../generators/tree';
|
|
3
3
|
import type { ReleaseGroupWithName } from '../config/filter-release-groups';
|
|
4
4
|
import { GitCommit } from './git';
|
|
5
|
+
export declare const noDiffInChangelogMessage: string;
|
|
5
6
|
export type ReleaseVersionGeneratorResult = {
|
|
6
7
|
data: VersionData;
|
|
7
8
|
callback: (tree: Tree, opts: {
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getCommitsRelevantToProjects = exports.handleDuplicateGitTags = exports.createGitTagValues = exports.createCommitMessageValues = exports.commitChanges = exports.ReleaseVersion = void 0;
|
|
3
|
+
exports.getCommitsRelevantToProjects = exports.handleDuplicateGitTags = exports.createGitTagValues = exports.createCommitMessageValues = exports.commitChanges = exports.ReleaseVersion = exports.noDiffInChangelogMessage = void 0;
|
|
4
|
+
const chalk = require("chalk");
|
|
4
5
|
const semver_1 = require("semver");
|
|
5
6
|
const file_map_utils_1 = require("../../../project-graph/file-map-utils");
|
|
6
7
|
const utils_1 = require("../../../tasks-runner/utils");
|
|
7
8
|
const output_1 = require("../../../utils/output");
|
|
8
9
|
const git_1 = require("./git");
|
|
10
|
+
exports.noDiffInChangelogMessage = chalk.yellow(`NOTE: There was no diff detected for the changelog entry. Maybe you intended to pass alternative git references via --from and --to?`);
|
|
9
11
|
function isPrerelease(version) {
|
|
10
12
|
// prerelease returns an array of matching prerelease "components", or null if the version is not a prerelease
|
|
11
13
|
return (0, semver_1.prerelease)(version) !== null;
|
|
@@ -704,57 +704,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
704
704
|
SOFTWARE.
|
|
705
705
|
|
|
706
706
|
|
|
707
|
-
regenerator-runtime
|
|
708
|
-
MIT
|
|
709
|
-
MIT License
|
|
710
|
-
|
|
711
|
-
Copyright (c) 2014-present, Facebook, Inc.
|
|
712
|
-
|
|
713
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
714
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
715
|
-
in the Software without restriction, including without limitation the rights
|
|
716
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
717
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
718
|
-
furnished to do so, subject to the following conditions:
|
|
719
|
-
|
|
720
|
-
The above copyright notice and this permission notice shall be included in all
|
|
721
|
-
copies or substantial portions of the Software.
|
|
722
|
-
|
|
723
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
724
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
725
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
726
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
727
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
728
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
729
|
-
SOFTWARE.
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
tabbable
|
|
733
|
-
MIT
|
|
734
|
-
The MIT License (MIT)
|
|
735
|
-
|
|
736
|
-
Copyright (c) 2015 David Clark
|
|
737
|
-
|
|
738
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
739
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
740
|
-
in the Software without restriction, including without limitation the rights
|
|
741
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
742
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
743
|
-
furnished to do so, subject to the following conditions:
|
|
744
|
-
|
|
745
|
-
The above copyright notice and this permission notice shall be included in all
|
|
746
|
-
copies or substantial portions of the Software.
|
|
747
|
-
|
|
748
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
749
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
750
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
751
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
752
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
753
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
754
|
-
SOFTWARE.
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
707
|
toggle-selection
|
|
759
708
|
MIT
|
|
760
709
|
|