1 | 'use strict';
|
2 |
|
3 | Object.defineProperty(exports, '__esModule', { value: true });
|
4 |
|
5 | function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
|
6 |
|
7 | var path = require('path');
|
8 | var commander$1 = require('commander');
|
9 | var fs = require('fs');
|
10 | var invariant = _interopDefault(require('invariant'));
|
11 | var loudRejection = _interopDefault(require('loud-rejection'));
|
12 | var semver = _interopDefault(require('semver'));
|
13 | var chalk = _interopDefault(require('chalk'));
|
14 | var inquirer = require('inquirer');
|
15 | var read = _interopDefault(require('read'));
|
16 | var readline = require('readline');
|
17 | var stripAnsi = _interopDefault(require('strip-ansi'));
|
18 | var tty = require('tty');
|
19 | var util = require('util');
|
20 | require('camelcase');
|
21 | var isCI = require('is-ci');
|
22 | var os = require('os');
|
23 | var events = require('events');
|
24 | var _rimraf = _interopDefault(require('rimraf'));
|
25 | var _mkdirp = _interopDefault(require('mkdirp'));
|
26 | var _glob = _interopDefault(require('glob'));
|
27 | var stripBOM = _interopDefault(require('strip-bom'));
|
28 | var types = require('@pika/types');
|
29 | var child_process = require('child_process');
|
30 | var isBuiltinModule = _interopDefault(require('is-builtin-module'));
|
31 | var validateLicense = _interopDefault(require('validate-npm-package-license'));
|
32 | var nodeUrl = require('url');
|
33 | var detectIndent = _interopDefault(require('detect-indent'));
|
34 | var importFrom = _interopDefault(require('import-from'));
|
35 | var uri2path = _interopDefault(require('file-uri-to-path'));
|
36 |
|
37 |
|
38 | function sortAlpha(a, b) {
|
39 |
|
40 | const shortLen = Math.min(a.length, b.length);
|
41 |
|
42 | for (let i = 0; i < shortLen; i++) {
|
43 | const aChar = a.charCodeAt(i);
|
44 | const bChar = b.charCodeAt(i);
|
45 |
|
46 | if (aChar !== bChar) {
|
47 | return aChar - bChar;
|
48 | }
|
49 | }
|
50 |
|
51 | return a.length - b.length;
|
52 | }
|
53 | function sortOptionsByFlags(a, b) {
|
54 | const aOpt = a.flags.replace(/-/g, '');
|
55 | const bOpt = b.flags.replace(/-/g, '');
|
56 | return sortAlpha(aOpt, bOpt);
|
57 | }
|
58 | function removeSuffix(pattern, suffix) {
|
59 | if (pattern.endsWith(suffix)) {
|
60 | return pattern.slice(0, -suffix.length);
|
61 | }
|
62 |
|
63 | return pattern;
|
64 | }
|
65 |
|
66 | function formatFunction(...strs) {
|
67 | return strs.join(' ');
|
68 | }
|
69 |
|
70 | const defaultFormatter = {
|
71 | bold: formatFunction,
|
72 | dim: formatFunction,
|
73 | italic: formatFunction,
|
74 | underline: formatFunction,
|
75 | inverse: formatFunction,
|
76 | strikethrough: formatFunction,
|
77 | black: formatFunction,
|
78 | red: formatFunction,
|
79 | green: formatFunction,
|
80 | yellow: formatFunction,
|
81 | blue: formatFunction,
|
82 | magenta: formatFunction,
|
83 | cyan: formatFunction,
|
84 | white: formatFunction,
|
85 | gray: formatFunction,
|
86 | grey: formatFunction,
|
87 | stripColor: formatFunction
|
88 | };
|
89 |
|
90 | const messages = {
|
91 | upToDate: 'Already up-to-date.',
|
92 | folderInSync: 'Folder in sync.',
|
93 | nothingToInstall: 'Nothing to install.',
|
94 | resolvingPackages: 'Resolving packages',
|
95 | checkingManifest: 'Validating package.json',
|
96 | fetchingPackages: 'Fetching packages',
|
97 | linkingDependencies: 'Linking dependencies',
|
98 | rebuildingPackages: 'Rebuilding all packages',
|
99 | buildingFreshPackages: 'Building fresh packages',
|
100 | cleaningModules: 'Cleaning modules',
|
101 | bumpingVersion: 'Bumping version',
|
102 | savingHar: 'Saving HAR file: $0',
|
103 | answer: 'Answer?',
|
104 | usage: 'Usage',
|
105 | installCommandRenamed: '`install` has been replaced with `add` to add new dependencies. Run $0 instead.',
|
106 | globalFlagRemoved: '`--global` has been deprecated. Please run $0 instead.',
|
107 | waitingInstance: 'Waiting for the other pika instance to finish (pid $0, inside $1)',
|
108 | waitingNamedInstance: 'Waiting for the other pika instance to finish ($0)',
|
109 | offlineRetrying: 'There appears to be trouble with your network connection. Retrying...',
|
110 | internalServerErrorRetrying: 'There appears to be trouble with the npm registry (returned $1). Retrying...',
|
111 | clearedCache: 'Cleared cache.',
|
112 | couldntClearPackageFromCache: "Couldn't clear package $0 from cache",
|
113 | clearedPackageFromCache: 'Cleared package $0 from cache',
|
114 | packWroteTarball: 'Wrote tarball to $0.',
|
115 | helpExamples: ' Examples:\n$0\n',
|
116 | helpCommands: ' Commands:\n$0\n',
|
117 | helpCommandsMore: ' Run `$0` for more information on specific commands.',
|
118 | helpLearnMore: ' Visit $0 to learn more about Pika.\n',
|
119 | manifestPotentialTypo: 'Potential typo $0, did you mean $1?',
|
120 | manifestBuiltinModule: '$0 is also the name of a node core module',
|
121 | manifestNameDot: "Name can't start with a dot",
|
122 | manifestNameIllegalChars: 'Name contains illegal characters',
|
123 | manifestNameBlacklisted: 'Name is blacklisted',
|
124 | manifestLicenseInvalid: 'License should be a valid SPDX license expression',
|
125 | manifestLicenseNone: 'No license field',
|
126 | manifestStringExpected: '$0 is not a string',
|
127 | manifestDependencyCollision: '$0 has dependency $1 with range $2 that collides with a dependency in $3 of the same name with version $4',
|
128 | manifestDirectoryNotFound: 'Unable to read $0 directory of module $1',
|
129 | verboseFileCopy: 'Copying $0 to $1.',
|
130 | verboseFileLink: 'Creating hardlink at $0 to $1.',
|
131 | verboseFileSymlink: 'Creating symlink at $0 to $1.',
|
132 | verboseFileSkip: 'Skipping copying of file $0 as the file at $1 is the same size ($2) and mtime ($3).',
|
133 | verboseFileSkipSymlink: 'Skipping copying of $0 as the file at $1 is the same symlink ($2).',
|
134 | verboseFileSkipHardlink: 'Skipping copying of $0 as the file at $1 is the same hardlink ($2).',
|
135 | verboseFileRemoveExtraneous: 'Removing extraneous file $0.',
|
136 | verboseFilePhantomExtraneous: "File $0 would be marked as extraneous but has been removed as it's listed as a phantom file.",
|
137 | verboseFileSkipArtifact: 'Skipping copying of $0 as the file is marked as a built artifact and subject to change.',
|
138 | verboseFileFolder: 'Creating directory $0.',
|
139 | verboseRequestStart: 'Performing $0 request to $1.',
|
140 | verboseRequestFinish: 'Request $0 finished with status code $1.',
|
141 | configSet: 'Set $0 to $1.',
|
142 | configDelete: 'Deleted $0.',
|
143 | configNpm: 'npm config',
|
144 | configPika: 'pika config',
|
145 | couldntFindPackagejson: "Couldn't find a package.json file in $0",
|
146 | couldntFindMatch: "Couldn't find match for $0 in $1 for $2.",
|
147 | couldntFindPackageInCache: "Couldn't find any versions for $0 that matches $1 in our cache (possible versions are $2). This is usually caused by a missing entry in the lockfile, running Pika without the --offline flag may help fix this issue.",
|
148 | couldntFindVersionThatMatchesRange: "Couldn't find any versions for $0 that matches $1",
|
149 | chooseVersionFromList: 'Please choose a version of $0 from this list:',
|
150 | moduleNotInManifest: "This module isn't specified in a package.json file.",
|
151 | moduleAlreadyInManifest: '$0 is already in $1. Please remove existing entry first before adding it to $2.',
|
152 | unknownFolderOrTarball: "Passed folder/tarball doesn't exist,",
|
153 | unknownPackage: "Couldn't find package $0.",
|
154 | unknownPackageName: "Couldn't find package name.",
|
155 | unknownUser: "Couldn't find user $0.",
|
156 | unknownRegistryResolver: 'Unknown registry resolver $0',
|
157 | userNotAnOwner: "User $0 isn't an owner of this package.",
|
158 | invalidVersionArgument: 'Use the $0 flag to create a new version.',
|
159 | invalidVersion: 'Invalid version supplied.',
|
160 | requiredVersionInRange: 'Required version in range.',
|
161 | packageNotFoundRegistry: "Couldn't find package $0 on the $1 registry.",
|
162 | requiredPackageNotFoundRegistry: "Couldn't find package $0 required by $1 on the $2 registry.",
|
163 | doesntExist: "Package $1 refers to a non-existing file '$0'.",
|
164 | missingRequiredPackageKey: `Package $0 doesn't have a $1.`,
|
165 | invalidAccess: 'Invalid argument for access, expected public or restricted.',
|
166 | invalidCommand: 'Invalid subcommand. Try $0',
|
167 | invalidGistFragment: 'Invalid gist fragment $0.',
|
168 | invalidHostedGitFragment: 'Invalid hosted git fragment $0.',
|
169 | invalidFragment: 'Invalid fragment $0.',
|
170 | invalidPackageName: 'Invalid package name.',
|
171 | invalidPackageVersion: "Can't add $0: invalid package version $1.",
|
172 | couldntFindManifestIn: "Couldn't find manifest in $0.",
|
173 | shrinkwrapWarning: 'npm-shrinkwrap.json found. This will not be updated or respected. See https://yarnpkg.com/en/docs/migrating-from-npm for more information.',
|
174 | npmLockfileWarning: 'package-lock.json found. Your project contains lock files generated by tools other than Pika. It is advised not to mix package managers in order to avoid resolution inconsistencies caused by unsynchronized lock files. To clear this warning, remove package-lock.json.',
|
175 | lockfileOutdated: 'Outdated lockfile. Please run `pika install` and try again.',
|
176 | lockfileMerged: 'Merge conflict detected in pika.lock and successfully merged.',
|
177 | lockfileConflict: 'A merge conflict was found in pika.lock but it could not be successfully merged, regenerating pika.lock from scratch.',
|
178 | ignoredScripts: 'Ignored scripts due to flag.',
|
179 | missingAddDependencies: 'Missing list of packages to add to your project.',
|
180 | yesWarning: 'The yes flag has been set. This will automatically answer yes to all questions, which may have security implications.',
|
181 | networkWarning: "You don't appear to have an internet connection. Try the --offline flag to use the cache for registry queries.",
|
182 | flatGlobalError: 'The package $0 requires a flat dependency graph. Add `"flat": true` to your package.json and try again.',
|
183 | noName: `Package doesn't have a name.`,
|
184 | noVersion: `Package doesn't have a version.`,
|
185 | answerRequired: 'An answer is required.',
|
186 | missingWhyDependency: 'Missing package name, folder or path to file to identify why a package has been installed',
|
187 | bugReport: 'If you think this is a bug, please open a bug report with the information provided in $0.',
|
188 | unexpectedError: 'An unexpected error occurred: $0.',
|
189 | jsonError: 'Error parsing JSON at $0, $1.',
|
190 | noPermission: 'Cannot create $0 due to insufficient permissions.',
|
191 | noGlobalFolder: 'Cannot find a suitable global folder. Tried these: $0',
|
192 | allDependenciesUpToDate: 'All of your dependencies are up to date.',
|
193 | legendColorsForVersionUpdates: 'Color legend : \n $0 : Major Update backward-incompatible updates \n $1 : Minor Update backward-compatible features \n $2 : Patch Update backward-compatible bug fixes',
|
194 | frozenLockfileError: 'Your lockfile needs to be updated, but pika was run with `--frozen-lockfile`.',
|
195 | fileWriteError: 'Could not write file $0: $1',
|
196 | fileDeleteError: 'Could not delete file $0: $1',
|
197 | multiplePackagesCantUnpackInSameDestination: 'Pattern $0 is trying to unpack in the same destination $1 as pattern $2. This could result in non-deterministic behavior, skipping.',
|
198 | incorrectLockfileEntry: 'Lockfile has incorrect entry for $0. Ignoring it.',
|
199 | invalidResolutionName: 'Resolution field $0 does not end with a valid package name and will be ignored',
|
200 | invalidResolutionVersion: 'Resolution field $0 has an invalid version entry and may be ignored',
|
201 | incompatibleResolutionVersion: 'Resolution field $0 is incompatible with requested version $1',
|
202 | pikaOutdated: "Your current version of Pika is out of date. The latest version is $0, while you're on $1.",
|
203 | pikaOutdatedInstaller: 'To upgrade, download the latest installer at $0.',
|
204 | pikaOutdatedCommand: 'To upgrade, run the following command:',
|
205 | tooManyArguments: 'Too many arguments, maximum of $0.',
|
206 | tooFewArguments: 'Not enough arguments, expected at least $0.',
|
207 | noArguments: "This command doesn't require any arguments.",
|
208 | ownerRemoving: 'Removing owner $0 from package $1.',
|
209 | ownerRemoved: 'Owner removed.',
|
210 | ownerRemoveError: "Couldn't remove owner.",
|
211 | ownerGetting: 'Getting owners for package $0',
|
212 | ownerGettingFailed: "Couldn't get list of owners.",
|
213 | ownerAlready: 'This user is already an owner of this package.',
|
214 | ownerAdded: 'Added owner.',
|
215 | ownerAdding: 'Adding owner $0 to package $1',
|
216 | ownerAddingFailed: "Couldn't add owner.",
|
217 | ownerNone: 'No owners.',
|
218 | teamCreating: 'Creating team',
|
219 | teamRemoving: 'Removing team',
|
220 | teamAddingUser: 'Adding user to team',
|
221 | teamRemovingUser: 'Removing user from team',
|
222 | teamListing: 'Listing teams',
|
223 | distFailed: `⚠️ Distribution "$0" failed to build: $1 $2`,
|
224 | distExiting: ` Exiting...`,
|
225 | distContinuing: ` Continuing...`,
|
226 | cleaning: 'Cleaning modules',
|
227 | cleanCreatingFile: 'Creating $0',
|
228 | cleanCreatedFile: 'Created $0. Please review the contents of this file then run "pika autoclean --force" to perform a clean.',
|
229 | cleanAlreadyExists: '$0 already exists. To revert to the default file, delete $0 then rerun this command.',
|
230 | cleanRequiresForce: 'This command required the "--force" flag to perform the clean. This is a destructive operation. Files specified in $0 will be deleted.',
|
231 | cleanDoesNotExist: '$0 does not exist. Autoclean will delete files specified by $0. Run "autoclean --init" to create $0 with the default entries.',
|
232 | binLinkCollision: "There's already a linked binary called $0 in your global Pika bin. Could not link this package's $0 bin entry.",
|
233 | linkCollision: "There's already a package called $0 registered. This command has had no effect. If this command was run in another folder with the same name, the other folder is still linked. Please run pika unlink in the other folder if you want to register this folder.",
|
234 | linkMissing: 'No registered package found called $0.',
|
235 | linkRegistered: 'Registered $0.',
|
236 | linkRegisteredMessage: 'You can now run `pika link $0` in the projects where you want to use this package and it will be used instead.',
|
237 | linkUnregistered: 'Unregistered $0.',
|
238 | linkUnregisteredMessage: 'You can now run `pika unlink $0` in the projects where you no longer want to use this package.',
|
239 | linkUsing: 'Using linked package for $0.',
|
240 | linkDisusing: 'Removed linked package $0.',
|
241 | linkDisusingMessage: 'You will need to run `pika` to re-install the package that was linked.',
|
242 | linkTargetMissing: 'The target of linked package $0 is missing. Removing link.',
|
243 | createInvalidBin: 'Invalid bin entry found in package $0.',
|
244 | createMissingPackage: 'Package not found - this is probably an internal error, and should be reported at https://github.com/yarnpkg/yarn/issues.',
|
245 | workspacesAddRootCheck: 'Running this command will add the dependency to the workspace root rather than the workspace itself, which might not be what you want - if you really meant it, make it explicit by running this command again with the -W flag (or --ignore-workspace-root-check).',
|
246 | workspacesRemoveRootCheck: 'Running this command will remove the dependency from the workspace root rather than the workspace itself, which might not be what you want - if you really meant it, make it explicit by running this command again with the -W flag (or --ignore-workspace-root-check).',
|
247 | workspacesFocusRootCheck: 'This command can only be run inside an individual workspace.',
|
248 | workspacesRequirePrivateProjects: 'Workspaces can only be enabled in private projects.',
|
249 | workspacesSettingMustBeArray: 'The workspaces field in package.json must be an array.',
|
250 | workspacesDisabled: 'Your project root defines workspaces but the feature is disabled in your Pika config. Please check "workspaces-experimental" in your .pikarc file.',
|
251 | workspacesNohoistRequirePrivatePackages: 'nohoist config is ignored in $0 because it is not a private package. If you think nohoist should be allowed in public packages, please submit an issue for your use case.',
|
252 | workspacesNohoistDisabled: `$0 defines nohoist but the feature is disabled in your Pika config ("workspaces-nohoist-experimental" in .pikarc file)`,
|
253 | workspaceRootNotFound: "Cannot find the root of your workspace - are you sure you're currently in a workspace?",
|
254 | workspaceMissingWorkspace: 'Missing workspace name.',
|
255 | workspaceMissingCommand: 'Missing command name.',
|
256 | workspaceUnknownWorkspace: 'Unknown workspace $0.',
|
257 | workspaceVersionMandatory: 'Missing version in workspace at $0, ignoring.',
|
258 | workspaceNameMandatory: 'Missing name in workspace at $0, ignoring.',
|
259 | workspaceNameDuplicate: 'There are more than one workspace with name $0',
|
260 | cacheFolderSkipped: 'Skipping preferred cache folder $0 because it is not writable.',
|
261 | cacheFolderMissing: "Pika hasn't been able to find a cache folder it can use. Please use the explicit --cache-folder option to tell it what location to use, or make one of the preferred locations writable.",
|
262 | cacheFolderSelected: 'Selected the next writable cache folder in the list, will be $0.',
|
263 | execMissingCommand: 'Missing command name.',
|
264 | noScriptsAvailable: 'There are no scripts specified inside package.json.',
|
265 | noBinAvailable: 'There are no binary scripts available.',
|
266 | dashDashDeprecation: `From Pika 1.0 onwards, scripts don't require "--" for options to be forwarded. In a future version, any explicit "--" will be forwarded as-is to the scripts.`,
|
267 | commandNotSpecified: 'No command specified.',
|
268 | binCommands: 'Commands available from binary scripts: ',
|
269 | possibleCommands: 'Project commands',
|
270 | commandQuestion: 'Which command would you like to run?',
|
271 | commandFailedWithCode: 'Command failed with exit code $0.',
|
272 | commandFailedWithSignal: 'Command failed with signal $0.',
|
273 | packageRequiresNodeGyp: 'This package requires node-gyp, which is not currently installed. Pika will attempt to automatically install it. If this fails, you can run "pika global add node-gyp" to manually install it.',
|
274 | nodeGypAutoInstallFailed: 'Failed to auto-install node-gyp. Please run "pika global add node-gyp" manually. Error: $0',
|
275 | foundIncompatible: 'Found incompatible module',
|
276 | incompatibleEngine: 'The engine $0 is incompatible with this module. Expected version $1. Got $2',
|
277 | incompatibleCPU: 'The CPU architecture $0 is incompatible with this module.',
|
278 | incompatibleOS: 'The platform $0 is incompatible with this module.',
|
279 | invalidEngine: 'The engine $0 appears to be invalid.',
|
280 | optionalCompatibilityExcluded: '$0 is an optional dependency and failed compatibility check. Excluding it from installation.',
|
281 | optionalModuleFail: 'This module is OPTIONAL, you can safely ignore this error',
|
282 | optionalModuleScriptFail: 'Error running install script for optional dependency: $0',
|
283 | optionalModuleCleanupFail: 'Could not cleanup build artifacts from failed install: $0',
|
284 | unmetPeer: '$0 has unmet peer dependency $1.',
|
285 | incorrectPeer: '$0 has incorrect peer dependency $1.',
|
286 | selectedPeer: 'Selecting $1 at level $2 as the peer dependency of $0.',
|
287 | missingBundledDependency: '$0 is missing a bundled dependency $1. This should be reported to the package maintainer.',
|
288 | savedNewDependency: 'Saved 1 new dependency.',
|
289 | savedNewDependencies: 'Saved $0 new dependencies.',
|
290 | directDependencies: 'Direct dependencies',
|
291 | allDependencies: 'All dependencies',
|
292 | foundWarnings: 'Found $0 warnings.',
|
293 | foundErrors: 'Found $0 errors.',
|
294 | savedLockfile: 'Saved lockfile.',
|
295 | noRequiredLockfile: 'No lockfile in this directory. Run `pika install` to generate one.',
|
296 | noLockfileFound: 'No lockfile found.',
|
297 | invalidSemver: 'Invalid semver version',
|
298 | newVersion: 'New version',
|
299 | currentVersion: 'Current version',
|
300 | noVersionOnPublish: 'Proceeding with current version',
|
301 | manualVersionResolution: 'Unable to find a suitable version for $0, please choose one by typing one of the numbers below:',
|
302 | manualVersionResolutionOption: '$0 which resolved to $1',
|
303 | createdTag: 'Created tag.',
|
304 | createdTagFail: "Couldn't add tag.",
|
305 | deletedTag: 'Deleted tag.',
|
306 | deletedTagFail: "Couldn't delete tag.",
|
307 | gettingTags: 'Getting tags',
|
308 | deletingTags: 'Deleting tag',
|
309 | creatingTag: 'Creating tag $0 = $1',
|
310 | whyStart: 'Why do we have the module $0?',
|
311 | whyFinding: 'Finding dependency',
|
312 | whyCalculating: 'Calculating file sizes',
|
313 | whyUnknownMatch: "We couldn't find a match!",
|
314 | whyInitGraph: 'Initialising dependency graph',
|
315 | whyWhoKnows: "We don't know why this module exists",
|
316 | whyDiskSizeWithout: 'Disk size without dependencies: $0',
|
317 | whyDiskSizeUnique: 'Disk size with unique dependencies: $0',
|
318 | whyDiskSizeTransitive: 'Disk size with transitive dependencies: $0',
|
319 | whySharedDependencies: 'Number of shared dependencies: $0',
|
320 | whyHoistedTo: `Has been hoisted to $0`,
|
321 | whyHoistedFromSimple: `This module exists because it's hoisted from $0.`,
|
322 | whyNotHoistedSimple: `This module exists here because it's in the nohoist list $0.`,
|
323 | whyDependedOnSimple: `This module exists because $0 depends on it.`,
|
324 | whySpecifiedSimple: `This module exists because it's specified in $0.`,
|
325 | whyReasons: 'Reasons this module exists',
|
326 | whyHoistedFrom: 'Hoisted from $0',
|
327 | whyNotHoisted: `in the nohoist list $0`,
|
328 | whyDependedOn: '$0 depends on it',
|
329 | whySpecified: `Specified in $0`,
|
330 | whyMatch: `\r=> Found $0`,
|
331 | uninstalledPackages: 'Uninstalled packages.',
|
332 | uninstallRegenerate: 'Regenerating lockfile and installing missing dependencies',
|
333 | cleanRemovedFiles: 'Removed $0 files',
|
334 | cleanSavedSize: 'Saved $0 MB.',
|
335 | configFileFound: 'Found configuration file $0.',
|
336 | configPossibleFile: 'Checking for configuration file $0.',
|
337 | npmUsername: 'npm username',
|
338 | npmPassword: 'npm password',
|
339 | npmEmail: 'npm email',
|
340 | npmOneTimePassword: 'npm one-time password',
|
341 | loggingIn: 'Logging in',
|
342 | loggedIn: 'Logged in.',
|
343 | notRevokingEnvToken: 'Not revoking login token, specified via environment variable.',
|
344 | notRevokingConfigToken: 'Not revoking login token, specified via config file.',
|
345 | noTokenToRevoke: 'No login token to revoke.',
|
346 | revokingToken: 'Revoking token',
|
347 | revokedToken: 'Revoked login token.',
|
348 | loginAsPublic: 'Logging in as public',
|
349 | incorrectCredentials: 'Incorrect username or password.',
|
350 | incorrectOneTimePassword: 'Incorrect one-time password.',
|
351 | twoFactorAuthenticationEnabled: 'Two factor authentication enabled.',
|
352 | clearedCredentials: 'Cleared login credentials.',
|
353 | publishFail: "Couldn't publish package: $0",
|
354 | publishPrivate: 'Package marked as private, not publishing.',
|
355 | published: 'Published.',
|
356 | publishing: 'Publishing',
|
357 | nonInteractiveNoVersionSpecified: 'You must specify a new version with --new-version when running with --non-interactive.',
|
358 | nonInteractiveNoToken: "No token found and can't prompt for login when running with --non-interactive.",
|
359 | infoFail: 'Received invalid response from npm.',
|
360 | malformedRegistryResponse: 'Received malformed response from registry for $0. The registry may be down.',
|
361 | registryNoVersions: 'No valid versions found for $0. The package may be unpublished.',
|
362 | cantRequestOffline: "Can't make a request in offline mode ($0)",
|
363 | requestManagerNotSetupHAR: 'RequestManager was not setup to capture HAR files',
|
364 | requestError: 'Request $0 returned a $1',
|
365 | requestFailed: 'Request failed $0',
|
366 | tarballNotInNetworkOrCache: '$0: Tarball is not in network and can not be located in cache ($1)',
|
367 | fetchBadHashWithPath: "Integrity check failed for $0 (computed integrity doesn't match our records, got $2)",
|
368 | fetchBadIntegrityAlgorithm: 'Integrity checked failed for $0 (none of the specified algorithms are supported)',
|
369 | fetchErrorCorrupt: '$0. Mirror tarball appears to be corrupt. You can resolve this by running:\n\n rm -rf $1\n pika install',
|
370 | errorExtractingTarball: 'Extracting tar content of $1 failed, the file appears to be corrupt: $0',
|
371 | updateInstalling: 'Installing $0...',
|
372 | hostedGitResolveError: 'Error connecting to repository. Please, check the url.',
|
373 | unknownFetcherFor: 'Unknown fetcher for $0',
|
374 | downloadGitWithoutCommit: 'Downloading the git repo $0 over plain git without a commit hash',
|
375 | downloadHTTPWithoutCommit: 'Downloading the git repo $0 over HTTP without a commit hash',
|
376 | unplugDisabled: "Packages can only be unplugged when Plug'n'Play is enabled.",
|
377 | plugnplayWindowsSupport: "Plug'n'Play on Windows doesn't support the cache and project to be kept on separate drives",
|
378 | packageInstalledWithBinaries: 'Installed $0 with binaries:',
|
379 | packageHasBinaries: '$0 has binaries:',
|
380 | packageHasNoBinaries: '$0 has no binaries',
|
381 | packageBinaryNotFound: "Couldn't find a binary named $0",
|
382 | couldBeDeduped: '$0 could be deduped from $1 to $2',
|
383 | lockfileNotContainPattern: 'Lockfile does not contain pattern: $0',
|
384 | integrityCheckFailed: 'Integrity check failed',
|
385 | noIntegrityFile: "Couldn't find an integrity file",
|
386 | integrityFailedExpectedIsNotAJSON: 'Integrity check: integrity file is not a json',
|
387 | integrityCheckLinkedModulesDontMatch: "Integrity check: Linked modules don't match",
|
388 | integrityFlagsDontMatch: "Integrity check: Flags don't match",
|
389 | integrityLockfilesDontMatch: "Integrity check: Lock files don't match",
|
390 | integrityFailedFilesMissing: 'Integrity check: Files are missing',
|
391 | integrityPatternsDontMatch: "Integrity check: Top level patterns don't match",
|
392 | integrityModulesFoldersMissing: 'Integrity check: Some module folders are missing',
|
393 | integritySystemParamsDontMatch: "Integrity check: System parameters don't match",
|
394 | packageNotInstalled: '$0 not installed',
|
395 | optionalDepNotInstalled: 'Optional dependency $0 not installed',
|
396 | packageWrongVersion: '$0 is wrong version: expected $1, got $2',
|
397 | packageDontSatisfy: "$0 doesn't satisfy found match of $1",
|
398 | lockfileExists: 'Lockfile already exists, not migrating.',
|
399 | pikaManifestExists: 'pika.package.json manifest already exists, not migrating.',
|
400 | noManifestExists: 'No package.json manifest found. Run `pika init` to generate a new pika.package.json manifest.',
|
401 | skippingImport: 'Skipping import of $0 for $1',
|
402 | importFailed: 'Import of $0 for $1 failed, resolving normally.',
|
403 | importResolveFailed: 'Import of $0 failed starting in $1',
|
404 | importResolvedRangeMatch: 'Using version $0 of $1 instead of $2 for $3',
|
405 | importSourceFilesCorrupted: 'Failed to import from package-lock.json, source file(s) corrupted',
|
406 | importPackageLock: 'found npm package-lock.json, converting to pika.lock',
|
407 | importYarnLock: 'found yarn.lock, converting to pika.lock',
|
408 | importNodeModules: 'creating pika.lock from local node_modules folder',
|
409 | packageContainsPikaAsGlobal: 'Installing Pika via Pika will result in you having two separate versions of Pika installed at the same time, which is not recommended. To update Pika please follow https://yarnpkg.com/en/docs/install .',
|
410 | watchStarting: `Starting up`,
|
411 | watchRunning: `Ready! Watching source tree for changes`,
|
412 | watchRebuild: `Rebuilding...`,
|
413 | watchError: `Build error!`,
|
414 | noValidationErrors: `0 Validation Errors found.`,
|
415 | validationErrors: `$0 Validation Error(s) found. Resolve before publishing.`,
|
416 | scopeNotValid: 'The specified scope is not valid.',
|
417 | deprecatedCommand: '$0 is deprecated. Please use $1.',
|
418 | deprecatedListArgs: 'Filtering by arguments is deprecated. Please use the pattern option instead.',
|
419 | implicitFileDeprecated: 'Using the "file:" protocol implicitly is deprecated. Please either prepend the protocol or prepend the path $0 with "./".',
|
420 | unsupportedNodeVersion: 'You are using Node $0 which is not supported and may encounter bugs or unexpected behavior. Pika supports the following semver range: $1',
|
421 | verboseUpgradeBecauseRequested: 'Considering upgrade of $0 to $1 because it was directly requested.',
|
422 | verboseUpgradeBecauseOutdated: 'Considering upgrade of $0 to $1 because a newer version exists in the registry.',
|
423 | verboseUpgradeNotUnlocking: 'Not unlocking $0 in the lockfile because it is a new or direct dependency.',
|
424 | verboseUpgradeUnlocking: 'Unlocking $0 in the lockfile.',
|
425 | folderMissing: "Directory $0 doesn't exist",
|
426 | mutexPortBusy: 'Cannot use the network mutex on port $0. It is probably used by another app.',
|
427 | auditRunning: 'Auditing packages',
|
428 | auditSummary: '$0 vulnerabilities found - Packages audited: $1',
|
429 | auditSummarySeverity: 'Severity:',
|
430 | auditCritical: '$0 Critical',
|
431 | auditHigh: '$0 High',
|
432 | auditModerate: '$0 Moderate',
|
433 | auditLow: '$0 Low',
|
434 | auditInfo: '$0 Info',
|
435 | auditResolveCommand: '# Run $0 to resolve $1 $2',
|
436 | auditSemverMajorChange: 'SEMVER WARNING: Recommended action is a potentially breaking change',
|
437 | auditManualReview: 'Manual Review\nSome vulnerabilities require your attention to resolve\n\nVisit https://go.npm.me/audit-guide for additional guidance',
|
438 | auditRunAuditForDetails: 'Security audit found potential problems. Run "pika audit" for additional details.',
|
439 | auditOffline: 'Skipping audit. Security audit cannot be performed in offline mode.'
|
440 | };
|
441 |
|
442 |
|
443 |
|
444 | var languages = Object.freeze({
|
445 | en: messages
|
446 | });
|
447 |
|
448 | function stringifyLangArgs(args) {
|
449 | return args.map(function (val) {
|
450 | if (val != null && val.inspect) {
|
451 | return val.inspect();
|
452 | } else {
|
453 | try {
|
454 | const str = JSON.stringify(val) || val + '';
|
455 |
|
456 |
|
457 |
|
458 | return str.replace(/((?:^|[^\\])(?:\\{2})*)\\u001[bB]/g, '$1\u001b').replace(/[\\]r[\\]n|([\\])?[\\]n/g, (match, precededBacklash) => {
|
459 |
|
460 |
|
461 | return precededBacklash ? match : os.EOL;
|
462 | });
|
463 | } catch (e) {
|
464 | return util.inspect(val);
|
465 | }
|
466 | }
|
467 | });
|
468 | }
|
469 | class BaseReporter {
|
470 | constructor(opts = {}) {
|
471 | const lang = 'en';
|
472 | this.language = lang;
|
473 | this.stdout = opts.stdout || process.stdout;
|
474 | this.stderr = opts.stderr || process.stderr;
|
475 | this.stdin = opts.stdin || this._getStandardInput();
|
476 | this.emoji = !!opts.emoji;
|
477 | this.nonInteractive = !!opts.nonInteractive;
|
478 | this.noProgress = !!opts.noProgress || isCI;
|
479 | this.isVerbose = !!opts.verbose;
|
480 |
|
481 | this.isTTY = this.stdout.isTTY;
|
482 | this.peakMemory = 0;
|
483 | this.startTime = Date.now();
|
484 | this.format = defaultFormatter;
|
485 | }
|
486 |
|
487 | lang(key, ...args) {
|
488 | const msg = languages[this.language][key] || messages[key];
|
489 |
|
490 | if (!msg) {
|
491 | throw new ReferenceError(`No message defined for language key ${key}`);
|
492 | }
|
493 |
|
494 |
|
495 | const stringifiedArgs = stringifyLangArgs(args);
|
496 |
|
497 | return msg.replace(/\$(\d+)/g, (str, i) => {
|
498 | return stringifiedArgs[i];
|
499 | });
|
500 | }
|
501 | |
502 |
|
503 |
|
504 |
|
505 |
|
506 |
|
507 |
|
508 | rawText(str) {
|
509 | return {
|
510 | inspect() {
|
511 | return str;
|
512 | }
|
513 |
|
514 | };
|
515 | }
|
516 |
|
517 | verbose(msg) {
|
518 | if (this.isVerbose) {
|
519 | this._verbose(msg);
|
520 | }
|
521 | }
|
522 |
|
523 | verboseInspect(val) {
|
524 | if (this.isVerbose) {
|
525 | this._verboseInspect(val);
|
526 | }
|
527 | }
|
528 |
|
529 | _verbose(msg) {}
|
530 |
|
531 | _verboseInspect(val) {}
|
532 |
|
533 | _getStandardInput() {
|
534 | let standardInput;
|
535 |
|
536 | try {
|
537 | standardInput = process.stdin;
|
538 | } catch (e) {
|
539 | console.warn(e.message);
|
540 | delete process.stdin;
|
541 |
|
542 | process.stdin = new events.EventEmitter();
|
543 | standardInput = process.stdin;
|
544 | }
|
545 |
|
546 | return standardInput;
|
547 | }
|
548 |
|
549 | initPeakMemoryCounter() {
|
550 | this.checkPeakMemory();
|
551 | this.peakMemoryInterval = setInterval(() => {
|
552 | this.checkPeakMemory();
|
553 | }, 1000);
|
554 |
|
555 | this.peakMemoryInterval.unref();
|
556 | }
|
557 |
|
558 | checkPeakMemory() {
|
559 | const {
|
560 | heapTotal
|
561 | } = process.memoryUsage();
|
562 |
|
563 | if (heapTotal > this.peakMemory) {
|
564 | this.peakMemory = heapTotal;
|
565 | }
|
566 | }
|
567 |
|
568 | close() {
|
569 | if (this.peakMemoryInterval) {
|
570 | clearInterval(this.peakMemoryInterval);
|
571 | this.peakMemoryInterval = null;
|
572 | }
|
573 | }
|
574 |
|
575 | getTotalTime() {
|
576 | return Date.now() - this.startTime;
|
577 | }
|
578 |
|
579 |
|
580 | list(key, items, hints) {}
|
581 |
|
582 |
|
583 | tree(key, obj, {
|
584 | force = false
|
585 | } = {}) {}
|
586 |
|
587 |
|
588 | step(current, total, message, emoji) {}
|
589 |
|
590 |
|
591 |
|
592 | error(message) {}
|
593 |
|
594 |
|
595 | info(message) {}
|
596 |
|
597 |
|
598 | warn(message) {}
|
599 |
|
600 |
|
601 | success(message) {}
|
602 |
|
603 |
|
604 |
|
605 | log(message, {
|
606 | force = false
|
607 | } = {}) {}
|
608 |
|
609 |
|
610 | command(command) {}
|
611 |
|
612 |
|
613 | inspect(value) {}
|
614 |
|
615 |
|
616 | header(command, pkg) {}
|
617 |
|
618 |
|
619 | footer(showPeakMemory) {}
|
620 |
|
621 |
|
622 | table(head, body) {}
|
623 |
|
624 |
|
625 | activity() {
|
626 | return {
|
627 | tick(name) {},
|
628 |
|
629 | end() {}
|
630 |
|
631 | };
|
632 | }
|
633 |
|
634 |
|
635 | activitySet(total, workers) {
|
636 | return {
|
637 | spinners: Array(workers).fill({
|
638 | clear() {},
|
639 |
|
640 | setPrefix() {},
|
641 |
|
642 | tick() {},
|
643 |
|
644 | end() {}
|
645 |
|
646 | }),
|
647 |
|
648 | end() {}
|
649 |
|
650 | };
|
651 | }
|
652 |
|
653 |
|
654 | question(question, options = {}) {
|
655 | return Promise.reject(new Error('Not implemented'));
|
656 | }
|
657 |
|
658 |
|
659 | async questionAffirm(question) {
|
660 | const condition = true;
|
661 |
|
662 | if (this.nonInteractive) {
|
663 | return true;
|
664 | }
|
665 |
|
666 | while (condition) {
|
667 | let answer = await this.question(question);
|
668 | answer = answer.toLowerCase();
|
669 |
|
670 | if (answer === 'y' || answer === 'yes') {
|
671 | return true;
|
672 | }
|
673 |
|
674 | if (answer === 'n' || answer === 'no') {
|
675 | return false;
|
676 | }
|
677 |
|
678 | this.error('Invalid answer for question');
|
679 | }
|
680 |
|
681 | return false;
|
682 | }
|
683 |
|
684 |
|
685 | select(header, question, options) {
|
686 | return Promise.reject(new Error('Not implemented'));
|
687 | }
|
688 |
|
689 |
|
690 | progress(total) {
|
691 | return function () {};
|
692 | }
|
693 |
|
694 |
|
695 | disableProgress() {
|
696 | this.noProgress = true;
|
697 | }
|
698 |
|
699 |
|
700 | prompt(message, choices, options = {}) {
|
701 | return Promise.reject(new Error('Not implemented'));
|
702 | }
|
703 |
|
704 | }
|
705 |
|
706 |
|
707 | function sortTrees(trees) {
|
708 | return trees.sort(function (tree1, tree2) {
|
709 | return tree1.name.localeCompare(tree2.name);
|
710 | });
|
711 | }
|
712 | function recurseTree(tree, prefix, recurseFunc) {
|
713 | const treeLen = tree.length;
|
714 | const treeEnd = treeLen - 1;
|
715 |
|
716 | for (let i = 0; i < treeLen; i++) {
|
717 | const atEnd = i === treeEnd;
|
718 | recurseFunc(tree[i], prefix + getLastIndentChar(atEnd), prefix + getNextIndentChar(atEnd));
|
719 | }
|
720 | }
|
721 | function getFormattedOutput(fmt) {
|
722 | const item = formatColor(fmt.color, fmt.name, fmt.formatter);
|
723 | const suffix = getSuffix(fmt.hint, fmt.formatter);
|
724 | return `${fmt.prefix}─ ${item}${suffix}\n`;
|
725 | }
|
726 |
|
727 | function getNextIndentChar(end) {
|
728 | return end ? ' ' : '│ ';
|
729 | }
|
730 |
|
731 | function getLastIndentChar(end) {
|
732 | return end ? '└' : '├';
|
733 | }
|
734 |
|
735 | function getSuffix(hint, formatter) {
|
736 | return hint ? ` (${formatter.grey(hint)})` : '';
|
737 | }
|
738 |
|
739 | function formatColor(color, strToFormat, formatter) {
|
740 | return color ? formatter[color](strToFormat) : strToFormat;
|
741 | }
|
742 |
|
743 | const CLEAR_WHOLE_LINE = 0;
|
744 | const CLEAR_RIGHT_OF_CURSOR = 1;
|
745 | function clearLine(stdout) {
|
746 | if (!chalk.supportsColor) {
|
747 | if (stdout instanceof tty.WriteStream) {
|
748 | if (stdout.columns > 0) {
|
749 | stdout.write(`\r${' '.repeat(stdout.columns - 1)}`);
|
750 | }
|
751 |
|
752 | stdout.write(`\r`);
|
753 | }
|
754 |
|
755 | return;
|
756 | }
|
757 |
|
758 | readline.clearLine(stdout, CLEAR_WHOLE_LINE);
|
759 | readline.cursorTo(stdout, 0);
|
760 | }
|
761 | function toStartOfLine(stdout) {
|
762 | if (!chalk.supportsColor) {
|
763 | stdout.write('\r');
|
764 | return;
|
765 | }
|
766 |
|
767 | readline.cursorTo(stdout, 0);
|
768 | }
|
769 | function writeOnNthLine(stdout, n, msg) {
|
770 | if (!chalk.supportsColor) {
|
771 | return;
|
772 | }
|
773 |
|
774 | if (n == 0) {
|
775 | readline.cursorTo(stdout, 0);
|
776 | stdout.write(msg);
|
777 | readline.clearLine(stdout, CLEAR_RIGHT_OF_CURSOR);
|
778 | return;
|
779 | }
|
780 |
|
781 | readline.cursorTo(stdout, 0);
|
782 | readline.moveCursor(stdout, 0, -n);
|
783 | stdout.write(msg);
|
784 | readline.clearLine(stdout, CLEAR_RIGHT_OF_CURSOR);
|
785 | readline.cursorTo(stdout, 0);
|
786 | readline.moveCursor(stdout, 0, n);
|
787 | }
|
788 | function clearNthLine(stdout, n) {
|
789 | if (!chalk.supportsColor) {
|
790 | return;
|
791 | }
|
792 |
|
793 | if (n == 0) {
|
794 | clearLine(stdout);
|
795 | return;
|
796 | }
|
797 |
|
798 | readline.cursorTo(stdout, 0);
|
799 | readline.moveCursor(stdout, 0, -n);
|
800 | readline.clearLine(stdout, CLEAR_WHOLE_LINE);
|
801 | readline.moveCursor(stdout, 0, n);
|
802 | }
|
803 |
|
804 | class ProgressBar {
|
805 | constructor(total, stdout = process.stderr, callback) {
|
806 | this.stdout = stdout;
|
807 | this.total = total;
|
808 | this.chars = ProgressBar.bars[0];
|
809 | this.delay = 60;
|
810 | this.curr = 0;
|
811 | this._callback = callback;
|
812 | clearLine(stdout);
|
813 | }
|
814 |
|
815 | tick() {
|
816 | if (this.curr >= this.total) {
|
817 | return;
|
818 | }
|
819 |
|
820 | this.curr++;
|
821 |
|
822 | if (!this.id) {
|
823 | this.id = setTimeout(() => this.render(), this.delay);
|
824 | }
|
825 | }
|
826 |
|
827 | cancelTick() {
|
828 | if (this.id) {
|
829 | clearTimeout(this.id);
|
830 | this.id = null;
|
831 | }
|
832 | }
|
833 |
|
834 | stop() {
|
835 |
|
836 | this.curr = this.total;
|
837 | this.cancelTick();
|
838 | clearLine(this.stdout);
|
839 |
|
840 | if (this._callback) {
|
841 | this._callback(this);
|
842 | }
|
843 | }
|
844 |
|
845 | render() {
|
846 |
|
847 | this.cancelTick();
|
848 | let ratio = this.curr / this.total;
|
849 | ratio = Math.min(Math.max(ratio, 0), 1);
|
850 |
|
851 | let bar = ` ${this.curr}/${this.total}`;
|
852 |
|
853 |
|
854 |
|
855 | const availableSpace = Math.max(0, this.stdout.columns - bar.length - 3);
|
856 | const width = Math.min(this.total, availableSpace);
|
857 | const completeLength = Math.round(width * ratio);
|
858 | const complete = this.chars[0].repeat(completeLength);
|
859 | const incomplete = this.chars[1].repeat(width - completeLength);
|
860 | bar = `[${complete}${incomplete}]${bar}`;
|
861 | toStartOfLine(this.stdout);
|
862 | this.stdout.write(bar);
|
863 | }
|
864 |
|
865 | }
|
866 | ProgressBar.bars = [['#', '-']];
|
867 |
|
868 | class Spinner {
|
869 | constructor(stdout = process.stderr, lineNumber = 0) {
|
870 | this.current = 0;
|
871 | this.prefix = '';
|
872 | this.lineNumber = lineNumber;
|
873 | this.stdout = stdout;
|
874 | this.delay = 60;
|
875 | this.chars = Spinner.spinners[28].split('');
|
876 | this.text = '';
|
877 | this.id = null;
|
878 | }
|
879 |
|
880 | setPrefix(prefix) {
|
881 | this.prefix = prefix;
|
882 | }
|
883 |
|
884 | setText(text) {
|
885 | this.text = text;
|
886 | }
|
887 |
|
888 | start() {
|
889 | this.current = 0;
|
890 | this.render();
|
891 | }
|
892 |
|
893 | render() {
|
894 | if (this.id) {
|
895 | clearTimeout(this.id);
|
896 | }
|
897 |
|
898 |
|
899 | let msg = `${this.prefix}${this.chars[this.current]} ${this.text}`;
|
900 |
|
901 | const columns = typeof this.stdout.columns === 'number' ? this.stdout.columns : 100;
|
902 | msg = msg.slice(0, columns);
|
903 | writeOnNthLine(this.stdout, this.lineNumber, msg);
|
904 | this.current = ++this.current % this.chars.length;
|
905 | this.id = setTimeout(() => this.render(), this.delay);
|
906 | }
|
907 |
|
908 | stop() {
|
909 | if (this.id) {
|
910 | clearTimeout(this.id);
|
911 | this.id = null;
|
912 | }
|
913 |
|
914 | clearNthLine(this.stdout, this.lineNumber);
|
915 | }
|
916 |
|
917 | }
|
918 | Spinner.spinners = ['|/-\\', '⠂-–—–-', '◐◓◑◒', '◴◷◶◵', '◰◳◲◱', '▖▘▝▗', '■□▪▫', '▌▀▐▄', '▉▊▋▌▍▎▏▎▍▌▋▊▉', '▁▃▄▅▆▇█▇▆▅▄▃', '←↖↑↗→↘↓↙', '┤┘┴└├┌┬┐', '◢◣◤◥', '.oO°Oo.', '.oO@*', '🌍🌎🌏', '◡◡ ⊙⊙ ◠◠', '☱☲☴', '⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏', '⠋⠙⠚⠞⠖⠦⠴⠲⠳⠓', '⠄⠆⠇⠋⠙⠸⠰⠠⠰⠸⠙⠋⠇⠆', '⠋⠙⠚⠒⠂⠂⠒⠲⠴⠦⠖⠒⠐⠐⠒⠓⠋', '⠁⠉⠙⠚⠒⠂⠂⠒⠲⠴⠤⠄⠄⠤⠴⠲⠒⠂⠂⠒⠚⠙⠉⠁', '⠈⠉⠋⠓⠒⠐⠐⠒⠖⠦⠤⠠⠠⠤⠦⠖⠒⠐⠐⠒⠓⠋⠉⠈', '⠁⠁⠉⠙⠚⠒⠂⠂⠒⠲⠴⠤⠄⠄⠤⠠⠠⠤⠦⠖⠒⠐⠐⠒⠓⠋⠉⠈⠈', '⢄⢂⢁⡁⡈⡐⡠', '⢹⢺⢼⣸⣇⡧⡗⡏', '⣾⣽⣻⢿⡿⣟⣯⣷', '⠁⠂⠄⡀⢀⠠⠐⠈'];
|
919 |
|
920 | const auditSeverityColors = {
|
921 | info: chalk.bold,
|
922 | low: chalk.bold,
|
923 | moderate: chalk.yellow,
|
924 | high: chalk.red,
|
925 | critical: chalk.bgRed
|
926 | };
|
927 |
|
928 | if (process.platform === 'win32' && !(process.env.TERM && /^xterm/i.test(process.env.TERM))) {
|
929 |
|
930 | chalk.bold._styles[0].close += '\u001b[m';
|
931 | }
|
932 |
|
933 | class ConsoleReporter extends BaseReporter {
|
934 | constructor(opts) {
|
935 | super(opts);
|
936 | this._lastCategorySize = 0;
|
937 | this._spinners = new Set();
|
938 | this.format = chalk;
|
939 | this.format.stripColor = stripAnsi;
|
940 | this.isSilent = !!opts.isSilent;
|
941 | }
|
942 |
|
943 | _prependEmoji(msg, emoji) {
|
944 | if (this.emoji && emoji && this.isTTY) {
|
945 | msg = `${emoji} ${msg}`;
|
946 | }
|
947 |
|
948 | return msg;
|
949 | }
|
950 |
|
951 | _logCategory(category, color, msg) {
|
952 | this._lastCategorySize = category.length;
|
953 |
|
954 | this._log(`${this.format[color](category)} ${msg}`);
|
955 | }
|
956 |
|
957 | _verbose(msg) {
|
958 | this._logCategory('verbose', 'grey', `${process.uptime()} ${msg}`);
|
959 | }
|
960 |
|
961 | _verboseInspect(obj) {
|
962 | this.inspect(obj);
|
963 | }
|
964 |
|
965 | close() {
|
966 | for (const spinner of this._spinners) {
|
967 | spinner.stop();
|
968 | }
|
969 |
|
970 | this._spinners.clear();
|
971 |
|
972 | this.stopProgress();
|
973 | super.close();
|
974 | }
|
975 |
|
976 | table(head, body) {
|
977 |
|
978 | head = head.map(field => this.format.underline(field));
|
979 |
|
980 | const rows = [head].concat(body);
|
981 |
|
982 | const cols = [];
|
983 |
|
984 | for (let i = 0; i < head.length; i++) {
|
985 | const widths = rows.map(row => this.format.stripColor(row[i]).length);
|
986 | cols[i] = Math.max(...widths);
|
987 | }
|
988 |
|
989 |
|
990 | const builtRows = rows.map(row => {
|
991 | for (let i = 0; i < row.length; i++) {
|
992 | const field = row[i];
|
993 | const padding = cols[i] - this.format.stripColor(field).length;
|
994 | row[i] = field + ' '.repeat(padding);
|
995 | }
|
996 |
|
997 | return row.join(' ');
|
998 | });
|
999 | this.log(builtRows.join('\n'));
|
1000 | }
|
1001 |
|
1002 | step(current, total, msg, emoji) {
|
1003 | msg = this._prependEmoji(msg, emoji);
|
1004 |
|
1005 | if (msg.endsWith('?')) {
|
1006 | msg = `${removeSuffix(msg, '?')}...?`;
|
1007 | } else {
|
1008 | msg += '...';
|
1009 | }
|
1010 |
|
1011 | this.log(`${this.format.dim(`[${current}/${total}]`)} ${msg}`);
|
1012 | }
|
1013 |
|
1014 | inspect(value) {
|
1015 | if (typeof value !== 'number' && typeof value !== 'string') {
|
1016 | value = util.inspect(value, {
|
1017 | breakLength: 0,
|
1018 | colors: this.isTTY,
|
1019 | depth: null,
|
1020 | maxArrayLength: null
|
1021 | });
|
1022 | }
|
1023 |
|
1024 | this.log(String(value), {
|
1025 | force: true
|
1026 | });
|
1027 | }
|
1028 |
|
1029 | list(key, items, hints) {
|
1030 | const gutterWidth = (this._lastCategorySize || 2) - 1;
|
1031 |
|
1032 | if (hints) {
|
1033 | for (const item of items) {
|
1034 | this._log(`${' '.repeat(gutterWidth)}- ${this.format.bold(item)}`);
|
1035 |
|
1036 | this._log(` ${' '.repeat(gutterWidth)} ${hints[item]}`);
|
1037 | }
|
1038 | } else {
|
1039 | for (const item of items) {
|
1040 | this._log(`${' '.repeat(gutterWidth)}- ${item}`);
|
1041 | }
|
1042 | }
|
1043 | }
|
1044 |
|
1045 | header(command, pkg) {
|
1046 | this.log(this.format.bold(`${pkg.name} ${command} v${pkg.version}`));
|
1047 | }
|
1048 |
|
1049 | footer(showPeakMemory) {
|
1050 | this.stopProgress();
|
1051 | const totalTime = (this.getTotalTime() / 1000).toFixed(2);
|
1052 | let msg = `Done in ${totalTime}s.`;
|
1053 |
|
1054 | if (showPeakMemory) {
|
1055 | const peakMemory = (this.peakMemory / 1024 / 1024).toFixed(2);
|
1056 | msg += ` Peak memory usage ${peakMemory}MB.`;
|
1057 | }
|
1058 |
|
1059 | this.log(this._prependEmoji(msg, '✨'));
|
1060 | }
|
1061 |
|
1062 | log(msg, {
|
1063 | force = false
|
1064 | } = {}) {
|
1065 | this._lastCategorySize = 0;
|
1066 |
|
1067 | this._log(msg, {
|
1068 | force
|
1069 | });
|
1070 | }
|
1071 |
|
1072 | _log(msg, {
|
1073 | force = false
|
1074 | } = {}) {
|
1075 | if (this.isSilent && !force) {
|
1076 | return;
|
1077 | }
|
1078 |
|
1079 | clearLine(this.stdout);
|
1080 | this.stdout.write(`${msg}\n`);
|
1081 | }
|
1082 |
|
1083 | success(msg) {
|
1084 | this._logCategory('success', 'green', msg);
|
1085 | }
|
1086 |
|
1087 | error(msg) {
|
1088 | clearLine(this.stderr);
|
1089 | this.stderr.write(`${this.format.red('error')} ${msg}\n`);
|
1090 | }
|
1091 |
|
1092 | info(msg) {
|
1093 | this._logCategory('info', 'blue', msg);
|
1094 | }
|
1095 |
|
1096 | command(command) {
|
1097 | this.log(this.format.dim(`$ ${command}`));
|
1098 | }
|
1099 |
|
1100 | warn(msg) {
|
1101 | clearLine(this.stderr);
|
1102 | this.stderr.write(`${this.format.yellow('warning')} ${msg}\n`);
|
1103 | }
|
1104 |
|
1105 | question(question, options = {}) {
|
1106 | if (!process.stdout.isTTY) {
|
1107 | return Promise.reject(new Error("Can't answer a question unless a user TTY"));
|
1108 | }
|
1109 |
|
1110 | return new Promise((resolve, reject) => {
|
1111 | read({
|
1112 | prompt: `${this.format.dim('question')} ${question}: `,
|
1113 | silent: !!options.password,
|
1114 | output: this.stdout,
|
1115 | input: this.stdin
|
1116 | }, (err, answer) => {
|
1117 | if (err) {
|
1118 | if (err.message === 'canceled') {
|
1119 | process.exitCode = 1;
|
1120 | }
|
1121 |
|
1122 | reject(err);
|
1123 | } else {
|
1124 | if (!answer && options.required) {
|
1125 | this.error(this.lang('answerRequired'));
|
1126 | resolve(this.question(question, options));
|
1127 | } else {
|
1128 | resolve(answer);
|
1129 | }
|
1130 | }
|
1131 | });
|
1132 | });
|
1133 | }
|
1134 |
|
1135 |
|
1136 | tree(key, trees, {
|
1137 | force = false
|
1138 | } = {}) {
|
1139 | this.stopProgress();
|
1140 |
|
1141 | if (this.isSilent && !force) {
|
1142 | return;
|
1143 | }
|
1144 |
|
1145 | const output = ({
|
1146 | name,
|
1147 | children,
|
1148 | hint,
|
1149 | color
|
1150 | }, titlePrefix, childrenPrefix) => {
|
1151 | const formatter = this.format;
|
1152 | const out = getFormattedOutput({
|
1153 | prefix: titlePrefix,
|
1154 | hint,
|
1155 | color,
|
1156 | name,
|
1157 | formatter
|
1158 | });
|
1159 | this.stdout.write(out);
|
1160 |
|
1161 | if (children && children.length) {
|
1162 | recurseTree(sortTrees(children), childrenPrefix, output);
|
1163 | }
|
1164 | };
|
1165 |
|
1166 | recurseTree(sortTrees(trees), '', output);
|
1167 | }
|
1168 |
|
1169 | activitySet(total, workers) {
|
1170 | if (!this.isTTY || this.noProgress) {
|
1171 | return super.activitySet(total, workers);
|
1172 | }
|
1173 |
|
1174 | const spinners = [];
|
1175 | const reporterSpinners = this._spinners;
|
1176 |
|
1177 | for (let i = 1; i < workers; i++) {
|
1178 | this.log('');
|
1179 | }
|
1180 |
|
1181 | for (let i = 0; i < workers; i++) {
|
1182 | const spinner = new Spinner(this.stderr, i);
|
1183 | reporterSpinners.add(spinner);
|
1184 | spinner.start();
|
1185 | let prefix = null;
|
1186 | let current = 0;
|
1187 |
|
1188 | const updatePrefix = () => {
|
1189 | spinner.setPrefix(`${this.format.dim(`[${current === 0 ? '-' : current}/${total}]`)} `);
|
1190 | };
|
1191 |
|
1192 | const clear = () => {
|
1193 | prefix = null;
|
1194 | current = 0;
|
1195 | updatePrefix();
|
1196 | spinner.setText('waiting...');
|
1197 | };
|
1198 |
|
1199 | clear();
|
1200 | spinners.unshift({
|
1201 | clear,
|
1202 |
|
1203 | setPrefix(_current, _prefix) {
|
1204 | current = _current;
|
1205 | prefix = _prefix;
|
1206 | spinner.setText(prefix);
|
1207 | updatePrefix();
|
1208 | },
|
1209 |
|
1210 | tick(msg) {
|
1211 | if (prefix) {
|
1212 | msg = `${prefix}: ${msg}`;
|
1213 | }
|
1214 |
|
1215 | spinner.setText(msg);
|
1216 | },
|
1217 |
|
1218 | end() {
|
1219 | spinner.stop();
|
1220 | reporterSpinners.delete(spinner);
|
1221 | }
|
1222 |
|
1223 | });
|
1224 | }
|
1225 |
|
1226 | return {
|
1227 | spinners,
|
1228 | end: () => {
|
1229 | for (const spinner of spinners) {
|
1230 | spinner.end();
|
1231 | }
|
1232 |
|
1233 | readline.moveCursor(this.stdout, 0, -workers + 1);
|
1234 | }
|
1235 | };
|
1236 | }
|
1237 |
|
1238 | activity() {
|
1239 | if (!this.isTTY) {
|
1240 | return {
|
1241 | tick() {},
|
1242 |
|
1243 | end() {}
|
1244 |
|
1245 | };
|
1246 | }
|
1247 |
|
1248 | const reporterSpinners = this._spinners;
|
1249 | const spinner = new Spinner(this.stderr);
|
1250 | spinner.start();
|
1251 | reporterSpinners.add(spinner);
|
1252 | return {
|
1253 | tick(name) {
|
1254 | spinner.setText(name);
|
1255 | },
|
1256 |
|
1257 | end() {
|
1258 | spinner.stop();
|
1259 | reporterSpinners.delete(spinner);
|
1260 | }
|
1261 |
|
1262 | };
|
1263 | }
|
1264 |
|
1265 | select(header, question, options) {
|
1266 | if (!this.isTTY) {
|
1267 | return Promise.reject(new Error("Can't answer a question unless a user TTY"));
|
1268 | }
|
1269 |
|
1270 | const rl = readline.createInterface({
|
1271 | input: this.stdin,
|
1272 | output: this.stdout,
|
1273 | terminal: true
|
1274 | });
|
1275 | const questions = options.map(opt => opt.name);
|
1276 | const answers = options.map(opt => opt.value);
|
1277 |
|
1278 | function toIndex(input) {
|
1279 | const index = answers.indexOf(input);
|
1280 |
|
1281 | if (index >= 0) {
|
1282 | return index;
|
1283 | } else {
|
1284 | return +input;
|
1285 | }
|
1286 | }
|
1287 |
|
1288 | return new Promise(resolve => {
|
1289 | this.info(header);
|
1290 |
|
1291 | for (let i = 0; i < questions.length; i++) {
|
1292 | this.log(` ${this.format.dim(`${i + 1})`)} ${questions[i]}`);
|
1293 | }
|
1294 |
|
1295 | const ask = () => {
|
1296 | rl.question(`${question}: `, input => {
|
1297 | let index = toIndex(input);
|
1298 |
|
1299 | if (isNaN(index)) {
|
1300 | this.log('Not a number');
|
1301 | ask();
|
1302 | return;
|
1303 | }
|
1304 |
|
1305 | if (index <= 0 || index > options.length) {
|
1306 | this.log('Outside answer range');
|
1307 | ask();
|
1308 | return;
|
1309 | }
|
1310 |
|
1311 |
|
1312 | index--;
|
1313 | rl.close();
|
1314 | resolve(answers[index]);
|
1315 | });
|
1316 | };
|
1317 |
|
1318 | ask();
|
1319 | });
|
1320 | }
|
1321 |
|
1322 | progress(count) {
|
1323 | if (this.noProgress || count <= 0) {
|
1324 | return function () {
|
1325 | };
|
1326 | }
|
1327 |
|
1328 | if (!this.isTTY) {
|
1329 | return function () {
|
1330 | };
|
1331 | }
|
1332 |
|
1333 |
|
1334 | this.stopProgress();
|
1335 | const bar = this._progressBar = new ProgressBar(count, this.stderr, progress => {
|
1336 | if (progress === this._progressBar) {
|
1337 | this._progressBar = null;
|
1338 | }
|
1339 | });
|
1340 | bar.render();
|
1341 | return function () {
|
1342 | bar.tick();
|
1343 | };
|
1344 | }
|
1345 |
|
1346 | stopProgress() {
|
1347 | if (this._progressBar) {
|
1348 | this._progressBar.stop();
|
1349 | }
|
1350 | }
|
1351 |
|
1352 | async prompt(message, choices, options = {}) {
|
1353 | if (!process.stdout.isTTY) {
|
1354 | return Promise.reject(new Error("Can't answer a question unless a user TTY"));
|
1355 | }
|
1356 |
|
1357 | let pageSize;
|
1358 |
|
1359 | if (process.stdout instanceof tty.WriteStream) {
|
1360 | pageSize = process.stdout.rows - 2;
|
1361 | }
|
1362 |
|
1363 | const rl = readline.createInterface({
|
1364 | input: this.stdin,
|
1365 | output: this.stdout,
|
1366 | terminal: true
|
1367 | });
|
1368 |
|
1369 | const prompt = inquirer.createPromptModule({
|
1370 | input: this.stdin,
|
1371 | output: this.stdout
|
1372 | });
|
1373 | const {
|
1374 | name = 'prompt',
|
1375 | type = 'input',
|
1376 | validate
|
1377 | } = options;
|
1378 | const answers = await prompt([{
|
1379 | name,
|
1380 | type,
|
1381 | message,
|
1382 | choices,
|
1383 | pageSize,
|
1384 | validate,
|
1385 | default: options.default
|
1386 | }]);
|
1387 | rl.close();
|
1388 | return answers[name];
|
1389 | }
|
1390 |
|
1391 | }
|
1392 |
|
1393 | function _defineProperty(obj, key, value) {
|
1394 | if (key in obj) {
|
1395 | Object.defineProperty(obj, key, {
|
1396 | value: value,
|
1397 | enumerable: true,
|
1398 | configurable: true,
|
1399 | writable: true
|
1400 | });
|
1401 | } else {
|
1402 | obj[key] = value;
|
1403 | }
|
1404 |
|
1405 | return obj;
|
1406 | }
|
1407 |
|
1408 | function _objectSpread(target) {
|
1409 | for (var i = 1; i < arguments.length; i++) {
|
1410 | var source = arguments[i] != null ? arguments[i] : {};
|
1411 | var ownKeys = Object.keys(source);
|
1412 |
|
1413 | if (typeof Object.getOwnPropertySymbols === 'function') {
|
1414 | ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {
|
1415 | return Object.getOwnPropertyDescriptor(source, sym).enumerable;
|
1416 | }));
|
1417 | }
|
1418 |
|
1419 | ownKeys.forEach(function (key) {
|
1420 | _defineProperty(target, key, source[key]);
|
1421 | });
|
1422 | }
|
1423 |
|
1424 | return target;
|
1425 | }
|
1426 |
|
1427 | class JSONReporter extends BaseReporter {
|
1428 | constructor(opts) {
|
1429 | super(opts);
|
1430 | this._activityId = 0;
|
1431 | this._progressId = 0;
|
1432 | }
|
1433 |
|
1434 | _dump(type, data, error) {
|
1435 | let stdout = this.stdout;
|
1436 |
|
1437 | if (error) {
|
1438 | stdout = this.stderr;
|
1439 | }
|
1440 |
|
1441 | stdout.write(`${JSON.stringify({
|
1442 | type,
|
1443 | data
|
1444 | })}\n`);
|
1445 | }
|
1446 |
|
1447 | _verbose(msg) {
|
1448 | this._dump('verbose', msg);
|
1449 | }
|
1450 |
|
1451 | list(type, items, hints) {
|
1452 | this._dump('list', {
|
1453 | type,
|
1454 | items,
|
1455 | hints
|
1456 | });
|
1457 | }
|
1458 |
|
1459 | tree(type, trees) {
|
1460 | this._dump('tree', {
|
1461 | type,
|
1462 | trees
|
1463 | });
|
1464 | }
|
1465 |
|
1466 | step(current, total, message) {
|
1467 | this._dump('step', {
|
1468 | message,
|
1469 | current,
|
1470 | total
|
1471 | });
|
1472 | }
|
1473 |
|
1474 | inspect(value) {
|
1475 | this._dump('inspect', value);
|
1476 | }
|
1477 |
|
1478 | footer(showPeakMemory) {
|
1479 | this._dump('finished', this.getTotalTime());
|
1480 | }
|
1481 |
|
1482 | log(msg) {
|
1483 | this._dump('log', msg);
|
1484 | }
|
1485 |
|
1486 | command(msg) {
|
1487 | this._dump('command', msg);
|
1488 | }
|
1489 |
|
1490 | table(head, body) {
|
1491 | this._dump('table', {
|
1492 | head,
|
1493 | body
|
1494 | });
|
1495 | }
|
1496 |
|
1497 | success(msg) {
|
1498 | this._dump('success', msg);
|
1499 | }
|
1500 |
|
1501 | error(msg) {
|
1502 | this._dump('error', msg, true);
|
1503 | }
|
1504 |
|
1505 | warn(msg) {
|
1506 | this._dump('warning', msg, true);
|
1507 | }
|
1508 |
|
1509 | info(msg) {
|
1510 | this._dump('info', msg);
|
1511 | }
|
1512 |
|
1513 | activitySet(total, workers) {
|
1514 | if (!this.isTTY || this.noProgress) {
|
1515 | return super.activitySet(total, workers);
|
1516 | }
|
1517 |
|
1518 | const id = this._activityId++;
|
1519 |
|
1520 | this._dump('activitySetStart', {
|
1521 | id,
|
1522 | total,
|
1523 | workers
|
1524 | });
|
1525 |
|
1526 | const spinners = [];
|
1527 |
|
1528 | for (let i = 0; i < workers; i++) {
|
1529 | let current = 0;
|
1530 | let header = '';
|
1531 | spinners.push({
|
1532 | clear() {},
|
1533 |
|
1534 | setPrefix(_current, _header) {
|
1535 | current = _current;
|
1536 | header = _header;
|
1537 | },
|
1538 |
|
1539 | tick: msg => {
|
1540 | this._dump('activitySetTick', {
|
1541 | id,
|
1542 | header,
|
1543 | current,
|
1544 | worker: i,
|
1545 | message: msg
|
1546 | });
|
1547 | },
|
1548 |
|
1549 | end() {}
|
1550 |
|
1551 | });
|
1552 | }
|
1553 |
|
1554 | return {
|
1555 | spinners,
|
1556 | end: () => {
|
1557 | this._dump('activitySetEnd', {
|
1558 | id
|
1559 | });
|
1560 | }
|
1561 | };
|
1562 | }
|
1563 |
|
1564 | activity() {
|
1565 | return this._activity({});
|
1566 | }
|
1567 |
|
1568 | _activity(data) {
|
1569 | if (!this.isTTY || this.noProgress) {
|
1570 | return {
|
1571 | tick() {},
|
1572 |
|
1573 | end() {}
|
1574 |
|
1575 | };
|
1576 | }
|
1577 |
|
1578 | const id = this._activityId++;
|
1579 |
|
1580 | this._dump('activityStart', _objectSpread({
|
1581 | id
|
1582 | }, data));
|
1583 |
|
1584 | return {
|
1585 | tick: name => {
|
1586 | this._dump('activityTick', {
|
1587 | id,
|
1588 | name
|
1589 | });
|
1590 | },
|
1591 | end: () => {
|
1592 | this._dump('activityEnd', {
|
1593 | id
|
1594 | });
|
1595 | }
|
1596 | };
|
1597 | }
|
1598 |
|
1599 | progress(total) {
|
1600 | if (this.noProgress) {
|
1601 | return function () {
|
1602 | };
|
1603 | }
|
1604 |
|
1605 | const id = this._progressId++;
|
1606 | let current = 0;
|
1607 |
|
1608 | this._dump('progressStart', {
|
1609 | id,
|
1610 | total
|
1611 | });
|
1612 |
|
1613 | return () => {
|
1614 | current++;
|
1615 |
|
1616 | this._dump('progressTick', {
|
1617 | id,
|
1618 | current
|
1619 | });
|
1620 |
|
1621 | if (current === total) {
|
1622 | this._dump('progressFinish', {
|
1623 | id
|
1624 | });
|
1625 | }
|
1626 | };
|
1627 | }
|
1628 |
|
1629 | }
|
1630 |
|
1631 |
|
1632 |
|
1633 |
|
1634 |
|
1635 | const DEPENDENCY_TYPES = ['devDependencies', 'dependencies', 'legacyDependencies'];
|
1636 |
|
1637 | const RESOLUTIONS = 'resolutions';
|
1638 | const MANIFEST_FIELDS = [RESOLUTIONS, ...DEPENDENCY_TYPES];
|
1639 | const SUPPORTED_NODE_VERSIONS = '>=8.5.0';
|
1640 |
|
1641 |
|
1642 |
|
1643 |
|
1644 |
|
1645 |
|
1646 |
|
1647 |
|
1648 |
|
1649 |
|
1650 |
|
1651 |
|
1652 |
|
1653 |
|
1654 |
|
1655 | const CHILD_CONCURRENCY = 5;
|
1656 | const NODE_PACKAGE_JSON = 'package.json';
|
1657 |
|
1658 |
|
1659 |
|
1660 |
|
1661 |
|
1662 |
|
1663 |
|
1664 |
|
1665 |
|
1666 |
|
1667 |
|
1668 |
|
1669 | const DEFAULT_INDENT = ' ';
|
1670 |
|
1671 |
|
1672 | const ENV_PATH_KEY = getPathKey(process.platform, process.env);
|
1673 | function getPathKey(platform, env) {
|
1674 | let pathKey = 'PATH';
|
1675 |
|
1676 | if (platform === 'win32') {
|
1677 | pathKey = 'Path';
|
1678 |
|
1679 | for (const key in env) {
|
1680 | if (key.toLowerCase() === 'path') {
|
1681 | pathKey = key;
|
1682 | }
|
1683 | }
|
1684 | }
|
1685 |
|
1686 | return pathKey;
|
1687 | }
|
1688 |
|
1689 |
|
1690 |
|
1691 |
|
1692 |
|
1693 |
|
1694 |
|
1695 |
|
1696 |
|
1697 |
|
1698 |
|
1699 |
|
1700 |
|
1701 | function nullify(obj) {
|
1702 | if (Array.isArray(obj)) {
|
1703 | for (const item of obj) {
|
1704 | nullify(item);
|
1705 | }
|
1706 | } else if (obj !== null && typeof obj === 'object' || typeof obj === 'function') {
|
1707 | Object.setPrototypeOf(obj, null);
|
1708 |
|
1709 | if (typeof obj === 'object') {
|
1710 | for (const key in obj) {
|
1711 | nullify(obj[key]);
|
1712 | }
|
1713 | }
|
1714 | }
|
1715 |
|
1716 | return obj;
|
1717 | }
|
1718 |
|
1719 | const unlink = util.promisify(_rimraf);
|
1720 | const glob = util.promisify(_glob);
|
1721 | const mkdirp = util.promisify(_mkdirp);
|
1722 | const open = util.promisify(fs.open);
|
1723 | const writeFile = util.promisify(fs.writeFile);
|
1724 | const readlink = util.promisify(fs.readlink);
|
1725 | const realpath = util.promisify(fs.realpath);
|
1726 | const readdir = util.promisify(fs.readdir);
|
1727 | const rename = util.promisify(fs.rename);
|
1728 | const access = util.promisify(fs.access);
|
1729 | const stat = util.promisify(fs.stat);
|
1730 | const exists = util.promisify(fs.exists);
|
1731 | const lstat = util.promisify(fs.lstat);
|
1732 | const chmod = util.promisify(fs.chmod);
|
1733 | const link = util.promisify(fs.link);
|
1734 | const copyFile = util.promisify(fs.copyFile);
|
1735 | const readFileBuffer = util.promisify(fs.readFile);
|
1736 | const readFile = path => {
|
1737 | return util.promisify(fs.readFile)(path, {
|
1738 | encoding: 'utf-8'
|
1739 | });
|
1740 | };
|
1741 |
|
1742 |
|
1743 |
|
1744 |
|
1745 |
|
1746 |
|
1747 |
|
1748 |
|
1749 |
|
1750 |
|
1751 |
|
1752 |
|
1753 |
|
1754 |
|
1755 |
|
1756 |
|
1757 |
|
1758 |
|
1759 |
|
1760 |
|
1761 |
|
1762 |
|
1763 |
|
1764 |
|
1765 |
|
1766 |
|
1767 |
|
1768 |
|
1769 |
|
1770 |
|
1771 |
|
1772 |
|
1773 |
|
1774 |
|
1775 |
|
1776 |
|
1777 |
|
1778 |
|
1779 |
|
1780 |
|
1781 |
|
1782 |
|
1783 |
|
1784 |
|
1785 |
|
1786 |
|
1787 |
|
1788 |
|
1789 |
|
1790 |
|
1791 |
|
1792 |
|
1793 |
|
1794 |
|
1795 |
|
1796 |
|
1797 |
|
1798 |
|
1799 |
|
1800 |
|
1801 |
|
1802 |
|
1803 |
|
1804 |
|
1805 |
|
1806 |
|
1807 |
|
1808 |
|
1809 |
|
1810 |
|
1811 |
|
1812 |
|
1813 |
|
1814 |
|
1815 |
|
1816 |
|
1817 |
|
1818 |
|
1819 |
|
1820 |
|
1821 |
|
1822 |
|
1823 |
|
1824 |
|
1825 |
|
1826 |
|
1827 |
|
1828 |
|
1829 |
|
1830 |
|
1831 |
|
1832 |
|
1833 |
|
1834 |
|
1835 |
|
1836 |
|
1837 |
|
1838 |
|
1839 |
|
1840 |
|
1841 |
|
1842 |
|
1843 |
|
1844 |
|
1845 |
|
1846 |
|
1847 |
|
1848 |
|
1849 |
|
1850 |
|
1851 |
|
1852 |
|
1853 |
|
1854 |
|
1855 |
|
1856 |
|
1857 |
|
1858 |
|
1859 |
|
1860 |
|
1861 |
|
1862 |
|
1863 |
|
1864 |
|
1865 |
|
1866 |
|
1867 |
|
1868 |
|
1869 |
|
1870 |
|
1871 |
|
1872 |
|
1873 |
|
1874 |
|
1875 |
|
1876 |
|
1877 |
|
1878 |
|
1879 |
|
1880 |
|
1881 |
|
1882 |
|
1883 |
|
1884 |
|
1885 |
|
1886 |
|
1887 |
|
1888 |
|
1889 |
|
1890 |
|
1891 |
|
1892 |
|
1893 |
|
1894 |
|
1895 |
|
1896 |
|
1897 |
|
1898 |
|
1899 |
|
1900 |
|
1901 |
|
1902 |
|
1903 |
|
1904 |
|
1905 |
|
1906 |
|
1907 |
|
1908 |
|
1909 |
|
1910 |
|
1911 |
|
1912 |
|
1913 |
|
1914 |
|
1915 |
|
1916 |
|
1917 |
|
1918 |
|
1919 |
|
1920 |
|
1921 |
|
1922 |
|
1923 |
|
1924 |
|
1925 |
|
1926 |
|
1927 |
|
1928 |
|
1929 |
|
1930 |
|
1931 |
|
1932 |
|
1933 |
|
1934 |
|
1935 |
|
1936 |
|
1937 |
|
1938 |
|
1939 |
|
1940 |
|
1941 |
|
1942 |
|
1943 |
|
1944 |
|
1945 |
|
1946 |
|
1947 |
|
1948 |
|
1949 |
|
1950 |
|
1951 |
|
1952 |
|
1953 |
|
1954 |
|
1955 |
|
1956 |
|
1957 |
|
1958 |
|
1959 |
|
1960 |
|
1961 |
|
1962 |
|
1963 |
|
1964 |
|
1965 |
|
1966 |
|
1967 |
|
1968 |
|
1969 |
|
1970 |
|
1971 |
|
1972 |
|
1973 |
|
1974 |
|
1975 |
|
1976 |
|
1977 |
|
1978 |
|
1979 |
|
1980 |
|
1981 |
|
1982 |
|
1983 |
|
1984 |
|
1985 |
|
1986 |
|
1987 |
|
1988 |
|
1989 |
|
1990 |
|
1991 |
|
1992 |
|
1993 |
|
1994 |
|
1995 |
|
1996 |
|
1997 |
|
1998 |
|
1999 |
|
2000 |
|
2001 |
|
2002 |
|
2003 |
|
2004 |
|
2005 |
|
2006 |
|
2007 |
|
2008 |
|
2009 |
|
2010 |
|
2011 |
|
2012 |
|
2013 |
|
2014 |
|
2015 |
|
2016 |
|
2017 |
|
2018 |
|
2019 |
|
2020 |
|
2021 |
|
2022 |
|
2023 |
|
2024 |
|
2025 |
|
2026 |
|
2027 |
|
2028 |
|
2029 |
|
2030 |
|
2031 |
|
2032 |
|
2033 |
|
2034 |
|
2035 |
|
2036 |
|
2037 |
|
2038 |
|
2039 |
|
2040 |
|
2041 |
|
2042 |
|
2043 |
|
2044 |
|
2045 |
|
2046 |
|
2047 |
|
2048 |
|
2049 |
|
2050 |
|
2051 |
|
2052 |
|
2053 |
|
2054 |
|
2055 |
|
2056 |
|
2057 |
|
2058 |
|
2059 |
|
2060 |
|
2061 |
|
2062 |
|
2063 |
|
2064 |
|
2065 |
|
2066 |
|
2067 |
|
2068 |
|
2069 |
|
2070 |
|
2071 |
|
2072 |
|
2073 |
|
2074 |
|
2075 |
|
2076 |
|
2077 |
|
2078 |
|
2079 |
|
2080 |
|
2081 |
|
2082 |
|
2083 |
|
2084 |
|
2085 |
|
2086 |
|
2087 |
|
2088 |
|
2089 |
|
2090 |
|
2091 |
|
2092 |
|
2093 |
|
2094 |
|
2095 |
|
2096 |
|
2097 |
|
2098 |
|
2099 |
|
2100 |
|
2101 |
|
2102 |
|
2103 |
|
2104 |
|
2105 |
|
2106 |
|
2107 |
|
2108 |
|
2109 |
|
2110 |
|
2111 |
|
2112 |
|
2113 |
|
2114 |
|
2115 |
|
2116 |
|
2117 |
|
2118 |
|
2119 |
|
2120 |
|
2121 |
|
2122 |
|
2123 |
|
2124 |
|
2125 |
|
2126 |
|
2127 |
|
2128 |
|
2129 |
|
2130 |
|
2131 |
|
2132 |
|
2133 |
|
2134 |
|
2135 |
|
2136 |
|
2137 |
|
2138 |
|
2139 |
|
2140 |
|
2141 |
|
2142 |
|
2143 |
|
2144 |
|
2145 |
|
2146 |
|
2147 |
|
2148 |
|
2149 |
|
2150 |
|
2151 |
|
2152 |
|
2153 |
|
2154 |
|
2155 |
|
2156 |
|
2157 |
|
2158 |
|
2159 |
|
2160 |
|
2161 |
|
2162 |
|
2163 |
|
2164 |
|
2165 |
|
2166 |
|
2167 |
|
2168 |
|
2169 |
|
2170 |
|
2171 |
|
2172 |
|
2173 |
|
2174 |
|
2175 |
|
2176 |
|
2177 |
|
2178 |
|
2179 |
|
2180 |
|
2181 |
|
2182 |
|
2183 |
|
2184 |
|
2185 |
|
2186 |
|
2187 |
|
2188 |
|
2189 |
|
2190 |
|
2191 |
|
2192 |
|
2193 |
|
2194 |
|
2195 |
|
2196 |
|
2197 |
|
2198 |
|
2199 |
|
2200 |
|
2201 |
|
2202 |
|
2203 |
|
2204 |
|
2205 |
|
2206 |
|
2207 |
|
2208 |
|
2209 |
|
2210 |
|
2211 |
|
2212 |
|
2213 |
|
2214 |
|
2215 |
|
2216 |
|
2217 |
|
2218 |
|
2219 |
|
2220 |
|
2221 |
|
2222 |
|
2223 |
|
2224 |
|
2225 |
|
2226 |
|
2227 |
|
2228 |
|
2229 |
|
2230 |
|
2231 |
|
2232 |
|
2233 |
|
2234 |
|
2235 |
|
2236 |
|
2237 |
|
2238 |
|
2239 |
|
2240 |
|
2241 |
|
2242 |
|
2243 |
|
2244 |
|
2245 |
|
2246 |
|
2247 | async function readJson(loc) {
|
2248 | return (await readJsonAndFile(loc)).object;
|
2249 | }
|
2250 | async function readJsonAndFile(loc) {
|
2251 | const file = await readFile(loc);
|
2252 |
|
2253 | try {
|
2254 | return {
|
2255 | object: nullify(JSON.parse(stripBOM(file))),
|
2256 | content: file
|
2257 | };
|
2258 | } catch (err) {
|
2259 | err.message = `${loc}: ${err.message}`;
|
2260 | throw err;
|
2261 | }
|
2262 | }
|
2263 |
|
2264 |
|
2265 |
|
2266 |
|
2267 |
|
2268 |
|
2269 |
|
2270 |
|
2271 | const cr = '\r'.charCodeAt(0);
|
2272 | const lf = '\n'.charCodeAt(0);
|
2273 |
|
2274 | async function getEolFromFile(path) {
|
2275 | if (!(await exists(path))) {
|
2276 | return undefined;
|
2277 | }
|
2278 |
|
2279 | const buffer = await readFileBuffer(path);
|
2280 |
|
2281 | for (let i = 0; i < buffer.length; ++i) {
|
2282 | if (buffer[i] === cr) {
|
2283 | return '\r\n';
|
2284 | }
|
2285 |
|
2286 | if (buffer[i] === lf) {
|
2287 | return '\n';
|
2288 | }
|
2289 | }
|
2290 |
|
2291 | return undefined;
|
2292 | }
|
2293 |
|
2294 | async function writeFilePreservingEol(path, data) {
|
2295 | const eol = (await getEolFromFile(path)) || os.EOL;
|
2296 |
|
2297 | if (eol !== '\n') {
|
2298 | data = data.replace(/\n/g, eol);
|
2299 | }
|
2300 |
|
2301 | await writeFile(path, data);
|
2302 | }
|
2303 |
|
2304 |
|
2305 |
|
2306 |
|
2307 |
|
2308 |
|
2309 |
|
2310 |
|
2311 |
|
2312 |
|
2313 |
|
2314 |
|
2315 |
|
2316 |
|
2317 |
|
2318 |
|
2319 |
|
2320 |
|
2321 |
|
2322 |
|
2323 |
|
2324 |
|
2325 |
|
2326 |
|
2327 |
|
2328 |
|
2329 |
|
2330 |
|
2331 |
|
2332 |
|
2333 |
|
2334 |
|
2335 |
|
2336 |
|
2337 |
|
2338 |
|
2339 |
|
2340 |
|
2341 |
|
2342 |
|
2343 |
|
2344 |
|
2345 |
|
2346 |
|
2347 |
|
2348 |
|
2349 |
|
2350 |
|
2351 |
|
2352 |
|
2353 |
|
2354 |
|
2355 |
|
2356 |
|
2357 |
|
2358 |
|
2359 | async function generatePublishManifest(manifest, config, _dists) {
|
2360 | const {
|
2361 | name,
|
2362 | version,
|
2363 | description,
|
2364 | keywords,
|
2365 | homepage,
|
2366 | bugs,
|
2367 | bin,
|
2368 | license,
|
2369 | authors,
|
2370 | contributors,
|
2371 | man,
|
2372 | sideEffects,
|
2373 | repository,
|
2374 | dependencies,
|
2375 | peerDependencies,
|
2376 | devDependencies,
|
2377 | bundledDependencies,
|
2378 | optionalDependencies,
|
2379 | engines,
|
2380 | enginesStrict,
|
2381 | private: priv,
|
2382 | publishConfig
|
2383 | } = manifest;
|
2384 | const newManifest = {
|
2385 | name,
|
2386 | description,
|
2387 | version,
|
2388 | license,
|
2389 | bin,
|
2390 | files: ['dist-*/', 'bin/'],
|
2391 | pika: true,
|
2392 | sideEffects: sideEffects || false,
|
2393 | keywords,
|
2394 | homepage,
|
2395 | bugs,
|
2396 | authors,
|
2397 | contributors,
|
2398 | man,
|
2399 | repository,
|
2400 | dependencies: dependencies || {},
|
2401 | peerDependencies,
|
2402 | devDependencies,
|
2403 | bundledDependencies,
|
2404 | optionalDependencies,
|
2405 | engines,
|
2406 | enginesStrict,
|
2407 | private: priv,
|
2408 | publishConfig
|
2409 | };
|
2410 | const dists = _dists || (await config.getDistributions());
|
2411 |
|
2412 | for (const [runner, options] of dists) {
|
2413 | if (runner.manifest) {
|
2414 | await runner.manifest(newManifest, {
|
2415 | cwd: config.cwd,
|
2416 | isFull: true,
|
2417 | manifest,
|
2418 | options
|
2419 | });
|
2420 | }
|
2421 | }
|
2422 |
|
2423 | newManifest.pika = true;
|
2424 | return newManifest;
|
2425 | }
|
2426 | function generatePrettyManifest(manifest) {
|
2427 | return JSON.stringify(_objectSpread({}, manifest, {
|
2428 | dependencies: Object.keys(manifest.dependencies).length === 0 ? {} : '{ ... }'
|
2429 | }), null, 2);
|
2430 | }
|
2431 |
|
2432 | function setFlags(commander) {
|
2433 | commander.description('Prepares your package out directory (pkg/) for publishing.');
|
2434 | commander.usage('build [flags]');
|
2435 | commander.option('-O, --out <path>', 'Where to write to');
|
2436 | commander.option('--force', 'Whether to ignore failed build plugins and continue through errors.');
|
2437 | commander.option('-P, --publish', 'Whether to include publish-only builds like unpkg & types.');
|
2438 | }
|
2439 | function hasWrapper(commander, args) {
|
2440 | return true;
|
2441 | }
|
2442 | class Build {
|
2443 | constructor(flags, config, reporter) {
|
2444 | this.flags = flags;
|
2445 | this.config = config;
|
2446 | this.reporter = reporter;
|
2447 | this.totalNum = 0;
|
2448 | this.out = path.resolve(config.cwd, flags.out || 'pkg/');
|
2449 |
|
2450 | if (this.out === this.config.cwd) {
|
2451 | throw new Error('On publish, you cannot write to cwd because a package.json is created');
|
2452 | }
|
2453 | }
|
2454 |
|
2455 | async cleanup() {
|
2456 | const {
|
2457 | out
|
2458 | } = this;
|
2459 | await unlink(path.join(out, '*'));
|
2460 | }
|
2461 |
|
2462 | async init(isFull) {
|
2463 | const {
|
2464 | config,
|
2465 | out,
|
2466 | reporter,
|
2467 | flags
|
2468 | } = this;
|
2469 | const {
|
2470 | cwd
|
2471 | } = config;
|
2472 | const outPretty = path.relative(cwd, out) + path.sep;
|
2473 | const manifest = await config.manifest;
|
2474 | const distRunners = await config.getDistributions();
|
2475 | const builderConfig = {
|
2476 | out,
|
2477 | cwd,
|
2478 | reporter: {
|
2479 | info: msg => reporter.log(chalk.dim(` » ${msg}`)),
|
2480 | warning: msg => reporter.log(chalk.yellow(` » ${msg}`)),
|
2481 | success: msg => reporter.log(chalk.green(` » ${msg}`)),
|
2482 | created: (filename, entrypoint) => reporter.log(` 📝 ${chalk.green(path.relative(cwd, filename))} ${entrypoint ? chalk.dim(`[${entrypoint}]`) : ''}`)
|
2483 | },
|
2484 | isFull,
|
2485 | manifest,
|
2486 | src: {
|
2487 | loc: path.join(out, 'dist-src'),
|
2488 | entrypoint: path.join(out, 'dist-src', 'index.js'),
|
2489 |
|
2490 | options: {},
|
2491 |
|
2492 | files: await (async () => {
|
2493 | const ignoreSet = new Set([]);
|
2494 | ignoreSet.add('**/*/README.md');
|
2495 | const files = await glob(`src/**/*`, {
|
2496 | cwd,
|
2497 | nodir: true,
|
2498 | absolute: true,
|
2499 | ignore: Array.from(ignoreSet).map(g => path.join('src', g))
|
2500 | });
|
2501 | return files.filter(fileAbs => !fileAbs.endsWith('.d.ts'));
|
2502 | })()
|
2503 | }
|
2504 | };
|
2505 | const steps = [];
|
2506 | steps.push(async (curr, total) => {
|
2507 | this.reporter.step(curr, total, 'Validating source');
|
2508 |
|
2509 | for (const [runner, options] of distRunners) {
|
2510 | if (runner.validate) {
|
2511 | const result = await runner.validate(_objectSpread({}, builderConfig, {
|
2512 | options
|
2513 | }));
|
2514 |
|
2515 | if (result instanceof Error) {
|
2516 | throw result;
|
2517 | }
|
2518 | }
|
2519 | }
|
2520 | });
|
2521 | steps.push(async (curr, total) => {
|
2522 | this.reporter.step(curr, total, `Preparing pipeline`);
|
2523 | await this.cleanup();
|
2524 | reporter.log(` ❇️ ${chalk.green(outPretty)}`);
|
2525 |
|
2526 | for (const [runner, options] of distRunners) {
|
2527 | await (runner.beforeBuild && runner.beforeBuild(_objectSpread({}, builderConfig, {
|
2528 | options
|
2529 | })));
|
2530 | }
|
2531 | });
|
2532 |
|
2533 | if (distRunners.length === 0) {
|
2534 | steps.push(async (curr, total) => {
|
2535 | this.reporter.step(curr, total, `Pipeline is empty! See ${chalk.underline('https://github.com/pikapkg/pack')} for help getting started`);
|
2536 | });
|
2537 | }
|
2538 |
|
2539 | for (const [runner, options] of distRunners) {
|
2540 | steps.push(async (curr, total) => {
|
2541 | this.reporter.step(curr, total, `Running ${chalk.bold(runner.name)}`);
|
2542 |
|
2543 | try {
|
2544 | await (runner.beforeJob && runner.beforeJob(_objectSpread({}, builderConfig, {
|
2545 | options
|
2546 | })));
|
2547 | await (runner.build && runner.build(_objectSpread({}, builderConfig, {
|
2548 | options
|
2549 | })));
|
2550 | await (runner.afterJob && runner.afterJob(_objectSpread({}, builderConfig, {
|
2551 | options
|
2552 | })));
|
2553 | } catch (err) {
|
2554 | if (flags.force) {
|
2555 | console.log(' ❗️ ', chalk.red(err.message), chalk.dim('--force, continuing...'));
|
2556 | } else {
|
2557 | throw err;
|
2558 | }
|
2559 | }
|
2560 |
|
2561 |
|
2562 |
|
2563 |
|
2564 |
|
2565 |
|
2566 |
|
2567 |
|
2568 |
|
2569 |
|
2570 |
|
2571 |
|
2572 |
|
2573 | });
|
2574 | }
|
2575 |
|
2576 | steps.push(async (curr, total) => {
|
2577 | this.reporter.step(curr, total, `Finalizing package`);
|
2578 |
|
2579 | for (const [runner, options] of distRunners) {
|
2580 | await (runner.afterBuild && runner.afterBuild(_objectSpread({}, builderConfig, {
|
2581 | options
|
2582 | })));
|
2583 | }
|
2584 |
|
2585 | if (await exists(path.join(cwd, 'CHANGELOG'))) {
|
2586 | copyFile(path.join(cwd, 'CHANGELOG'), path.join(out, 'CHANGELOG'));
|
2587 | reporter.log(chalk.dim(` » copying CHANGELOG...`));
|
2588 | } else if (await exists(path.join(cwd, 'CHANGELOG.md'))) {
|
2589 | copyFile(path.join(cwd, 'CHANGELOG.md'), path.join(out, 'CHANGELOG.md'));
|
2590 | reporter.log(chalk.dim(` » copying CHANGELOG.md...`));
|
2591 | }
|
2592 |
|
2593 | if (await exists(path.join(cwd, 'LICENSE'))) {
|
2594 | copyFile(path.join(cwd, 'LICENSE'), path.join(out, 'LICENSE'));
|
2595 | reporter.log(chalk.dim(` » copying LICENSE...`));
|
2596 | } else if (await exists(path.join(cwd, 'LICENSE.md'))) {
|
2597 | copyFile(path.join(cwd, 'LICENSE.md'), path.join(out, 'LICENSE.md'));
|
2598 | reporter.log(chalk.dim(` » copying LICENSE.md...`));
|
2599 | }
|
2600 |
|
2601 | if (await exists(path.join(cwd, 'README'))) {
|
2602 | copyFile(path.join(cwd, 'README'), path.join(out, 'README'));
|
2603 | reporter.log(chalk.dim(` » copying README...`));
|
2604 | } else if (await exists(path.join(cwd, 'README.md'))) {
|
2605 | copyFile(path.join(cwd, 'README.md'), path.join(out, 'README.md'));
|
2606 | reporter.log(chalk.dim(` » copying README.md...`));
|
2607 | }
|
2608 |
|
2609 | const publishManifest = await generatePublishManifest(config._manifest, config, distRunners);
|
2610 |
|
2611 | if (out === cwd) {
|
2612 | reporter.log(`NEW MANIFEST:\n\n`);
|
2613 | reporter.log(generatePrettyManifest(publishManifest));
|
2614 | reporter.log(`\n\n`);
|
2615 | } else {
|
2616 | await writeFilePreservingEol(path.join(out, 'package.json'), JSON.stringify(publishManifest, null, DEFAULT_INDENT) + '\n');
|
2617 | reporter.log(` 📝 ` + chalk.green(outPretty + 'package.json'));
|
2618 | }
|
2619 |
|
2620 | reporter.log(` 📦 ` + chalk.green(outPretty));
|
2621 | });
|
2622 | let currentStep = 0;
|
2623 |
|
2624 | for (const step of steps) {
|
2625 | await step(++currentStep, steps.length);
|
2626 | }
|
2627 | }
|
2628 |
|
2629 | }
|
2630 | async function run(config, reporter, flags, args) {
|
2631 | const isProduction = flags.publish;
|
2632 | const builder = new Build(flags, config, reporter);
|
2633 | await builder.init(isProduction);
|
2634 | }
|
2635 |
|
2636 | var build = Object.freeze({
|
2637 | setFlags: setFlags,
|
2638 | hasWrapper: hasWrapper,
|
2639 | Build: Build,
|
2640 | run: run
|
2641 | });
|
2642 |
|
2643 | class BlockingQueue {
|
2644 | constructor(alias, maxConcurrency = Infinity) {
|
2645 | this.concurrencyQueue = [];
|
2646 | this.maxConcurrency = maxConcurrency;
|
2647 | this.runningCount = 0;
|
2648 | this.warnedStuck = false;
|
2649 | this.alias = alias;
|
2650 | this.first = true;
|
2651 | this.running = nullify() || {};
|
2652 | this.queue = nullify() || {};
|
2653 | this.stuckTick = this.stuckTick.bind(this);
|
2654 | }
|
2655 |
|
2656 | stillActive() {
|
2657 | if (this.stuckTimer) {
|
2658 | clearTimeout(this.stuckTimer);
|
2659 | }
|
2660 |
|
2661 | this.stuckTimer = setTimeout(this.stuckTick, 5000);
|
2662 |
|
2663 |
|
2664 | this.stuckTimer.unref && this.stuckTimer.unref();
|
2665 | }
|
2666 |
|
2667 | stuckTick() {
|
2668 | if (this.runningCount === 1) {
|
2669 | this.warnedStuck = true;
|
2670 | console.log(`The ${JSON.stringify(this.alias)} blocking queue may be stuck. 5 seconds ` + `without any activity with 1 worker: ${Object.keys(this.running)[0]}`);
|
2671 | }
|
2672 | }
|
2673 |
|
2674 | push(key, factory) {
|
2675 | if (this.first) {
|
2676 | this.first = false;
|
2677 | } else {
|
2678 | this.stillActive();
|
2679 | }
|
2680 |
|
2681 | return new Promise((resolve, reject) => {
|
2682 |
|
2683 | const queue = this.queue[key] = this.queue[key] || [];
|
2684 | queue.push({
|
2685 | factory,
|
2686 | resolve,
|
2687 | reject
|
2688 | });
|
2689 |
|
2690 | if (!this.running[key]) {
|
2691 | this.shift(key);
|
2692 | }
|
2693 | });
|
2694 | }
|
2695 |
|
2696 | shift(key) {
|
2697 | if (this.running[key]) {
|
2698 | delete this.running[key];
|
2699 | this.runningCount--;
|
2700 |
|
2701 | if (this.stuckTimer) {
|
2702 | clearTimeout(this.stuckTimer);
|
2703 | this.stuckTimer = null;
|
2704 | }
|
2705 |
|
2706 | if (this.warnedStuck) {
|
2707 | this.warnedStuck = false;
|
2708 | console.log(`${JSON.stringify(this.alias)} blocking queue finally resolved. Nothing to worry about.`);
|
2709 | }
|
2710 | }
|
2711 |
|
2712 | const queue = this.queue[key];
|
2713 |
|
2714 | if (!queue) {
|
2715 | return;
|
2716 | }
|
2717 |
|
2718 | const {
|
2719 | resolve,
|
2720 | reject,
|
2721 | factory
|
2722 | } = queue.shift();
|
2723 |
|
2724 | if (!queue.length) {
|
2725 | delete this.queue[key];
|
2726 | }
|
2727 |
|
2728 | const next = () => {
|
2729 | this.shift(key);
|
2730 | this.shiftConcurrencyQueue();
|
2731 | };
|
2732 |
|
2733 | const run = () => {
|
2734 | this.running[key] = true;
|
2735 | this.runningCount++;
|
2736 | factory().then(function (val) {
|
2737 | resolve(val);
|
2738 | next();
|
2739 | return null;
|
2740 | }).catch(function (err) {
|
2741 | reject(err);
|
2742 | next();
|
2743 | });
|
2744 | };
|
2745 |
|
2746 | this.maybePushConcurrencyQueue(run);
|
2747 | }
|
2748 |
|
2749 | maybePushConcurrencyQueue(run) {
|
2750 | if (this.runningCount < this.maxConcurrency) {
|
2751 | run();
|
2752 | } else {
|
2753 | this.concurrencyQueue.push(run);
|
2754 | }
|
2755 | }
|
2756 |
|
2757 | shiftConcurrencyQueue() {
|
2758 | if (this.runningCount < this.maxConcurrency) {
|
2759 | const fn = this.concurrencyQueue.shift();
|
2760 |
|
2761 | if (fn) {
|
2762 | fn();
|
2763 | }
|
2764 | }
|
2765 | }
|
2766 |
|
2767 | }
|
2768 |
|
2769 | class ProcessSpawnError extends types.MessageError {
|
2770 | constructor(msg, code, process) {
|
2771 | super(msg);
|
2772 | this.code = code;
|
2773 | this.process = process;
|
2774 | }
|
2775 |
|
2776 | }
|
2777 | class ProcessTermError extends types.MessageError {}
|
2778 |
|
2779 |
|
2780 | const queue = new BlockingQueue('child', CHILD_CONCURRENCY);
|
2781 |
|
2782 | let uid = 0;
|
2783 | const spawnedProcesses = {};
|
2784 | function forwardSignalToSpawnedProcesses(signal) {
|
2785 | for (const key of Object.keys(spawnedProcesses)) {
|
2786 | spawnedProcesses[key].kill(signal);
|
2787 | }
|
2788 | }
|
2789 | function spawn(program, args, opts = {}, onData) {
|
2790 | const key = opts.cwd || String(++uid);
|
2791 | return queue.push(key, () => new Promise((resolve, reject) => {
|
2792 | const proc = child_process.spawn(program, args, opts);
|
2793 |
|
2794 | spawnedProcesses[key] = proc;
|
2795 | let processingDone = false;
|
2796 | let processClosed = false;
|
2797 | let err = null;
|
2798 | let stdout = '';
|
2799 | proc.on('error', err => {
|
2800 | if (err.code === 'ENOENT') {
|
2801 | reject(new ProcessSpawnError(`Couldn't find the binary ${program}`, err.code, program));
|
2802 | } else {
|
2803 | reject(err);
|
2804 | }
|
2805 | });
|
2806 |
|
2807 | function updateStdout(chunk) {
|
2808 | stdout += chunk;
|
2809 |
|
2810 | if (onData) {
|
2811 | onData(chunk);
|
2812 | }
|
2813 | }
|
2814 |
|
2815 | function finish() {
|
2816 | delete spawnedProcesses[key];
|
2817 |
|
2818 | if (err) {
|
2819 | reject(err);
|
2820 | } else {
|
2821 | resolve(stdout.trim());
|
2822 | }
|
2823 | }
|
2824 |
|
2825 | if (typeof opts.process === 'function') {
|
2826 | opts.process(proc, updateStdout, reject, function () {
|
2827 | if (processClosed) {
|
2828 | finish();
|
2829 | } else {
|
2830 | processingDone = true;
|
2831 | }
|
2832 | });
|
2833 | } else {
|
2834 | if (proc.stderr) {
|
2835 | proc.stderr.on('data', updateStdout);
|
2836 | }
|
2837 |
|
2838 | if (proc.stdout) {
|
2839 | proc.stdout.on('data', updateStdout);
|
2840 | }
|
2841 |
|
2842 | processingDone = true;
|
2843 | }
|
2844 |
|
2845 | proc.on('close', (code, signal) => {
|
2846 | if (signal || code >= 1) {
|
2847 | err = new ProcessTermError(['Command failed.', signal ? `Exit signal: ${signal}` : `Exit code: ${code}`, `Command: ${program}`, `Arguments: ${args.join(' ')}`, `Directory: ${opts.cwd || process.cwd()}`, `Output:\n${stdout.trim()}`].join('\n'));
|
2848 | err.EXIT_SIGNAL = signal;
|
2849 | err.EXIT_CODE = code;
|
2850 | }
|
2851 |
|
2852 | if (processingDone || err) {
|
2853 | finish();
|
2854 | } else {
|
2855 | processClosed = true;
|
2856 | }
|
2857 | });
|
2858 | }));
|
2859 | }
|
2860 |
|
2861 | function fixCmdWinSlashes(cmd) {
|
2862 | function findQuotes(quoteSymbol) {
|
2863 | const quotes = [];
|
2864 |
|
2865 | const addQuote = (_, index) => {
|
2866 | quotes.push({
|
2867 | from: index,
|
2868 | to: index + _.length
|
2869 | });
|
2870 | return _;
|
2871 | };
|
2872 |
|
2873 | const regEx = new RegExp(quoteSymbol + '.*' + quoteSymbol);
|
2874 | cmd.replace(regEx, addQuote);
|
2875 | return quotes;
|
2876 | }
|
2877 |
|
2878 | const quotes = findQuotes('"').concat(findQuotes("'"));
|
2879 |
|
2880 | function isInsideQuotes(index) {
|
2881 | return quotes.reduce((result, quote) => {
|
2882 | return result || quote.from <= index && index <= quote.to;
|
2883 | }, false);
|
2884 | }
|
2885 |
|
2886 | const cmdPrePattern = '((?:^|&&|&|\\|\\||\\|)\\s*)';
|
2887 | const cmdPattern = '(".*?"|\'.*?\'|\\S*)';
|
2888 | const regExp = new RegExp(`${cmdPrePattern}${cmdPattern}`, 'g');
|
2889 | return cmd.replace(regExp, (whole, pre, cmd, index) => {
|
2890 | if ((pre[0] === '&' || pre[0] === '|') && isInsideQuotes(index)) {
|
2891 | return whole;
|
2892 | }
|
2893 |
|
2894 | return pre + cmd.replace(/\//g, '\\');
|
2895 | });
|
2896 | }
|
2897 |
|
2898 |
|
2899 |
|
2900 |
|
2901 |
|
2902 |
|
2903 |
|
2904 |
|
2905 |
|
2906 |
|
2907 |
|
2908 |
|
2909 |
|
2910 |
|
2911 |
|
2912 |
|
2913 |
|
2914 |
|
2915 |
|
2916 |
|
2917 |
|
2918 |
|
2919 |
|
2920 |
|
2921 |
|
2922 |
|
2923 |
|
2924 |
|
2925 |
|
2926 |
|
2927 | async function makeEnv() {
|
2928 |
|
2929 |
|
2930 |
|
2931 | const env = _objectSpread({
|
2932 | NODE: process.execPath,
|
2933 | INIT_CWD: process.cwd()
|
2934 | }, process.env);
|
2935 |
|
2936 | return env;
|
2937 | }
|
2938 |
|
2939 |
|
2940 |
|
2941 |
|
2942 |
|
2943 |
|
2944 |
|
2945 |
|
2946 |
|
2947 |
|
2948 |
|
2949 |
|
2950 |
|
2951 |
|
2952 |
|
2953 |
|
2954 |
|
2955 |
|
2956 |
|
2957 |
|
2958 |
|
2959 |
|
2960 |
|
2961 |
|
2962 |
|
2963 |
|
2964 |
|
2965 |
|
2966 |
|
2967 |
|
2968 |
|
2969 |
|
2970 |
|
2971 |
|
2972 |
|
2973 |
|
2974 |
|
2975 |
|
2976 |
|
2977 |
|
2978 |
|
2979 |
|
2980 |
|
2981 |
|
2982 |
|
2983 |
|
2984 |
|
2985 |
|
2986 |
|
2987 |
|
2988 |
|
2989 |
|
2990 |
|
2991 |
|
2992 |
|
2993 |
|
2994 |
|
2995 |
|
2996 |
|
2997 |
|
2998 |
|
2999 |
|
3000 |
|
3001 |
|
3002 |
|
3003 |
|
3004 |
|
3005 |
|
3006 |
|
3007 |
|
3008 |
|
3009 |
|
3010 |
|
3011 |
|
3012 |
|
3013 |
|
3014 |
|
3015 |
|
3016 |
|
3017 |
|
3018 |
|
3019 |
|
3020 |
|
3021 |
|
3022 |
|
3023 |
|
3024 |
|
3025 |
|
3026 |
|
3027 |
|
3028 |
|
3029 |
|
3030 |
|
3031 |
|
3032 |
|
3033 |
|
3034 |
|
3035 |
|
3036 |
|
3037 |
|
3038 |
|
3039 |
|
3040 |
|
3041 |
|
3042 |
|
3043 |
|
3044 |
|
3045 |
|
3046 |
|
3047 |
|
3048 |
|
3049 |
|
3050 |
|
3051 |
|
3052 |
|
3053 |
|
3054 |
|
3055 |
|
3056 |
|
3057 |
|
3058 |
|
3059 |
|
3060 |
|
3061 |
|
3062 |
|
3063 |
|
3064 |
|
3065 |
|
3066 |
|
3067 |
|
3068 |
|
3069 |
|
3070 |
|
3071 |
|
3072 |
|
3073 |
|
3074 |
|
3075 |
|
3076 |
|
3077 |
|
3078 |
|
3079 |
|
3080 | async function executeLifecycleScript({
|
3081 | // config,
|
3082 | cwd,
|
3083 | cmd,
|
3084 | args,
|
3085 | isInteractive,
|
3086 | onProgress,
|
3087 | customShell
|
3088 | }) {
|
3089 | const env = await makeEnv();
|
3090 |
|
3091 | if (process.platform === 'win32' && (!customShell || customShell === 'cmd')) {
|
3092 |
|
3093 | cmd = fixCmdWinSlashes(cmd);
|
3094 | }
|
3095 |
|
3096 |
|
3097 |
|
3098 | let stdio = ['ignore', 'pipe', 'pipe'];
|
3099 | let detached = process.platform !== 'win32';
|
3100 |
|
3101 | if (isInteractive) {
|
3102 | stdio = 'inherit';
|
3103 | detached = false;
|
3104 | }
|
3105 |
|
3106 | const shell = customShell || true;
|
3107 | const stdout = await spawn(cmd, args, {
|
3108 | cwd,
|
3109 | env,
|
3110 | stdio,
|
3111 | detached,
|
3112 | shell
|
3113 | }, onProgress);
|
3114 | return {
|
3115 | cwd,
|
3116 | command: cmd,
|
3117 | stdout
|
3118 | };
|
3119 | }
|
3120 |
|
3121 |
|
3122 |
|
3123 |
|
3124 |
|
3125 |
|
3126 |
|
3127 |
|
3128 |
|
3129 |
|
3130 |
|
3131 |
|
3132 |
|
3133 |
|
3134 |
|
3135 |
|
3136 |
|
3137 |
|
3138 |
|
3139 |
|
3140 |
|
3141 |
|
3142 |
|
3143 |
|
3144 |
|
3145 |
|
3146 |
|
3147 |
|
3148 |
|
3149 |
|
3150 |
|
3151 |
|
3152 |
|
3153 |
|
3154 |
|
3155 |
|
3156 |
|
3157 |
|
3158 |
|
3159 |
|
3160 |
|
3161 |
|
3162 |
|
3163 |
|
3164 |
|
3165 |
|
3166 |
|
3167 |
|
3168 |
|
3169 |
|
3170 |
|
3171 |
|
3172 |
|
3173 |
|
3174 |
|
3175 |
|
3176 |
|
3177 |
|
3178 |
|
3179 |
|
3180 |
|
3181 |
|
3182 |
|
3183 |
|
3184 |
|
3185 |
|
3186 |
|
3187 |
|
3188 |
|
3189 |
|
3190 |
|
3191 |
|
3192 |
|
3193 |
|
3194 |
|
3195 |
|
3196 |
|
3197 | function setFlags$1(commander) {
|
3198 | commander.description('Publish');
|
3199 | commander.usage('publish [version] [...flags]');
|
3200 | commander.option('--any-branch', 'Allow publishing from any branch');
|
3201 | commander.option('--no-cleanup', 'Skips cleanup of node_modules');
|
3202 | commander.option('--yolo', 'Skips cleanup and testing');
|
3203 | commander.option('--no-publish', 'Skips publishing');
|
3204 | commander.option('--tag', ' Publish under a given dist-tag');
|
3205 | commander.option('--no-yarn', " Don't use Yarn");
|
3206 | commander.option('--contents', 'Subdirectory to publish', 'pkg/');
|
3207 | commander.option('--no-release-draft', 'Skips opening a GitHub release draft');
|
3208 | commander.option('--otp <code>', 'Publish with an OTP code');
|
3209 | }
|
3210 | function hasWrapper$1() {
|
3211 | return false;
|
3212 | }
|
3213 | async function run$1(config, reporter, flags, args) {
|
3214 | const contentsArg = flags.contents ? [] : ['--contents', flags.out || flags.contents || 'pkg/'];
|
3215 | const manifest = await config.loadPackageManifest();
|
3216 |
|
3217 | if (!manifest.scripts.version) {
|
3218 | reporter.warn(`${chalk.bold('missing "version" script:')} You'll want to create a fresh build after bumping the master package.json version.`);
|
3219 |
|
3220 | if (manifest.scripts.build) {
|
3221 | config._manifest.scripts.version = 'npm run build';
|
3222 | } else {
|
3223 | config._manifest.scripts.version = 'npx @pika/pack build';
|
3224 | }
|
3225 |
|
3226 | reporter.log(`Adding the following "version" lifecycle script to your package.json... ` + chalk.bold(`"${config._manifest.scripts.version}"`));
|
3227 | await config.savePackageManifest(config._manifest);
|
3228 | reporter.log(`Please review & commit this change before publishing.`);
|
3229 | return;
|
3230 | }
|
3231 |
|
3232 |
|
3233 | try {
|
3234 | await executeLifecycleScript({
|
3235 | cwd: config.cwd,
|
3236 | cmd: 'npx',
|
3237 | args: ['np', ...contentsArg, ...flags.originalArgs],
|
3238 | isInteractive: true
|
3239 | });
|
3240 | } catch (err) {
|
3241 |
|
3242 | return;
|
3243 | }
|
3244 |
|
3245 | const newManifest = await config.loadPackageManifest();
|
3246 | console.log(`If published publicly, you can see it at: ${chalk.underline(`https://unpkg.com/${newManifest.name}@${newManifest.version}/`)}`);
|
3247 | }
|
3248 |
|
3249 | var publish = Object.freeze({
|
3250 | setFlags: setFlags$1,
|
3251 | hasWrapper: hasWrapper$1,
|
3252 | run: run$1
|
3253 | });
|
3254 |
|
3255 | const commands = {
|
3256 | build,
|
3257 | publish
|
3258 | };
|
3259 |
|
3260 |
|
3261 | function hasWrapper$2(flags, args) {
|
3262 | return false;
|
3263 | }
|
3264 | function setFlags$2(commander) {
|
3265 | commander.description('Displays help information.');
|
3266 | }
|
3267 | function run$2(config, reporter, commander, args) {
|
3268 | if (args.length) {
|
3269 | const commandName = args.shift();
|
3270 |
|
3271 | if (Object.prototype.hasOwnProperty.call(commands, commandName)) {
|
3272 | const command = commands[commandName];
|
3273 |
|
3274 | if (command) {
|
3275 | command.setFlags(commander);
|
3276 | const examples = (command && command.examples || []).map(example => ` $ pika ${example}`);
|
3277 |
|
3278 | if (examples.length) {
|
3279 | commander.on('--help', () => {
|
3280 | reporter.log(reporter.lang('helpExamples', reporter.rawText(examples.join('\n'))));
|
3281 | });
|
3282 | }
|
3283 |
|
3284 |
|
3285 |
|
3286 | commander.help();
|
3287 | return Promise.resolve();
|
3288 | }
|
3289 | }
|
3290 | }
|
3291 |
|
3292 | commander.options.sort(sortOptionsByFlags);
|
3293 | commander.help();
|
3294 | return Promise.resolve();
|
3295 | }
|
3296 |
|
3297 | var helpCommand = Object.freeze({
|
3298 | hasWrapper: hasWrapper$2,
|
3299 | setFlags: setFlags$2,
|
3300 | run: run$2
|
3301 | });
|
3302 |
|
3303 | var typos = {
|
3304 | autohr: 'author',
|
3305 | autor: 'author',
|
3306 | contributers: 'contributors',
|
3307 | depdenencies: 'dependencies',
|
3308 | dependancies: 'dependencies',
|
3309 | dependecies: 'dependencies',
|
3310 | depends: 'dependencies',
|
3311 | 'dev-dependencies': 'devDependencies',
|
3312 | devDependences: 'devDependencies',
|
3313 | devDepenencies: 'devDependencies',
|
3314 | devEependencies: 'devDependencies',
|
3315 | devdependencies: 'devDependencies',
|
3316 | hampage: 'homepage',
|
3317 | hompage: 'homepage',
|
3318 | prefereGlobal: 'preferGlobal',
|
3319 | publicationConfig: 'publishConfig',
|
3320 | repo: 'repository',
|
3321 | repostitory: 'repository',
|
3322 | script: 'scripts'
|
3323 | };
|
3324 |
|
3325 | const strings = ['name', 'version'];
|
3326 | const dependencyKeys = [
|
3327 |
|
3328 | 'optionalDependencies',
|
3329 |
|
3330 |
|
3331 | 'dependencies', 'devDependencies'];
|
3332 |
|
3333 | function isValidName(name) {
|
3334 | return !name.match(/[\/@\s\+%:]/) && encodeURIComponent(name) === name;
|
3335 | }
|
3336 |
|
3337 | function isValidScopedName(name) {
|
3338 | if (name[0] !== '@') {
|
3339 | return false;
|
3340 | }
|
3341 |
|
3342 | const parts = name.slice(1).split('/');
|
3343 | return parts.length === 2 && isValidName(parts[0]) && isValidName(parts[1]);
|
3344 | }
|
3345 |
|
3346 | function isValidPackageName(name) {
|
3347 | return isValidName(name) || isValidScopedName(name);
|
3348 | }
|
3349 | function validate (info, isRoot, reporter, warn) {
|
3350 | if (isRoot) {
|
3351 | for (const key in typos) {
|
3352 | if (key in info) {
|
3353 | warn(reporter.lang('manifestPotentialTypo', key, typos[key]));
|
3354 | }
|
3355 | }
|
3356 | }
|
3357 |
|
3358 |
|
3359 | const {
|
3360 | name
|
3361 | } = info;
|
3362 |
|
3363 | if (typeof name === 'string') {
|
3364 | if (isRoot && isBuiltinModule(name)) {
|
3365 | warn(reporter.lang('manifestBuiltinModule', name));
|
3366 | }
|
3367 |
|
3368 |
|
3369 | if (name[0] === '.') {
|
3370 | throw new types.MessageError(reporter.lang('manifestNameDot'));
|
3371 | }
|
3372 |
|
3373 |
|
3374 | if (!isValidPackageName(name)) {
|
3375 | throw new types.MessageError(reporter.lang('manifestNameIllegalChars'));
|
3376 | }
|
3377 |
|
3378 |
|
3379 | const lower = name.toLowerCase();
|
3380 |
|
3381 | if (lower === 'node_modules' || lower === 'favicon.ico') {
|
3382 | throw new types.MessageError(reporter.lang('manifestNameBlacklisted'));
|
3383 | }
|
3384 | }
|
3385 |
|
3386 |
|
3387 |
|
3388 |
|
3389 |
|
3390 |
|
3391 |
|
3392 |
|
3393 |
|
3394 |
|
3395 |
|
3396 |
|
3397 |
|
3398 |
|
3399 | for (const key of strings) {
|
3400 | const val = info[key];
|
3401 |
|
3402 | if (val && typeof val !== 'string') {
|
3403 | throw new types.MessageError(reporter.lang('manifestStringExpected', key));
|
3404 | }
|
3405 | }
|
3406 |
|
3407 | cleanDependencies(info, isRoot, reporter, warn);
|
3408 | }
|
3409 | function cleanDependencies(info, isRoot, reporter, warn) {
|
3410 |
|
3411 | const depTypes = [];
|
3412 |
|
3413 | for (const type of dependencyKeys) {
|
3414 | const deps = info[type];
|
3415 |
|
3416 | if (!deps || typeof deps !== 'object') {
|
3417 | continue;
|
3418 | }
|
3419 |
|
3420 | depTypes.push([type, deps]);
|
3421 | }
|
3422 |
|
3423 |
|
3424 | const nonTrivialDeps = new Map();
|
3425 |
|
3426 | for (const [type, deps] of depTypes) {
|
3427 | for (const name of Object.keys(deps)) {
|
3428 | const version = deps[name];
|
3429 |
|
3430 | if (!nonTrivialDeps.has(name) && version && version !== '*') {
|
3431 | nonTrivialDeps.set(name, {
|
3432 | type,
|
3433 | version
|
3434 | });
|
3435 | }
|
3436 | }
|
3437 | }
|
3438 |
|
3439 |
|
3440 | const setDeps = new Set();
|
3441 |
|
3442 | for (const [type, deps] of depTypes) {
|
3443 | for (const name of Object.keys(deps)) {
|
3444 | let version = deps[name];
|
3445 | const dep = nonTrivialDeps.get(name);
|
3446 |
|
3447 | if (dep) {
|
3448 | if (version && version !== '*' && version !== dep.version && isRoot) {
|
3449 |
|
3450 | warn(reporter.lang('manifestDependencyCollision', dep.type, name, dep.version, type, version));
|
3451 | }
|
3452 |
|
3453 | version = dep.version;
|
3454 | }
|
3455 |
|
3456 | if (setDeps.has(name)) {
|
3457 | delete deps[name];
|
3458 | } else {
|
3459 | deps[name] = version;
|
3460 | setDeps.add(name);
|
3461 | }
|
3462 | }
|
3463 | }
|
3464 | }
|
3465 |
|
3466 | function isValidLicense(license) {
|
3467 | return !!license && validateLicense(license).validForNewPackages;
|
3468 | }
|
3469 | function stringifyPerson(person) {
|
3470 | if (!person || typeof person !== 'object') {
|
3471 | return person;
|
3472 | }
|
3473 |
|
3474 | const parts = [];
|
3475 |
|
3476 | if (person.name) {
|
3477 | parts.push(person.name);
|
3478 | }
|
3479 |
|
3480 | const email = person.email || person.mail;
|
3481 |
|
3482 | if (typeof email === 'string') {
|
3483 | parts.push(`<${email}>`);
|
3484 | }
|
3485 |
|
3486 | const url = person.url || person.web;
|
3487 |
|
3488 | if (typeof url === 'string') {
|
3489 | parts.push(`(${url})`);
|
3490 | }
|
3491 |
|
3492 | return parts.join(' ');
|
3493 | }
|
3494 | function parsePerson(person) {
|
3495 | if (typeof person !== 'string') {
|
3496 | return person;
|
3497 | }
|
3498 |
|
3499 |
|
3500 | const obj = {};
|
3501 | let name = person.match(/^([^\(<]+)/);
|
3502 |
|
3503 | if (name && name[0].trim()) {
|
3504 | obj.name = name[0].trim();
|
3505 | }
|
3506 |
|
3507 | const email = person.match(/<([^>]+)>/);
|
3508 |
|
3509 | if (email) {
|
3510 | obj.email = email[1];
|
3511 | }
|
3512 |
|
3513 | const url = person.match(/\(([^\)]+)\)/);
|
3514 |
|
3515 | if (url) {
|
3516 | obj.url = url[1];
|
3517 | }
|
3518 |
|
3519 | return obj;
|
3520 | }
|
3521 | function normalizePerson(person) {
|
3522 | return parsePerson(stringifyPerson(person));
|
3523 | }
|
3524 | function extractDescription(readme) {
|
3525 | if (typeof readme !== 'string' || readme === '') {
|
3526 | return undefined;
|
3527 | }
|
3528 |
|
3529 |
|
3530 | const lines = readme.trim().split('\n').map(line => line.trim());
|
3531 |
|
3532 | let start = 0;
|
3533 |
|
3534 | for (; start < lines.length; start++) {
|
3535 | const line = lines[start];
|
3536 |
|
3537 | if (line && line.match(/^(#|$)/)) {
|
3538 |
|
3539 | start++;
|
3540 | break;
|
3541 | }
|
3542 | }
|
3543 |
|
3544 |
|
3545 | while (start < lines.length && !lines[start]) {
|
3546 | start++;
|
3547 | }
|
3548 |
|
3549 |
|
3550 | let end = start;
|
3551 |
|
3552 | while (end < lines.length && lines[end]) {
|
3553 | end++;
|
3554 | }
|
3555 |
|
3556 | return lines.slice(start, end).join(' ');
|
3557 | }
|
3558 |
|
3559 | var LICENSES = {
|
3560 | 'Apache-2.0': new RegExp('(licensed under the apache license version the license you may not use this file except in compliance with the license you may obtain a copy of the license at http www apache org licenses license unless required by applicable law or agreed to in writing software distributed under the license is distributed on an as is basis without warranties or conditions of any kind either express or implied see the license for the specific language governing permissions and limitations under the license$|apache license version january http www apache org licenses terms and conditions for use reproduction and distribution definitions license shall mean the terms and conditions for use reproduction and distribution as defined by sections through of this document licensor shall mean the copyright owner or entity authorized by the copyright owner that is granting the license legal entity shall mean the union of the acting entity and all other entities that control are controlled by or are under common control with that entity for the purposes of this definition control means i the power direct or indirect to cause the direction or management of such entity whether by contract or otherwise or ii ownership of fifty percent or more of the outstanding shares or iii beneficial ownership of such entity you or your shall mean an individual or legal entity exercising permissions granted by this license source form shall mean the preferred form for making modifications including but not limited to software source code documentation source and configuration files object form shall mean any form resulting from mechanical transformation or translation of a source form including but not limited to compiled object code generated documentation and conversions to other media types work shall mean the work of authorship whether in source or object form made available under the license as indicated by a copyright notice that is included in or attached to the work an example is provided in the appendix below derivative works shall mean any work whether in source or object form that is based on or derived from the work and for which the editorial revisions annotations elaborations or other modifications represent as a whole an original work of authorship for the purposes of this license derivative works shall not include works that remain separable from or merely link or bind by name to the interfaces of the work and derivative works thereof contribution shall mean any work of authorship including the original version of the work and any modifications or additions to that work or derivative works thereof that is intentionally submitted to licensor for inclusion in the work by the copyright owner or by an individual or legal entity authorized to submit on behalf of the copyright owner for the purposes of this definition submitted means any form of electronic verbal or written communication sent to the licensor or its representatives including but not limited to communication on electronic mailing lists source code control systems and issue tracking systems that are managed by or on behalf of the licensor for the purpose of discussing and improving the work but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as not a contribution contributor shall mean licensor and any individual or legal entity on behalf of whom a contribution has been received by licensor and subsequently incorporated within the work grant of copyright license subject to the terms and conditions of this license each contributor hereby grants to you a perpetual worldwide non exclusive no charge royalty free irrevocable copyright license to reproduce prepare derivative works of publicly display publicly perform sublicense and distribute the work and such derivative works in source or object form grant of patent license subject to the terms and conditions of this license each contributor hereby grants to you a perpetual worldwide non exclusive no charge royalty free irrevocable except as stated in this section patent license to make have made use offer to sell sell import and otherwise transfer the work where such license applies only to those patent claims licensable by such contributor that are necessarily infringed by their contribution s alone or by combination of their contribution s with the work to which such contribution s was submitted if you institute patent litigation against any entity including a cross claim or counterclaim in a lawsuit alleging that the work or a contribution incorporated within the work constitutes direct or contributory patent infringement then any patent licenses granted to you under this license for that work shall terminate as of the date such litigation is filed redistribution you may reproduce and distribute copies of the work or derivative works thereof in any medium with or without modifications and in source or object form provided that you meet the following conditions a you must give any other recipients of the work or derivative works a copy of this license and b you must cause any modified files to carry prominent notices stating that you changed the files and c you must retain in the source form of any derivative works that you distribute all copyright patent trademark and attribution notices from the source form of the work excluding those notices that do not pertain to any part of the derivative works and d if the work includes a notice text file as part of its distribution then any derivative works that you distribute must include a readable copy of the attribution notices contained within such notice file excluding those notices that do not pertain to any part of the derivative works in at least one of the following places within a notice text file distributed as part of the derivative works within the source form or documentation if provided along with the derivative works or within a display generated by the derivative works if and wherever such third party notices normally appear the contents of the notice file are for informational purposes only and do not modify the license you may add your own attribution notices within derivative works that you distribute alongside or as an addendum to the notice text from the work provided that such additional attribution notices cannot be construed as modifying the license you may add your own copyright statement to your modifications and may provide additional or different license terms and conditions for use reproduction or distribution of your modifications or for any such derivative works as a whole provided your use reproduction and distribution of the work otherwise complies with the conditions stated in this license submission of contributions unless you explicitly state otherwise any contribution intentionally submitted for inclusion in the work by you to the licensor shall be under the terms and conditions of this license without any additional terms or conditions notwithstanding the above nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with licensor regarding such contributions trademarks this license does not grant permission to use the trade names trademarks service marks or product names of the licensor except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the notice file disclaimer of warranty unless required by applicable law or agreed to in writing licensor provides the work and each contributor provides its contributions on an as is basis without warranties or conditions of any kind either express or implied including without limitation any warranties or conditions of title non infringement merchantability or fitness for a particular purpose you are solely responsible for determining the appropriateness of using or redistributing the work and assume any risks associated with your exercise of permissions under this license limitation of liability in no event and under no legal theory whether in tort including negligence contract or otherwise unless required by applicable law such as deliberate and grossly negligent acts or agreed to in writing shall any contributor be liable to you for damages including any direct indirect special incidental or consequential damages of any character arising as a result of this license or out of the use or inability to use the work including but not limited to damages for loss of goodwill work stoppage computer failure or malfunction or any and all other commercial damages or losses even if such contributor has been advised of the possibility of such damages accepting warranty or additional liability while redistributing the work or derivative works thereof you may choose to offer and charge a fee for acceptance of support warranty indemnity or other liability obligations and or rights consistent with this license however in accepting such obligations you may act only on your own behalf and on your sole responsibility not on behalf of any other contributor and only if you agree to indemnify defend and hold each contributor harmless for any liability incurred by or claims asserted against such contributor by reason of your accepting any such warranty or additional liability end of terms and conditions$)', 'g'),
|
3561 | 'BSD-2-Clause': new RegExp('(redistribution and use in source and binary forms with or without modification are permitted provided that the following conditions are met redistributions of source code must retain the above copyright notice this list of conditions and the following disclaimer redistributions in binary form must reproduce the above copyright notice this list of conditions and the following disclaimer in the documentation and or other materials provided with the distribution this(.*?| )is provided by the copyright holders and contributors as is and any express or implied warranties including but not limited to the implied warranties of merchantability and fitness for a particular purpose are disclaimed in no event shall(.*?| )be liable for any direct indirect incidental special exemplary or consequential damages including but not limited to procurement of substitute goods or services loss of use data or profits or business interruption however caused and on any theory of liability whether in contract strict liability or tort including negligence or otherwise arising in any way out of the use of this(.*?| )even if advised of the possibility of such damage$|redistribution and use in source and binary forms with or without modification are permitted provided that the following conditions are met redistributions of source code must retain the above copyright notice this list of conditions and the following disclaimer redistributions in binary form must reproduce the above copyright notice this list of conditions and the following disclaimer in the documentation and or other materials provided with the distribution this software is provided by the copyright holders and contributors as is and any express or implied warranties including but not limited to the implied warranties of merchantability and fitness for a particular purpose are disclaimed in no event shall(.*?| )be liable for any direct indirect incidental special exemplary or consequential damages including but not limited to procurement of substitute goods or services loss of use data or profits or business interruption however caused and on any theory of liability whether in contract strict liability or tort including negligence or otherwise arising in any way out of the use of this software even if advised of the possibility of such damage$)', 'g'),
|
3562 | 'BSD-3-Clause': new RegExp('(redistribution and use in source and binary forms with or without modification are permitted provided that the following conditions are met redistributions of source code must retain the above copyright notice this list of conditions and the following disclaimer redistributions in binary form must reproduce the above copyright notice this list of conditions and the following disclaimer in the documentation and or other materials provided with the distribution neither the name of(.*?| )nor the names of the contributors may be used to endorse or promote products derived from this software without specific prior written permission this software is provided by the copyright holders and contributors as is and any express or implied warranties including but not limited to the implied warranties of merchantability and fitness for a particular purpose are disclaimed in no event shall(.*?| )be liable for any direct indirect incidental special exemplary or consequential damages including but not limited to procurement of substitute goods or services loss of use data or profits or business interruption however caused and on any theory of liability whether in contract strict liability or tort including negligence or otherwise arising in any way out of the use of this software even if advised of the possibility of such damage$|(redistribution and use in source and binary forms with or without modification are permitted provided that the following conditions are met redistributions of source code must retain the above copyright notice this list of conditions and the following disclaimer redistributions in binary form must reproduce the above copyright notice this list of conditions and the following disclaimer in the documentation and or other materials provided with the distribution the names of any contributors may not be used to endorse or promote products derived from this software without specific prior written permission this software is provided by the copyright holders and contributors as is and any express or implied warranties including but not limited to the implied warranties of merchantability and fitness for a particular purpose are disclaimed in no event shall the copyright holders and contributors be liable for any direct indirect incidental special exemplary or consequential damages including but not limited to procurement of substitute goods or services loss of use data or profits or business interruption however caused and on any theory of liability whether in contract strict liability or tort including negligence or otherwise arising in any way out of the use of this software even if advised of the possibility of such damage$|redistribution and use in source and binary forms with or without modification are permitted provided that the following conditions are met redistributions of source code must retain the above copyright notice this list of conditions and the following disclaimer redistributions in binary form must reproduce the above copyright notice this list of conditions and the following disclaimer in the documentation and or other materials provided with the distribution neither the name(.*?| )nor the names of(.*?| )contributors may be used to endorse or promote products derived from this software without specific prior written permission this software is provided by(.*?| )as is and any express or implied warranties including but not limited to the implied warranties of merchantability and fitness for a particular purpose are disclaimed in no event shall(.*?| )be liable for any direct indirect incidental special exemplary or consequential damages including but not limited to procurement of substitute goods or services loss of use data or profits or business interruption however caused and on any theory of liability whether in contract strict liability or tort including negligence or otherwise arising in any way out of the use of this software even if advised of the possibility of such damage$))', 'g'),
|
3563 | MIT: new RegExp('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$', 'g'),
|
3564 | Unlicense: new RegExp('this is free and unencumbered software released into the public domain anyone is free to copy modify publish use compile sell or distribute this software either in source code form or as a compiled binary for any purpose commercial or non commercial and by any means in jurisdictions that recognize copyright laws the author or authors of this software dedicate any and all copyright interest in the software to the public domain we make this dedication for the benefit of the public at large and to the detriment of our heirs and successors we intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law 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 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 for more information please refer to wildcard$', 'g')
|
3565 | };
|
3566 |
|
3567 | function clean(str) {
|
3568 | return str.replace(/[^A-Za-z\s]/g, ' ').replace(/[\s]+/g, ' ').trim().toLowerCase();
|
3569 | }
|
3570 |
|
3571 | const REGEXES = {
|
3572 | Apache: [/Apache License\b/],
|
3573 | BSD: [/BSD\b/],
|
3574 | ISC: [/The ISC License/, /ISC\b/],
|
3575 | MIT: [/MIT\b/],
|
3576 | Unlicense: [/http:\/\/unlicense.org\//],
|
3577 | WTFPL: [/DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE/, /WTFPL\b/]
|
3578 | };
|
3579 | function inferLicense(license) {
|
3580 |
|
3581 | const cleanLicense = clean(license);
|
3582 |
|
3583 | for (const licenseName in LICENSES) {
|
3584 | const testLicense = LICENSES[licenseName];
|
3585 |
|
3586 | if (cleanLicense.search(testLicense) >= 0) {
|
3587 | return licenseName;
|
3588 | }
|
3589 | }
|
3590 |
|
3591 |
|
3592 | for (const licenseName in REGEXES) {
|
3593 | for (const regex of REGEXES[licenseName]) {
|
3594 | if (license.search(regex) >= 0) {
|
3595 | return `${licenseName}*`;
|
3596 | }
|
3597 | }
|
3598 | }
|
3599 |
|
3600 | return null;
|
3601 | }
|
3602 |
|
3603 | const LICENSE_RENAMES = {
|
3604 | 'MIT/X11': 'MIT',
|
3605 | X11: 'MIT'
|
3606 | };
|
3607 | var fix = (async function (info, moduleLoc, reporter, warn) {
|
3608 | const files = await readdir(moduleLoc);
|
3609 |
|
3610 | if (typeof info.version === 'string') {
|
3611 | info.version = semver.clean(info.version) || info.version;
|
3612 | }
|
3613 |
|
3614 |
|
3615 | info.name = info.name || '';
|
3616 | info.version = info.version || '';
|
3617 |
|
3618 | if (typeof info.man === 'string') {
|
3619 | info.man = [info.man];
|
3620 | }
|
3621 |
|
3622 |
|
3623 | if (typeof info.keywords === 'string') {
|
3624 | info.keywords = info.keywords.split(/\s+/g);
|
3625 | }
|
3626 |
|
3627 |
|
3628 | if (!info.contributors && files.indexOf('AUTHORS') >= 0) {
|
3629 | const authorsFilepath = path.join(moduleLoc, 'AUTHORS');
|
3630 | const authorsFilestats = await stat(authorsFilepath);
|
3631 |
|
3632 | if (authorsFilestats.isFile()) {
|
3633 | let authors = await readFile(authorsFilepath);
|
3634 | info.contributors = authors.split(/\r?\n/g)
|
3635 | .map(line => line.replace(/^\s*#.*$/, '').trim())
|
3636 | .filter(line => !!line);
|
3637 | }
|
3638 | }
|
3639 |
|
3640 |
|
3641 | if (typeof info.author === 'string' || typeof info.author === 'object') {
|
3642 | info.author = normalizePerson(info.author);
|
3643 | }
|
3644 |
|
3645 | if (Array.isArray(info.contributors)) {
|
3646 | info.contributors = info.contributors.map(normalizePerson);
|
3647 | }
|
3648 |
|
3649 | if (Array.isArray(info.maintainers)) {
|
3650 | info.maintainers = info.maintainers.map(normalizePerson);
|
3651 | }
|
3652 |
|
3653 |
|
3654 | if (!info.readme) {
|
3655 | const readmeCandidates = files.filter(filename => {
|
3656 | const lower = filename.toLowerCase();
|
3657 | return lower === 'readme' || lower.indexOf('readme.') === 0;
|
3658 | }).sort((filename1, filename2) => {
|
3659 |
|
3660 | return filename2.indexOf('.') - filename1.indexOf('.');
|
3661 | });
|
3662 |
|
3663 | for (const readmeFilename of readmeCandidates) {
|
3664 | const readmeFilepath = path.join(moduleLoc, readmeFilename);
|
3665 | const readmeFileStats = await stat(readmeFilepath);
|
3666 |
|
3667 | if (readmeFileStats.isFile()) {
|
3668 | info.readmeFilename = readmeFilename;
|
3669 | info.readme = await readFile(readmeFilepath);
|
3670 | break;
|
3671 | }
|
3672 | }
|
3673 | }
|
3674 |
|
3675 |
|
3676 | if (!info.description && info.readme) {
|
3677 | const desc = extractDescription(info.readme);
|
3678 |
|
3679 | if (desc) {
|
3680 | info.description = desc;
|
3681 | }
|
3682 | }
|
3683 |
|
3684 |
|
3685 | if (Array.isArray(info.engines)) {
|
3686 | const engines = {};
|
3687 |
|
3688 | for (const str of info.engines) {
|
3689 | if (typeof str === 'string') {
|
3690 | const [name, ...patternParts] = str.trim().split(/ +/g);
|
3691 | engines[name] = patternParts.join(' ');
|
3692 | }
|
3693 | }
|
3694 |
|
3695 | info.engines = engines;
|
3696 | }
|
3697 |
|
3698 |
|
3699 | if (typeof info.bugs === 'string') {
|
3700 | info.bugs = {
|
3701 | url: info.bugs
|
3702 | };
|
3703 | }
|
3704 |
|
3705 |
|
3706 | if (typeof info.homepage === 'string') {
|
3707 | const parts = nodeUrl.parse(info.homepage);
|
3708 | parts.protocol = parts.protocol || 'http:';
|
3709 |
|
3710 | if (parts.pathname && !parts.hostname) {
|
3711 | parts.hostname = parts.pathname;
|
3712 | parts.pathname = '';
|
3713 | }
|
3714 |
|
3715 | info.homepage = nodeUrl.format(parts);
|
3716 | }
|
3717 |
|
3718 |
|
3719 |
|
3720 |
|
3721 | if (typeof info.name === 'string' && typeof info.bin === 'string' && info.bin.length > 0) {
|
3722 |
|
3723 | const name = info.name.replace(/^@[^\/]+\//, '');
|
3724 | info.bin = {
|
3725 | [name]: info.bin
|
3726 | };
|
3727 | }
|
3728 |
|
3729 |
|
3730 | if (info.bundledDependencies) {
|
3731 | info.bundleDependencies = info.bundledDependencies;
|
3732 | delete info.bundledDependencies;
|
3733 | }
|
3734 |
|
3735 | let scripts;
|
3736 |
|
3737 | if (info.scripts && typeof info.scripts === 'object') {
|
3738 | scripts = info.scripts;
|
3739 | } else {
|
3740 | scripts = {};
|
3741 | }
|
3742 |
|
3743 |
|
3744 | if (!scripts.start && files.indexOf('server.js') >= 0) {
|
3745 | scripts.start = 'node server';
|
3746 | }
|
3747 |
|
3748 |
|
3749 | if (!scripts.install && files.indexOf('binding.gyp') >= 0) {
|
3750 | scripts.install = 'node-gyp rebuild';
|
3751 | }
|
3752 |
|
3753 |
|
3754 | if (Object.keys(scripts).length) {
|
3755 | info.scripts = scripts;
|
3756 | }
|
3757 |
|
3758 | const dirs = info.directories;
|
3759 |
|
3760 | if (dirs && typeof dirs === 'object') {
|
3761 | const binDir = dirs.bin;
|
3762 |
|
3763 | if (!info.bin && binDir && typeof binDir === 'string') {
|
3764 | const bin = info.bin = {};
|
3765 | const fullBinDir = path.join(moduleLoc, binDir);
|
3766 |
|
3767 | if (await exists(fullBinDir)) {
|
3768 | for (const scriptName of await readdir(fullBinDir)) {
|
3769 | if (scriptName[0] === '.') {
|
3770 | continue;
|
3771 | }
|
3772 |
|
3773 | bin[scriptName] = path.join('.', binDir, scriptName);
|
3774 | }
|
3775 | } else {
|
3776 | warn(reporter.lang('manifestDirectoryNotFound', binDir, info.name));
|
3777 | }
|
3778 | }
|
3779 |
|
3780 | const manDir = dirs.man;
|
3781 |
|
3782 | if (!info.man && typeof manDir === 'string') {
|
3783 | const man = info.man = [];
|
3784 | const fullManDir = path.join(moduleLoc, manDir);
|
3785 |
|
3786 | if (await exists(fullManDir)) {
|
3787 | for (const filename of await readdir(fullManDir)) {
|
3788 | if (/^(.*?)\.[0-9]$/.test(filename)) {
|
3789 | man.push(path.join('.', manDir, filename));
|
3790 | }
|
3791 | }
|
3792 | } else {
|
3793 | warn(reporter.lang('manifestDirectoryNotFound', manDir, info.name));
|
3794 | }
|
3795 | }
|
3796 | }
|
3797 |
|
3798 | delete info.directories;
|
3799 |
|
3800 | const licenses = info.licenses;
|
3801 |
|
3802 | if (Array.isArray(licenses) && !info.license) {
|
3803 | let licenseTypes = [];
|
3804 |
|
3805 | for (let license of licenses) {
|
3806 | if (license && typeof license === 'object') {
|
3807 | license = license.type;
|
3808 | }
|
3809 |
|
3810 | if (typeof license === 'string') {
|
3811 | licenseTypes.push(license);
|
3812 | }
|
3813 | }
|
3814 |
|
3815 | licenseTypes = licenseTypes.filter(isValidLicense);
|
3816 |
|
3817 | if (licenseTypes.length === 1) {
|
3818 | info.license = licenseTypes[0];
|
3819 | } else if (licenseTypes.length) {
|
3820 | info.license = `(${licenseTypes.join(' OR ')})`;
|
3821 | }
|
3822 | }
|
3823 |
|
3824 | const license = info.license;
|
3825 |
|
3826 | if (license && typeof license === 'object') {
|
3827 | info.license = license.type;
|
3828 | }
|
3829 |
|
3830 |
|
3831 | const licenseFile = files.find(filename => {
|
3832 | const lower = filename.toLowerCase();
|
3833 | return lower === 'license' || lower.startsWith('license.') || lower === 'unlicense' || lower.startsWith('unlicense.');
|
3834 | });
|
3835 |
|
3836 | if (licenseFile) {
|
3837 | const licenseFilepath = path.join(moduleLoc, licenseFile);
|
3838 | const licenseFileStats = await stat(licenseFilepath);
|
3839 |
|
3840 | if (licenseFileStats.isFile()) {
|
3841 | const licenseContent = await readFile(licenseFilepath);
|
3842 | const inferredLicense = inferLicense(licenseContent);
|
3843 | info.licenseText = licenseContent;
|
3844 | const license = info.license;
|
3845 |
|
3846 | if (typeof license === 'string') {
|
3847 | if (inferredLicense && isValidLicense(inferredLicense) && !isValidLicense(license)) {
|
3848 |
|
3849 | const basicLicense = license.toLowerCase().replace(/(-like|\*)$/g, '');
|
3850 | const expandedLicense = inferredLicense.toLowerCase();
|
3851 |
|
3852 | if (expandedLicense.startsWith(basicLicense)) {
|
3853 |
|
3854 | info.license = inferredLicense;
|
3855 | }
|
3856 | }
|
3857 | } else if (inferredLicense) {
|
3858 |
|
3859 | info.license = inferredLicense;
|
3860 | } else {
|
3861 |
|
3862 | info.license = `SEE LICENSE IN ${licenseFile}`;
|
3863 | }
|
3864 | }
|
3865 | }
|
3866 |
|
3867 | if (typeof info.license === 'string') {
|
3868 |
|
3869 | info.license = LICENSE_RENAMES[info.license] || info.license;
|
3870 | } else if (typeof info.readme === 'string') {
|
3871 |
|
3872 | const inferredLicense = inferLicense(info.readme);
|
3873 |
|
3874 | if (inferredLicense) {
|
3875 | info.license = inferredLicense;
|
3876 | }
|
3877 | }
|
3878 |
|
3879 |
|
3880 | const noticeFile = files.find(filename => {
|
3881 | const lower = filename.toLowerCase();
|
3882 | return lower === 'notice' || lower.startsWith('notice.');
|
3883 | });
|
3884 |
|
3885 | if (noticeFile) {
|
3886 | const noticeFilepath = path.join(moduleLoc, noticeFile);
|
3887 | const noticeFileStats = await stat(noticeFilepath);
|
3888 |
|
3889 | if (noticeFileStats.isFile()) {
|
3890 | info.noticeText = await readFile(noticeFilepath);
|
3891 | }
|
3892 | }
|
3893 |
|
3894 | for (const dependencyType of MANIFEST_FIELDS) {
|
3895 | const dependencyList = info[dependencyType];
|
3896 |
|
3897 | if (dependencyList && typeof dependencyList === 'object') {
|
3898 | delete dependencyList['//'];
|
3899 |
|
3900 | for (const name in dependencyList) {
|
3901 | dependencyList[name] = dependencyList[name] || '';
|
3902 | }
|
3903 | }
|
3904 | }
|
3905 | });
|
3906 |
|
3907 | var normalizeManifest = (async function (info, moduleLoc, config, isRoot) {
|
3908 |
|
3909 |
|
3910 |
|
3911 |
|
3912 |
|
3913 |
|
3914 | const {
|
3915 | name,
|
3916 | version
|
3917 | } = info;
|
3918 | let human;
|
3919 |
|
3920 | if (typeof name === 'string') {
|
3921 | human = name;
|
3922 | }
|
3923 |
|
3924 | if (human && typeof version === 'string' && version) {
|
3925 | human += `@${version}`;
|
3926 | }
|
3927 |
|
3928 | if (isRoot && info._loc) {
|
3929 | human = path.relative(config.cwd, info._loc);
|
3930 | }
|
3931 |
|
3932 | function warn(msg) {
|
3933 | if (human) {
|
3934 | msg = `${human}: ${msg}`;
|
3935 | }
|
3936 |
|
3937 | config.reporter.warn(msg);
|
3938 | }
|
3939 |
|
3940 | await fix(info, moduleLoc, config.reporter, warn);
|
3941 |
|
3942 | try {
|
3943 | validate(info, isRoot, config.reporter, warn);
|
3944 | } catch (err) {
|
3945 | if (human) {
|
3946 | err.message = `${human}: ${err.message}`;
|
3947 | }
|
3948 |
|
3949 | throw err;
|
3950 | }
|
3951 |
|
3952 | return info;
|
3953 | });
|
3954 |
|
3955 | class Config {
|
3956 | constructor(reporter, cwd, flags) {
|
3957 | this.reporter = reporter;
|
3958 |
|
3959 | this.cwd = path.resolve(cwd || process.cwd());
|
3960 | this.flags = flags;
|
3961 | }
|
3962 |
|
3963 | async loadPackageManifest() {
|
3964 | const loc = path.join(this.cwd, NODE_PACKAGE_JSON);
|
3965 |
|
3966 | if (await exists(loc)) {
|
3967 | const info = await this.readJson(loc, readJsonAndFile);
|
3968 | this._manifest = _objectSpread({}, info.object);
|
3969 | this.manifestIndent = detectIndent(info.content).indent || undefined;
|
3970 | this.manifest = await normalizeManifest(info.object, this.cwd, this, true);
|
3971 | return this.manifest;
|
3972 | } else {
|
3973 | return null;
|
3974 | }
|
3975 | }
|
3976 |
|
3977 | readJson(loc, factory = readJson) {
|
3978 | try {
|
3979 | return factory(loc);
|
3980 | } catch (err) {
|
3981 | if (err instanceof SyntaxError) {
|
3982 | throw new types.MessageError(this.reporter.lang('jsonError', loc, err.message));
|
3983 | } else {
|
3984 | throw err;
|
3985 | }
|
3986 | }
|
3987 | }
|
3988 |
|
3989 | async savePackageManifest(newManifestData) {
|
3990 | const loc = path.join(this.cwd, NODE_PACKAGE_JSON);
|
3991 |
|
3992 | const manifest = _objectSpread({}, this._manifest, newManifestData);
|
3993 |
|
3994 | await writeFilePreservingEol(loc, JSON.stringify(manifest, null, this.manifestIndent || DEFAULT_INDENT) + '\n');
|
3995 | return this.loadPackageManifest();
|
3996 | }
|
3997 |
|
3998 | async getDistributions() {
|
3999 | const raw = this.manifest[`@pika/pack`] || {};
|
4000 | const override = this.flags.pipeline && JSON.parse(this.flags.pipeline);
|
4001 | const cwd = this.cwd;
|
4002 |
|
4003 | function cleanRawDistObject(rawVal) {
|
4004 | if (Array.isArray(rawVal)) {
|
4005 | let importStr = rawVal[0].startsWith('./') || rawVal[0].startsWith('../') ? path.join(cwd, rawVal[0]) : rawVal[0];
|
4006 | return [_objectSpread({}, importFrom(cwd, importStr), {
|
4007 | name: rawVal[0]
|
4008 | }), rawVal[1] || {}];
|
4009 | }
|
4010 |
|
4011 | if (typeof rawVal === 'string') {
|
4012 | return [{
|
4013 | build: ({
|
4014 | cwd
|
4015 | }) => {
|
4016 | return executeLifecycleScript({
|
4017 |
|
4018 | args: [],
|
4019 | cwd,
|
4020 | cmd: rawVal,
|
4021 | isInteractive: false
|
4022 | });
|
4023 | }
|
4024 | }, {}];
|
4025 | }
|
4026 |
|
4027 | if (!rawVal) {
|
4028 | throw new Error('Cannot be false');
|
4029 | }
|
4030 |
|
4031 | return false;
|
4032 | }
|
4033 |
|
4034 | const pipeline = override || raw.pipeline || [];
|
4035 | return pipeline.map(cleanRawDistObject).filter(Boolean);
|
4036 | }
|
4037 |
|
4038 | }
|
4039 |
|
4040 | function forwardSignalAndExit(signal) {
|
4041 | forwardSignalToSpawnedProcesses(signal);
|
4042 |
|
4043 |
|
4044 | process.exit(1);
|
4045 | }
|
4046 |
|
4047 | function handleSignals() {
|
4048 | process.on('SIGTERM', () => {
|
4049 | forwardSignalAndExit('SIGTERM');
|
4050 | });
|
4051 | }
|
4052 |
|
4053 | const FALSY_STRINGS = new Set(['0', 'false']);
|
4054 | function boolify(val) {
|
4055 | return !FALSY_STRINGS.has(val.toString().toLowerCase());
|
4056 | }
|
4057 | function boolifyWithDefault(val, defaultResult) {
|
4058 | return val === '' || val === null || val === undefined ? defaultResult : boolify(val);
|
4059 | }
|
4060 |
|
4061 | const commander = new commander$1.Command();
|
4062 |
|
4063 | const currentFilename = uri2path((typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('index.js', document.baseURI).href)));
|
4064 |
|
4065 | function getVersion() {
|
4066 | const packageJsonContent = fs.readFileSync(path.resolve(currentFilename, '../../package.json'), {
|
4067 | encoding: 'utf-8'
|
4068 | });
|
4069 | const {
|
4070 | version
|
4071 | } = nullify(JSON.parse(stripBOM(packageJsonContent)));
|
4072 | return version;
|
4073 | }
|
4074 |
|
4075 | function findProjectRoot(base) {
|
4076 | let prev = null;
|
4077 | let dir = base;
|
4078 |
|
4079 | do {
|
4080 | if (fs.existsSync(path.join(dir, NODE_PACKAGE_JSON))) {
|
4081 | return dir;
|
4082 | }
|
4083 |
|
4084 | prev = dir;
|
4085 | dir = path.dirname(dir);
|
4086 | } while (dir !== prev);
|
4087 |
|
4088 | return base;
|
4089 | }
|
4090 |
|
4091 | async function main({
|
4092 | startArgs,
|
4093 | args,
|
4094 | endArgs
|
4095 | }) {
|
4096 | const version = getVersion();
|
4097 | loudRejection();
|
4098 | handleSignals();
|
4099 |
|
4100 | commander.version(version, '-v, --version');
|
4101 | commander.usage('[command] [flags]');
|
4102 | commander.option('--verbose', 'output verbose messages on internal operations');
|
4103 | commander.option('--json', 'format Pika log messages as lines of JSON (see jsonlines.org)');
|
4104 |
|
4105 |
|
4106 | commander.option('--emoji [bool]', 'enable emoji in output', boolify, process.platform === 'darwin' || process.env.TERM_PROGRAM === 'Hyper' || process.env.TERM_PROGRAM === 'HyperTerm');
|
4107 | commander.option('-s, --silent', 'skip Pika console logs, other types of logs (script output) will be printed');
|
4108 | commander.option('--cwd <cwd>', 'working directory to use', process.cwd());
|
4109 | commander.option('--no-progress', 'disable progress bar');
|
4110 | commander.option('--no-node-version-check', 'do not warn when using a potentially unsupported Node version');
|
4111 | commander.option('--pipeline <pipeline>', 'the build pipeline to run');
|
4112 |
|
4113 | if (args[0] === '-v') {
|
4114 | console.log(version.trim());
|
4115 | process.exitCode = 0;
|
4116 | return;
|
4117 | }
|
4118 |
|
4119 |
|
4120 | const firstNonFlagIndex = args.findIndex((arg, idx, arr) => {
|
4121 | const isOption = arg.startsWith('-');
|
4122 | const prev = idx > 0 && arr[idx - 1];
|
4123 | const prevOption = prev && prev.startsWith('-') && commander.optionFor(prev);
|
4124 | const boundToPrevOption = prevOption && (prevOption.optional || prevOption.required);
|
4125 | return !isOption && !boundToPrevOption;
|
4126 | });
|
4127 | let preCommandArgs;
|
4128 | let commandName = '';
|
4129 |
|
4130 | if (firstNonFlagIndex > -1) {
|
4131 | preCommandArgs = args.slice(0, firstNonFlagIndex);
|
4132 | commandName = args[firstNonFlagIndex];
|
4133 | args = args.slice(firstNonFlagIndex + 1);
|
4134 | } else {
|
4135 | preCommandArgs = args;
|
4136 | args = [];
|
4137 | }
|
4138 |
|
4139 | let isKnownCommand = Object.prototype.hasOwnProperty.call(commands, commandName);
|
4140 |
|
4141 | const isHelp = arg => arg === '--help' || arg === '-h';
|
4142 |
|
4143 | const helpInPre = preCommandArgs.findIndex(isHelp);
|
4144 | const helpInArgs = args.findIndex(isHelp);
|
4145 |
|
4146 | const setHelpMode = () => {
|
4147 | if (isKnownCommand) {
|
4148 | args.unshift(commandName);
|
4149 | }
|
4150 |
|
4151 | commandName = 'help';
|
4152 | isKnownCommand = true;
|
4153 | };
|
4154 |
|
4155 | if (helpInPre > -1) {
|
4156 | preCommandArgs.splice(helpInPre);
|
4157 | setHelpMode();
|
4158 | } else if (isKnownCommand && helpInArgs === 0) {
|
4159 | args.splice(helpInArgs);
|
4160 | setHelpMode();
|
4161 | }
|
4162 |
|
4163 | if (!commandName) {
|
4164 | commandName = 'help';
|
4165 | isKnownCommand = true;
|
4166 | }
|
4167 |
|
4168 | if (!isKnownCommand) {
|
4169 |
|
4170 | args.unshift(commandName);
|
4171 | commandName = 'help';
|
4172 | }
|
4173 |
|
4174 | const command = commandName === 'help' ? helpCommand : commands[commandName];
|
4175 | commander.originalArgs = args;
|
4176 | args = [...preCommandArgs, ...args];
|
4177 | command.setFlags(commander);
|
4178 | commander.parse([...startArgs,
|
4179 |
|
4180 | 'this-arg-will-get-stripped-later', ...args]);
|
4181 | commander.args = commander.args.concat(endArgs.slice(1));
|
4182 |
|
4183 | console.assert(commander.args.length >= 1);
|
4184 | console.assert(commander.args[0] === 'this-arg-will-get-stripped-later');
|
4185 | commander.args.shift();
|
4186 |
|
4187 | const Reporter = commander.json ? JSONReporter : ConsoleReporter;
|
4188 | const reporter = new Reporter({
|
4189 | emoji: process.stdout.isTTY && commander.emoji,
|
4190 | verbose: commander.verbose,
|
4191 | noProgress: !commander.progress,
|
4192 | isSilent: boolifyWithDefault(process.env.PIKA_SILENT, false) || commander.silent,
|
4193 | nonInteractive: commander.nonInteractive
|
4194 | });
|
4195 |
|
4196 | const exit = (exitCode = 0) => {
|
4197 | if (exitCode === 0) {
|
4198 | clearErrorReport();
|
4199 | }
|
4200 |
|
4201 | process.exitCode = exitCode;
|
4202 | reporter.close();
|
4203 | };
|
4204 |
|
4205 | reporter.initPeakMemoryCounter();
|
4206 | const outputWrapperEnabled = boolifyWithDefault(process.env.PIKA_WRAP_OUTPUT, true);
|
4207 | const shouldWrapOutput = outputWrapperEnabled && !commander.json && command.hasWrapper(commander, commander.args);
|
4208 |
|
4209 | reporter.header(commandName, {
|
4210 | name: '@pika/pack',
|
4211 | version
|
4212 | });
|
4213 |
|
4214 | if (commander.nodeVersionCheck && !semver.satisfies(process.versions.node, SUPPORTED_NODE_VERSIONS)) {
|
4215 | reporter.warn(reporter.lang('unsupportedNodeVersion', process.versions.node, SUPPORTED_NODE_VERSIONS));
|
4216 | }
|
4217 |
|
4218 | if (command.noArguments && commander.args.length) {
|
4219 | reporter.error(reporter.lang('noArguments'));
|
4220 |
|
4221 | exit(1);
|
4222 | return;
|
4223 | }
|
4224 |
|
4225 |
|
4226 |
|
4227 |
|
4228 |
|
4229 |
|
4230 | const run = () => {
|
4231 | invariant(command, 'missing command');
|
4232 |
|
4233 |
|
4234 |
|
4235 | return command.run(config, reporter, commander, commander.args).then(exitCode => {
|
4236 | if (shouldWrapOutput) {
|
4237 | reporter.footer(false);
|
4238 | }
|
4239 |
|
4240 | return exitCode;
|
4241 | });
|
4242 | };
|
4243 |
|
4244 | function onUnexpectedError(err) {
|
4245 | function indent(str) {
|
4246 | return '\n ' + str.trim().split('\n').join('\n ');
|
4247 | }
|
4248 |
|
4249 | const log = [];
|
4250 | log.push(`Arguments: ${indent(process.argv.join(' '))}`);
|
4251 | log.push(`PATH: ${indent(process.env.PATH || 'undefined')}`);
|
4252 | log.push(`Pika version: ${indent(version)}`);
|
4253 | log.push(`Node version: ${indent(process.versions.node)}`);
|
4254 | log.push(`Platform: ${indent(process.platform + ' ' + process.arch)}`);
|
4255 | log.push(`Trace: ${indent(err.stack)}`);
|
4256 | const errorReportLoc = writeErrorReport(log);
|
4257 | reporter.error(reporter.lang('unexpectedError', err.message));
|
4258 |
|
4259 | if (errorReportLoc) {
|
4260 | reporter.info(reporter.lang('bugReport', errorReportLoc));
|
4261 | }
|
4262 | }
|
4263 |
|
4264 | function writeErrorReport(log) {
|
4265 | const errorReportLoc = path.join(config.cwd, 'pika-error.log');
|
4266 |
|
4267 | try {
|
4268 | fs.writeFileSync(errorReportLoc, log.join('\n\n') + '\n');
|
4269 | } catch (err) {
|
4270 | reporter.error(reporter.lang('fileWriteError', errorReportLoc, err.message));
|
4271 | return undefined;
|
4272 | }
|
4273 |
|
4274 | return errorReportLoc;
|
4275 | }
|
4276 |
|
4277 | function clearErrorReport() {
|
4278 | const errorReportLoc = path.join(config.cwd, 'pika-error.log');
|
4279 |
|
4280 | if (fs.existsSync(errorReportLoc)) {
|
4281 | try {
|
4282 | fs.unlinkSync(errorReportLoc);
|
4283 | } catch (err) {
|
4284 | reporter.error(reporter.lang('fileDeleteError', errorReportLoc, err.message));
|
4285 | return undefined;
|
4286 | }
|
4287 | }
|
4288 |
|
4289 | return errorReportLoc;
|
4290 | }
|
4291 |
|
4292 | const cwd = command.shouldRunInCurrentCwd ? commander.cwd : findProjectRoot(commander.cwd);
|
4293 | const config = new Config(reporter, cwd, commander);
|
4294 | await config.loadPackageManifest();
|
4295 |
|
4296 | try {
|
4297 |
|
4298 | const noProgressConfig = false;
|
4299 |
|
4300 | if (noProgressConfig) {
|
4301 | reporter.disableProgress();
|
4302 | }
|
4303 |
|
4304 |
|
4305 | reporter.verbose(`current time: ${new Date().toISOString()}`);
|
4306 | return run().then(exit);
|
4307 | } catch (err) {
|
4308 | reporter.verbose(err.stack);
|
4309 |
|
4310 | if (err instanceof types.MessageError) {
|
4311 | reporter.error(err.message);
|
4312 | } else {
|
4313 | onUnexpectedError(err);
|
4314 | }
|
4315 |
|
4316 |
|
4317 |
|
4318 |
|
4319 | return exit(1);
|
4320 | }
|
4321 | }
|
4322 |
|
4323 | async function start() {
|
4324 |
|
4325 | const doubleDashIndex = process.argv.findIndex(element => element === '--');
|
4326 | const startArgs = process.argv.slice(0, 2);
|
4327 | const args = process.argv.slice(2, doubleDashIndex === -1 ? process.argv.length : doubleDashIndex);
|
4328 | const endArgs = doubleDashIndex === -1 ? [] : process.argv.slice(doubleDashIndex);
|
4329 | await main({
|
4330 | startArgs,
|
4331 | args,
|
4332 | endArgs
|
4333 | });
|
4334 | }
|
4335 |
|
4336 | const autoRun = false;
|
4337 |
|
4338 | exports.autoRun = autoRun;
|
4339 | exports.default = start;
|
4340 | exports.main = main;
|