mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-09-17 14:07:34 +03:00
Merge branch 'master' into add-markdown-tree-sitter-grammar
This commit is contained in:
commit
e293df1ab1
@ -1,6 +1,6 @@
|
||||
env:
|
||||
PYTHON_VERSION: 3.10
|
||||
GITHUB_TOKEN: ENCRYPTED[13da504dc34d1608564d891fb7f456b546019d07d1abb059f9ab4296c56ccc0e6e32c7b313629776eda40ab74a54e95c]
|
||||
GITHUB_TOKEN: ENCRYPTED[!b0ff4671044672be50914a3a10b49af642bd8e0e681a6f4e5855ec5230a5cf9afbc53d9e90239b8d2c79455f014f383f!]
|
||||
# The above token, is a GitHub API Token, that allows us to download RipGrep without concern of API limits
|
||||
|
||||
linux_task:
|
||||
|
1
.github/workflows/package-tests-linux.yml
vendored
1
.github/workflows/package-tests-linux.yml
vendored
@ -104,6 +104,7 @@ jobs:
|
||||
- package: "notifications"
|
||||
- package: "open-on-github"
|
||||
- package: "package-generator"
|
||||
- package: "pulsar-updater"
|
||||
- package: "settings-view"
|
||||
- package: "snippets"
|
||||
- package: "spell-check"
|
||||
|
@ -145,6 +145,7 @@
|
||||
"postcss": "8.2.13",
|
||||
"postcss-selector-parser": "6.0.4",
|
||||
"property-accessors": "^1.1.3",
|
||||
"pulsar-updater": "file:packages/pulsar-updater",
|
||||
"resolve": "1.18.1",
|
||||
"scandal": "^3.2.0",
|
||||
"scoped-property-store": "^0.17.0",
|
||||
@ -226,6 +227,7 @@
|
||||
"notifications": "file:./packages/notifications",
|
||||
"open-on-github": "file:./packages/open-on-github",
|
||||
"package-generator": "file:./packages/package-generator",
|
||||
"pulsar-updater": "file:./packages/pulsar-updater",
|
||||
"settings-view": "file:./packages/settings-view",
|
||||
"snippets": "1.6.1",
|
||||
"spell-check": "file:./packages/spell-check",
|
||||
|
@ -85,6 +85,7 @@ See [RFC 003](https://github.com/atom/atom/blob/master/docs/rfcs/003-consolidate
|
||||
| **open-on-github** | [`./open-on-github`](./open-on-github) | |
|
||||
| **settings-view** | [`./settings-view`](./settings-view) | |
|
||||
| **package-generator** | [`./package-generator`](./package-generator) | |
|
||||
| **pulsar-updater** | [`./pulsar-updater`](./pulsar-updater) | |
|
||||
| **snippets** | [`pulsar-edit/snippets`][snippets] | |
|
||||
| **solarized-dark-syntax** | [`./solarized-dark-syntax`](./solarized-dark-syntax) | |
|
||||
| **solarized-light-syntax** | [`./solarized-light-syntax`](./solarized-light-syntax) | |
|
||||
|
@ -1,6 +0,0 @@
|
||||
provider = require './provider'
|
||||
|
||||
module.exports =
|
||||
activate: -> provider.load()
|
||||
|
||||
getProvider: -> provider
|
7
packages/autocomplete-atom-api/lib/main.js
Normal file
7
packages/autocomplete-atom-api/lib/main.js
Normal file
@ -0,0 +1,7 @@
|
||||
const provider = require('./provider');
|
||||
|
||||
module.exports = {
|
||||
activate() { return provider.load(); },
|
||||
|
||||
getProvider() { return provider; }
|
||||
};
|
@ -1,97 +0,0 @@
|
||||
fs = require 'fs'
|
||||
path = require 'path'
|
||||
|
||||
CLASSES = require('../completions.json')
|
||||
|
||||
propertyPrefixPattern = /(?:^|\[|\(|,|=|:|\s)\s*(atom\.(?:[a-zA-Z]+\.?){0,2})$/
|
||||
|
||||
module.exports =
|
||||
selector: '.source.coffee, .source.js'
|
||||
filterSuggestions: true
|
||||
|
||||
getSuggestions: ({bufferPosition, editor}) ->
|
||||
return unless @isEditingAnAtomPackageFile(editor)
|
||||
line = editor.getTextInRange([[bufferPosition.row, 0], bufferPosition])
|
||||
@getCompletions(line)
|
||||
|
||||
load: ->
|
||||
@loadCompletions()
|
||||
atom.project.onDidChangePaths => @scanProjectDirectories()
|
||||
@scanProjectDirectories()
|
||||
|
||||
scanProjectDirectories: ->
|
||||
@packageDirectories = []
|
||||
atom.project.getDirectories().forEach (directory) =>
|
||||
return unless directory?
|
||||
@readMetadata directory, (error, metadata) =>
|
||||
if @isAtomPackage(metadata) or @isAtomCore(metadata)
|
||||
@packageDirectories.push(directory)
|
||||
|
||||
readMetadata: (directory, callback) ->
|
||||
fs.readFile path.join(directory.getPath(), 'package.json'), (error, contents) ->
|
||||
unless error?
|
||||
try
|
||||
metadata = JSON.parse(contents)
|
||||
catch parseError
|
||||
error = parseError
|
||||
callback(error, metadata)
|
||||
|
||||
isAtomPackage: (metadata) ->
|
||||
metadata?.engines?.atom?.length > 0
|
||||
|
||||
isAtomCore: (metadata) ->
|
||||
metadata?.name is 'atom'
|
||||
|
||||
isEditingAnAtomPackageFile: (editor) ->
|
||||
editorPath = editor.getPath()
|
||||
if editorPath?
|
||||
parsedPath = path.parse(editorPath)
|
||||
basename = path.basename(parsedPath.dir)
|
||||
if basename is '.atom' or basename is '.pulsar'
|
||||
if parsedPath.base is 'init.coffee' or parsedPath.base is 'init.js'
|
||||
return true
|
||||
for directory in @packageDirectories ? []
|
||||
return true if directory.contains(editorPath)
|
||||
false
|
||||
|
||||
loadCompletions: ->
|
||||
@completions ?= {}
|
||||
@loadProperty('atom', 'AtomEnvironment', CLASSES)
|
||||
|
||||
getCompletions: (line) ->
|
||||
completions = []
|
||||
match = propertyPrefixPattern.exec(line)?[1]
|
||||
return completions unless match
|
||||
|
||||
segments = match.split('.')
|
||||
prefix = segments.pop() ? ''
|
||||
segments = segments.filter (segment) -> segment
|
||||
property = segments[segments.length - 1]
|
||||
propertyCompletions = @completions[property]?.completions ? []
|
||||
for completion in propertyCompletions when not prefix or firstCharsEqual(completion.name, prefix)
|
||||
completions.push(clone(completion))
|
||||
completions
|
||||
|
||||
getPropertyClass: (name) ->
|
||||
atom[name]?.constructor?.name
|
||||
|
||||
loadProperty: (propertyName, className, classes, parent) ->
|
||||
classCompletions = classes[className]
|
||||
return unless classCompletions?
|
||||
|
||||
@completions[propertyName] = completions: []
|
||||
|
||||
for completion in classCompletions
|
||||
@completions[propertyName].completions.push(completion)
|
||||
if completion.type is 'property'
|
||||
propertyClass = @getPropertyClass(completion.name)
|
||||
@loadProperty(completion.name, propertyClass, classes)
|
||||
return
|
||||
|
||||
clone = (obj) ->
|
||||
newObj = {}
|
||||
newObj[k] = v for k, v of obj
|
||||
newObj
|
||||
|
||||
firstCharsEqual = (str1, str2) ->
|
||||
str1[0].toLowerCase() is str2[0].toLowerCase()
|
125
packages/autocomplete-atom-api/lib/provider.js
Normal file
125
packages/autocomplete-atom-api/lib/provider.js
Normal file
@ -0,0 +1,125 @@
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const CLASSES = require('../completions.json');
|
||||
|
||||
const propertyPrefixPattern = /(?:^|\[|\(|,|=|:|\s)\s*(atom\.(?:[a-zA-Z]+\.?){0,2})$/;
|
||||
|
||||
module.exports = {
|
||||
selector: '.source.coffee, .source.js',
|
||||
filterSuggestions: true,
|
||||
|
||||
getSuggestions({bufferPosition, editor}) {
|
||||
if (!this.isEditingAnAtomPackageFile(editor)) { return; }
|
||||
const line = editor.getTextInRange([[bufferPosition.row, 0], bufferPosition]);
|
||||
return this.getCompletions(line);
|
||||
},
|
||||
|
||||
load() {
|
||||
this.loadCompletions();
|
||||
atom.project.onDidChangePaths(() => this.scanProjectDirectories());
|
||||
return this.scanProjectDirectories();
|
||||
},
|
||||
|
||||
scanProjectDirectories() {
|
||||
this.packageDirectories = [];
|
||||
atom.project.getDirectories().forEach(directory => {
|
||||
if (directory == null) { return; }
|
||||
this.readMetadata(directory, (error, metadata) => {
|
||||
if (this.isAtomPackage(metadata) || this.isAtomCore(metadata)) {
|
||||
this.packageDirectories.push(directory);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
readMetadata(directory, callback) {
|
||||
fs.readFile(path.join(directory.getPath(), 'package.json'), function(error, contents) {
|
||||
let metadata;
|
||||
if (error == null) {
|
||||
try {
|
||||
metadata = JSON.parse(contents);
|
||||
} catch (parseError) {
|
||||
error = parseError;
|
||||
}
|
||||
}
|
||||
return callback(error, metadata);
|
||||
});
|
||||
},
|
||||
|
||||
isAtomPackage(metadata) {
|
||||
return metadata?.engines?.atom?.length > 0;
|
||||
},
|
||||
|
||||
isAtomCore(metadata) {
|
||||
return metadata?.name === 'atom';
|
||||
},
|
||||
|
||||
isEditingAnAtomPackageFile(editor) {
|
||||
const editorPath = editor.getPath();
|
||||
if (editorPath != null) {
|
||||
const parsedPath = path.parse(editorPath);
|
||||
const basename = path.basename(parsedPath.dir);
|
||||
if ((basename === '.atom') || (basename === '.pulsar')) {
|
||||
if ((parsedPath.base === 'init.coffee') || (parsedPath.base === 'init.js')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (let directory of (this.packageDirectories != null ? this.packageDirectories : [])) {
|
||||
if (directory.contains(editorPath)) { return true; }
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
loadCompletions() {
|
||||
if (this.completions == null) { this.completions = {}; }
|
||||
return this.loadProperty('atom', 'AtomEnvironment', CLASSES);
|
||||
},
|
||||
|
||||
getCompletions(line) {
|
||||
const completions = [];
|
||||
const match = propertyPrefixPattern.exec(line)?.[1];
|
||||
if (!match) { return completions; }
|
||||
|
||||
let segments = match.split('.');
|
||||
const prefix = segments.pop() ?? '';
|
||||
segments = segments.filter(segment => segment);
|
||||
const property = segments[segments.length - 1];
|
||||
const propertyCompletions = this.completions[property]?.completions != null ? this.completions[property]?.completions : [];
|
||||
for (let completion of propertyCompletions) {
|
||||
if (!prefix || firstCharsEqual(completion.name, prefix)) {
|
||||
completions.push(clone(completion));
|
||||
}
|
||||
}
|
||||
return completions;
|
||||
},
|
||||
|
||||
getPropertyClass(name) {
|
||||
return atom[name]?.constructor?.name;
|
||||
},
|
||||
|
||||
loadProperty(propertyName, className, classes, parent) {
|
||||
const classCompletions = classes[className];
|
||||
if (classCompletions == null) { return; }
|
||||
|
||||
this.completions[propertyName] = {completions: []};
|
||||
|
||||
for (let completion of classCompletions) {
|
||||
this.completions[propertyName].completions.push(completion);
|
||||
if (completion.type === 'property') {
|
||||
const propertyClass = this.getPropertyClass(completion.name);
|
||||
this.loadProperty(completion.name, propertyClass, classes);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const clone = function(obj) {
|
||||
const newObj = {};
|
||||
for (let k in obj) { const v = obj[k]; newObj[k] = v; }
|
||||
return newObj;
|
||||
};
|
||||
|
||||
const firstCharsEqual = (str1, str2) => str1[0].toLowerCase() === str2[0].toLowerCase();
|
@ -1,142 +0,0 @@
|
||||
_ = require 'underscore-plus'
|
||||
|
||||
CharacterPattern = ///
|
||||
[
|
||||
^\s
|
||||
]
|
||||
///
|
||||
|
||||
module.exports =
|
||||
activate: ->
|
||||
@commandDisposable = atom.commands.add 'atom-text-editor',
|
||||
'autoflow:reflow-selection': (event) =>
|
||||
@reflowSelection(event.currentTarget.getModel())
|
||||
|
||||
deactivate: ->
|
||||
@commandDisposable?.dispose()
|
||||
@commandDisposable = null
|
||||
|
||||
reflowSelection: (editor) ->
|
||||
range = editor.getSelectedBufferRange()
|
||||
range = editor.getCurrentParagraphBufferRange() if range.isEmpty()
|
||||
return unless range?
|
||||
|
||||
reflowOptions =
|
||||
wrapColumn: @getPreferredLineLength(editor)
|
||||
tabLength: @getTabLength(editor)
|
||||
reflowedText = @reflow(editor.getTextInRange(range), reflowOptions)
|
||||
editor.getBuffer().setTextInRange(range, reflowedText)
|
||||
|
||||
reflow: (text, {wrapColumn, tabLength}) ->
|
||||
paragraphs = []
|
||||
# Convert all \r\n and \r to \n. The text buffer will normalize them later
|
||||
text = text.replace(/\r\n?/g, '\n')
|
||||
|
||||
leadingVerticalSpace = text.match(/^\s*\n/)
|
||||
if leadingVerticalSpace
|
||||
text = text.substr(leadingVerticalSpace.length)
|
||||
else
|
||||
leadingVerticalSpace = ''
|
||||
|
||||
trailingVerticalSpace = text.match(/\n\s*$/)
|
||||
if trailingVerticalSpace
|
||||
text = text.substr(0, text.length - trailingVerticalSpace.length)
|
||||
else
|
||||
trailingVerticalSpace = ''
|
||||
|
||||
paragraphBlocks = text.split(/\n\s*\n/g)
|
||||
if tabLength
|
||||
tabLengthInSpaces = Array(tabLength + 1).join(' ')
|
||||
else
|
||||
tabLengthInSpaces = ''
|
||||
|
||||
for block in paragraphBlocks
|
||||
blockLines = block.split('\n')
|
||||
|
||||
# For LaTeX tags surrounding the text, we simply ignore them, and
|
||||
# reproduce them verbatim in the wrapped text.
|
||||
beginningLinesToIgnore = []
|
||||
endingLinesToIgnore = []
|
||||
latexTagRegex = /^\s*\\\w+(\[.*\])?\{\w+\}(\[.*\])?\s*$/g # e.g. \begin{verbatim}
|
||||
latexTagStartRegex = /^\s*\\\w+\s*\{\s*$/g # e.g. \item{
|
||||
latexTagEndRegex = /^\s*\}\s*$/g # e.g. }
|
||||
while blockLines.length > 0 and (
|
||||
blockLines[0].match(latexTagRegex) or
|
||||
blockLines[0].match(latexTagStartRegex))
|
||||
beginningLinesToIgnore.push(blockLines[0])
|
||||
blockLines.shift()
|
||||
while blockLines.length > 0 and (
|
||||
blockLines[blockLines.length - 1].match(latexTagRegex) or
|
||||
blockLines[blockLines.length - 1].match(latexTagEndRegex))
|
||||
endingLinesToIgnore.unshift(blockLines[blockLines.length - 1])
|
||||
blockLines.pop()
|
||||
|
||||
# The paragraph might be a LaTeX section with no text, only tags:
|
||||
# \documentclass{article}
|
||||
# In that case, we have nothing to reflow.
|
||||
# Push the tags verbatim and continue to the next paragraph.
|
||||
unless blockLines.length > 0
|
||||
paragraphs.push(block)
|
||||
continue
|
||||
|
||||
# TODO: this could be more language specific. Use the actual comment char.
|
||||
# Remember that `-` has to be the last character in the character class.
|
||||
linePrefix = blockLines[0].match(/^\s*(\/\/|\/\*|;;|#'|\|\|\||--|[#%*>-])?\s*/g)[0]
|
||||
linePrefixTabExpanded = linePrefix
|
||||
if tabLengthInSpaces
|
||||
linePrefixTabExpanded = linePrefix.replace(/\t/g, tabLengthInSpaces)
|
||||
|
||||
if linePrefix
|
||||
escapedLinePrefix = _.escapeRegExp(linePrefix)
|
||||
blockLines = blockLines.map (blockLine) ->
|
||||
blockLine.replace(///^#{escapedLinePrefix}///, '')
|
||||
|
||||
blockLines = blockLines.map (blockLine) ->
|
||||
blockLine.replace(/^\s+/, '')
|
||||
|
||||
lines = []
|
||||
currentLine = []
|
||||
currentLineLength = linePrefixTabExpanded.length
|
||||
|
||||
wrappedLinePrefix = linePrefix
|
||||
.replace(/^(\s*)\/\*/, '$1 ')
|
||||
.replace(/^(\s*)-(?!-)/, '$1 ')
|
||||
|
||||
firstLine = true
|
||||
for segment in @segmentText(blockLines.join(' '))
|
||||
if @wrapSegment(segment, currentLineLength, wrapColumn)
|
||||
|
||||
# Independent of line prefix don't mess with it on the first line
|
||||
if firstLine isnt true
|
||||
# Handle C comments
|
||||
if linePrefix.search(/^\s*\/\*/) isnt -1 or linePrefix.search(/^\s*-(?!-)/) isnt -1
|
||||
linePrefix = wrappedLinePrefix
|
||||
lines.push(linePrefix + currentLine.join(''))
|
||||
currentLine = []
|
||||
currentLineLength = linePrefixTabExpanded.length
|
||||
firstLine = false
|
||||
currentLine.push(segment)
|
||||
currentLineLength += segment.length
|
||||
lines.push(linePrefix + currentLine.join(''))
|
||||
|
||||
wrappedLines = beginningLinesToIgnore.concat(lines.concat(endingLinesToIgnore))
|
||||
paragraphs.push(wrappedLines.join('\n').replace(/\s+\n/g, '\n'))
|
||||
|
||||
return leadingVerticalSpace + paragraphs.join('\n\n') + trailingVerticalSpace
|
||||
|
||||
getTabLength: (editor) ->
|
||||
atom.config.get('editor.tabLength', scope: editor.getRootScopeDescriptor()) ? 2
|
||||
|
||||
getPreferredLineLength: (editor) ->
|
||||
atom.config.get('editor.preferredLineLength', scope: editor.getRootScopeDescriptor())
|
||||
|
||||
wrapSegment: (segment, currentLineLength, wrapColumn) ->
|
||||
CharacterPattern.test(segment) and
|
||||
(currentLineLength + segment.length > wrapColumn) and
|
||||
(currentLineLength > 0 or segment.length < wrapColumn)
|
||||
|
||||
segmentText: (text) ->
|
||||
segments = []
|
||||
re = /[\s]+|[^\s]+/g
|
||||
segments.push(match[0]) while match = re.exec(text)
|
||||
segments
|
165
packages/autoflow/lib/autoflow.js
Normal file
165
packages/autoflow/lib/autoflow.js
Normal file
@ -0,0 +1,165 @@
|
||||
|
||||
const _ = require('underscore-plus');
|
||||
|
||||
const CharacterPattern = new RegExp(/[^\s]/);
|
||||
|
||||
module.exports = {
|
||||
activate() {
|
||||
this.commandDisposable = atom.commands.add('atom-text-editor', {
|
||||
'autoflow:reflow-selection': event => {
|
||||
this.reflowSelection(event.currentTarget.getModel());
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
deactivate() {
|
||||
this.commandDisposable?.dispose();
|
||||
this.commandDisposable = null;
|
||||
},
|
||||
|
||||
reflowSelection(editor) {
|
||||
let range = editor.getSelectedBufferRange();
|
||||
if (range.isEmpty()) { range = editor.getCurrentParagraphBufferRange(); }
|
||||
if (range == null) { return; }
|
||||
|
||||
const reflowOptions = {
|
||||
wrapColumn: this.getPreferredLineLength(editor),
|
||||
tabLength: this.getTabLength(editor)
|
||||
};
|
||||
const reflowedText = this.reflow(editor.getTextInRange(range), reflowOptions);
|
||||
return editor.getBuffer().setTextInRange(range, reflowedText);
|
||||
},
|
||||
|
||||
reflow(text, {wrapColumn, tabLength}) {
|
||||
let tabLengthInSpaces;
|
||||
const paragraphs = [];
|
||||
// Convert all \r\n and \r to \n. The text buffer will normalize them later
|
||||
text = text.replace(/\r\n?/g, '\n');
|
||||
|
||||
let leadingVerticalSpace = text.match(/^\s*\n/);
|
||||
if (leadingVerticalSpace) {
|
||||
text = text.substr(leadingVerticalSpace.length);
|
||||
} else {
|
||||
leadingVerticalSpace = '';
|
||||
}
|
||||
|
||||
let trailingVerticalSpace = text.match(/\n\s*$/);
|
||||
if (trailingVerticalSpace) {
|
||||
text = text.substr(0, text.length - trailingVerticalSpace.length);
|
||||
} else {
|
||||
trailingVerticalSpace = '';
|
||||
}
|
||||
|
||||
const paragraphBlocks = text.split(/\n\s*\n/g);
|
||||
if (tabLength) {
|
||||
tabLengthInSpaces = Array(tabLength + 1).join(' ');
|
||||
} else {
|
||||
tabLengthInSpaces = '';
|
||||
}
|
||||
|
||||
for (let block of paragraphBlocks) {
|
||||
let blockLines = block.split('\n');
|
||||
|
||||
// For LaTeX tags surrounding the text, we simply ignore them, and
|
||||
// reproduce them verbatim in the wrapped text.
|
||||
const beginningLinesToIgnore = [];
|
||||
const endingLinesToIgnore = [];
|
||||
const latexTagRegex = /^\s*\\\w+(\[.*\])?\{\w+\}(\[.*\])?\s*$/g; // e.g. \begin{verbatim}
|
||||
const latexTagStartRegex = /^\s*\\\w+\s*\{\s*$/g; // e.g. \item{
|
||||
const latexTagEndRegex = /^\s*\}\s*$/g; // e.g. }
|
||||
while ((blockLines.length > 0) && (
|
||||
blockLines[0].match(latexTagRegex) ||
|
||||
blockLines[0].match(latexTagStartRegex))) {
|
||||
beginningLinesToIgnore.push(blockLines[0]);
|
||||
blockLines.shift();
|
||||
}
|
||||
while ((blockLines.length > 0) && (
|
||||
blockLines[blockLines.length - 1].match(latexTagRegex) ||
|
||||
blockLines[blockLines.length - 1].match(latexTagEndRegex))) {
|
||||
endingLinesToIgnore.unshift(blockLines[blockLines.length - 1]);
|
||||
blockLines.pop();
|
||||
}
|
||||
|
||||
// The paragraph might be a LaTeX section with no text, only tags:
|
||||
// \documentclass{article}
|
||||
// In that case, we have nothing to reflow.
|
||||
// Push the tags verbatim and continue to the next paragraph.
|
||||
if (!(blockLines.length > 0)) {
|
||||
paragraphs.push(block);
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO: this could be more language specific. Use the actual comment char.
|
||||
// Remember that `-` has to be the last character in the character class.
|
||||
let linePrefix = blockLines[0].match(/^\s*(\/\/|\/\*|;;|#'|\|\|\||--|[#%*>-])?\s*/g)[0];
|
||||
let linePrefixTabExpanded = linePrefix;
|
||||
if (tabLengthInSpaces) {
|
||||
linePrefixTabExpanded = linePrefix.replace(/\t/g, tabLengthInSpaces);
|
||||
}
|
||||
|
||||
if (linePrefix) {
|
||||
var escapedLinePrefix = _.escapeRegExp(linePrefix);
|
||||
blockLines = blockLines.map(blockLine => blockLine.replace(new RegExp(`^${escapedLinePrefix}`), ''));
|
||||
}
|
||||
|
||||
blockLines = blockLines.map(blockLine => blockLine.replace(/^\s+/, ''));
|
||||
|
||||
const lines = [];
|
||||
let currentLine = [];
|
||||
let currentLineLength = linePrefixTabExpanded.length;
|
||||
|
||||
const wrappedLinePrefix = linePrefix
|
||||
.replace(/^(\s*)\/\*/, '$1 ')
|
||||
.replace(/^(\s*)-(?!-)/, '$1 ');
|
||||
|
||||
let firstLine = true;
|
||||
for (let segment of this.segmentText(blockLines.join(' '))) {
|
||||
if (this.wrapSegment(segment, currentLineLength, wrapColumn)) {
|
||||
|
||||
// Independent of line prefix don't mess with it on the first line
|
||||
if (firstLine !== true) {
|
||||
// Handle C comments
|
||||
if ((linePrefix.search(/^\s*\/\*/) !== -1) || (linePrefix.search(/^\s*-(?!-)/) !== -1)) {
|
||||
linePrefix = wrappedLinePrefix;
|
||||
}
|
||||
}
|
||||
lines.push(linePrefix + currentLine.join(''));
|
||||
currentLine = [];
|
||||
currentLineLength = linePrefixTabExpanded.length;
|
||||
firstLine = false;
|
||||
}
|
||||
currentLine.push(segment);
|
||||
currentLineLength += segment.length;
|
||||
}
|
||||
lines.push(linePrefix + currentLine.join(''));
|
||||
|
||||
const wrappedLines = beginningLinesToIgnore.concat(lines.concat(endingLinesToIgnore));
|
||||
paragraphs.push(wrappedLines.join('\n').replace(/\s+\n/g, '\n'));
|
||||
}
|
||||
|
||||
return leadingVerticalSpace + paragraphs.join('\n\n') + trailingVerticalSpace;
|
||||
},
|
||||
|
||||
getTabLength(editor) {
|
||||
return atom.config.get('editor.tabLength', { scope: editor.getRootScopeDescriptor() }) ?? 2;
|
||||
},
|
||||
|
||||
getPreferredLineLength(editor) {
|
||||
return atom.config.get('editor.preferredLineLength', {scope: editor.getRootScopeDescriptor()});
|
||||
},
|
||||
|
||||
wrapSegment(segment, currentLineLength, wrapColumn) {
|
||||
return CharacterPattern.test(segment) &&
|
||||
((currentLineLength + segment.length) > wrapColumn) &&
|
||||
((currentLineLength > 0) || (segment.length < wrapColumn));
|
||||
},
|
||||
|
||||
segmentText(text) {
|
||||
let match;
|
||||
const segments = [];
|
||||
const re = /[\s]+|[^\s]+/g;
|
||||
while ((match = re.exec(text))) { segments.push(match[0]); }
|
||||
return segments;
|
||||
}
|
||||
};
|
@ -1,68 +0,0 @@
|
||||
{CompositeDisposable, Disposable} = require 'atom'
|
||||
_ = require 'underscore-plus'
|
||||
Grim = require 'grim'
|
||||
|
||||
module.exports =
|
||||
class DeprecationCopStatusBarView
|
||||
lastLength: null
|
||||
toolTipDisposable: null
|
||||
|
||||
constructor: ->
|
||||
@subscriptions = new CompositeDisposable
|
||||
|
||||
@element = document.createElement('div')
|
||||
@element.classList.add('deprecation-cop-status', 'inline-block', 'text-warning')
|
||||
@element.setAttribute('tabindex', -1)
|
||||
|
||||
@icon = document.createElement('span')
|
||||
@icon.classList.add('icon', 'icon-alert')
|
||||
@element.appendChild(@icon)
|
||||
|
||||
@deprecationNumber = document.createElement('span')
|
||||
@deprecationNumber.classList.add('deprecation-number')
|
||||
@deprecationNumber.textContent = '0'
|
||||
@element.appendChild(@deprecationNumber)
|
||||
|
||||
clickHandler = ->
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
atom.commands.dispatch workspaceElement, 'deprecation-cop:view'
|
||||
@element.addEventListener('click', clickHandler)
|
||||
@subscriptions.add(new Disposable(=> @element.removeEventListener('click', clickHandler)))
|
||||
|
||||
@update()
|
||||
|
||||
debouncedUpdateDeprecatedSelectorCount = _.debounce(@update, 1000)
|
||||
|
||||
@subscriptions.add Grim.on 'updated', @update
|
||||
# TODO: Remove conditional when the new StyleManager deprecation APIs reach stable.
|
||||
if atom.styles.onDidUpdateDeprecations?
|
||||
@subscriptions.add(atom.styles.onDidUpdateDeprecations(debouncedUpdateDeprecatedSelectorCount))
|
||||
|
||||
destroy: ->
|
||||
@subscriptions.dispose()
|
||||
@element.remove()
|
||||
|
||||
getDeprecatedCallCount: ->
|
||||
Grim.getDeprecations().map((d) -> d.getStackCount()).reduce(((a, b) -> a + b), 0)
|
||||
|
||||
getDeprecatedStyleSheetsCount: ->
|
||||
# TODO: Remove conditional when the new StyleManager deprecation APIs reach stable.
|
||||
if atom.styles.getDeprecations?
|
||||
Object.keys(atom.styles.getDeprecations()).length
|
||||
else
|
||||
0
|
||||
|
||||
update: =>
|
||||
length = @getDeprecatedCallCount() + @getDeprecatedStyleSheetsCount()
|
||||
|
||||
return if @lastLength is length
|
||||
|
||||
@lastLength = length
|
||||
@deprecationNumber.textContent = "#{_.pluralize(length, 'deprecation')}"
|
||||
@toolTipDisposable?.dispose()
|
||||
@toolTipDisposable = atom.tooltips.add @element, title: "#{_.pluralize(length, 'call')} to deprecated methods"
|
||||
|
||||
if length is 0
|
||||
@element.style.display = 'none'
|
||||
else
|
||||
@element.style.display = ''
|
104
packages/deprecation-cop/lib/deprecation-cop-status-bar-view.js
Normal file
104
packages/deprecation-cop/lib/deprecation-cop-status-bar-view.js
Normal file
@ -0,0 +1,104 @@
|
||||
|
||||
const { CompositeDisposable, Disposable } = require("atom");
|
||||
const _ = require("underscore-plus");
|
||||
const Grim = require("grim");
|
||||
|
||||
module.exports = class DeprecationCopStatusBarView {
|
||||
static lastLength = null;
|
||||
static toolTipDisposable = null;
|
||||
|
||||
constructor() {
|
||||
this.update = this.update.bind(this);
|
||||
this.subscriptions = new CompositeDisposable();
|
||||
|
||||
this.element = document.createElement("div");
|
||||
this.element.classList.add(
|
||||
"deprecation-cop-status",
|
||||
"inline-block",
|
||||
"text-warning"
|
||||
);
|
||||
this.element.setAttribute("tabindex", -1);
|
||||
|
||||
this.icon = document.createElement("span");
|
||||
this.icon.classList.add("icon", "icon-alert");
|
||||
this.element.appendChild(this.icon);
|
||||
|
||||
this.deprecationNumber = document.createElement("span");
|
||||
this.deprecationNumber.classList.add("deprecation-number");
|
||||
this.deprecationNumber.textContent = "0";
|
||||
this.element.appendChild(this.deprecationNumber);
|
||||
|
||||
const clickHandler = function () {
|
||||
const workspaceElement = atom.views.getView(atom.workspace);
|
||||
atom.commands.dispatch(workspaceElement, "deprecation-cop:view");
|
||||
};
|
||||
this.element.addEventListener("click", clickHandler);
|
||||
this.subscriptions.add(
|
||||
new Disposable(() =>
|
||||
this.element.removeEventListener("click", clickHandler)
|
||||
)
|
||||
);
|
||||
|
||||
this.update();
|
||||
|
||||
const debouncedUpdateDeprecatedSelectorCount = _.debounce(
|
||||
this.update,
|
||||
1000
|
||||
);
|
||||
|
||||
this.subscriptions.add(Grim.on("updated", this.update));
|
||||
// TODO: Remove conditional when the new StyleManager deprecation APIs reach stable.
|
||||
if (atom.styles.onDidUpdateDeprecations != null) {
|
||||
this.subscriptions.add(
|
||||
atom.styles.onDidUpdateDeprecations(
|
||||
debouncedUpdateDeprecatedSelectorCount
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.subscriptions.dispose();
|
||||
this.element.remove();
|
||||
}
|
||||
|
||||
getDeprecatedCallCount() {
|
||||
return Grim.getDeprecations()
|
||||
.map((d) => d.getStackCount())
|
||||
.reduce((a, b) => a + b, 0);
|
||||
}
|
||||
|
||||
getDeprecatedStyleSheetsCount() {
|
||||
// TODO: Remove conditional when the new StyleManager deprecation APIs reach stable.
|
||||
if (atom.styles.getDeprecations != null) {
|
||||
return Object.keys(atom.styles.getDeprecations()).length;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
update() {
|
||||
const length =
|
||||
this.getDeprecatedCallCount() + this.getDeprecatedStyleSheetsCount();
|
||||
|
||||
if (this.lastLength === length) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.lastLength = length;
|
||||
this.deprecationNumber.textContent = `${_.pluralize(
|
||||
length,
|
||||
"deprecation"
|
||||
)}`;
|
||||
this.toolTipDisposable?.dispose();
|
||||
this.toolTipDisposable = atom.tooltips.add(this.element, {
|
||||
title: `${_.pluralize(length, "call")} to deprecated methods`,
|
||||
});
|
||||
|
||||
if (length === 0) {
|
||||
return (this.element.style.display = "none");
|
||||
} else {
|
||||
return (this.element.style.display = "");
|
||||
}
|
||||
}
|
||||
};
|
@ -8,6 +8,12 @@ injectionRegex: '^(c|C)$'
|
||||
treeSitter:
|
||||
grammar: 'tree-sitter-c/tree-sitter-c.wasm'
|
||||
highlightsQuery: 'tree-sitter-c/highlights.scm'
|
||||
localsQuery: 'tree-sitter-c/locals.scm'
|
||||
tagsQuery: 'tree-sitter-c/tags.scm'
|
||||
foldsQuery: 'tree-sitter-c/folds.scm'
|
||||
indentsQuery: 'tree-sitter-c/indents.scm'
|
||||
|
||||
fileTypes: [
|
||||
'h'
|
||||
'c'
|
||||
'h.in'
|
||||
]
|
||||
|
@ -3,11 +3,33 @@ scopeName: 'source.cpp'
|
||||
type: 'modern-tree-sitter'
|
||||
parser: 'tree-sitter-cpp'
|
||||
|
||||
injectionRegex: '^(cpp|CPP|cc|CC)$'
|
||||
injectionRegex: '^(c|C)(\\+\\+|pp|PP)$'
|
||||
|
||||
treeSitter:
|
||||
grammar: 'tree-sitter-cpp/tree-sitter-cpp.wasm'
|
||||
highlightsQuery: 'tree-sitter-cpp/highlights.scm'
|
||||
localsQuery: 'tree-sitter-cpp/locals.scm'
|
||||
tagsQuery: 'tree-sitter-cpp/tags.scm'
|
||||
foldsQuery: 'tree-sitter-cpp/folds.scm'
|
||||
indentsQuery: 'tree-sitter-cpp/indents.scm'
|
||||
|
||||
fileTypes: [
|
||||
'cc'
|
||||
'cpp'
|
||||
'cp'
|
||||
'cxx'
|
||||
'c++'
|
||||
'cu'
|
||||
'cuh'
|
||||
'h'
|
||||
'hh'
|
||||
'hpp'
|
||||
'hxx'
|
||||
'h++'
|
||||
'inl'
|
||||
'ino'
|
||||
'ipp'
|
||||
'tcc'
|
||||
'tpp'
|
||||
]
|
||||
|
||||
contentRegex: '\n\\s*(namespace|class|template)\\s+'
|
||||
|
2
packages/language-c/grammars/tree-sitter-c/tags.scm
Normal file
2
packages/language-c/grammars/tree-sitter-c/tags.scm
Normal file
@ -0,0 +1,2 @@
|
||||
|
||||
((function_declarator (identifier) @name))
|
2
packages/language-c/grammars/tree-sitter-cpp/tags.scm
Normal file
2
packages/language-c/grammars/tree-sitter-cpp/tags.scm
Normal file
@ -0,0 +1,2 @@
|
||||
|
||||
((function_declarator (identifier) @name))
|
@ -11,6 +11,7 @@ treeSitter:
|
||||
grammar: 'tree-sitter/tree-sitter-css.wasm'
|
||||
highlightsQuery: 'tree-sitter/queries/highlights.scm'
|
||||
foldsQuery: 'tree-sitter/queries/folds.scm'
|
||||
tagsQuery: 'tree-sitter/queries/tags.scm'
|
||||
indentsQuery: 'tree-sitter/queries/indents.scm'
|
||||
|
||||
injectionRegex: '^(css|CSS)$'
|
||||
|
@ -0,0 +1 @@
|
||||
(selectors) @name
|
@ -13,5 +13,6 @@ comments:
|
||||
treeSitter:
|
||||
grammar: 'tree-sitter-java/tree-sitter-java.wasm'
|
||||
highlightsQuery: 'tree-sitter-java/highlights.scm'
|
||||
tagsQuery: 'tree-sitter-java/tags.scm'
|
||||
indentsQuery: 'tree-sitter-java/indents.scm'
|
||||
foldsQuery: 'tree-sitter-java/folds.scm'
|
||||
|
21
packages/language-java/grammars/tree-sitter-java/tags.scm
Normal file
21
packages/language-java/grammars/tree-sitter-java/tags.scm
Normal file
@ -0,0 +1,21 @@
|
||||
(class_declaration
|
||||
name: (identifier) @name) @definition.class
|
||||
|
||||
(method_declaration
|
||||
name: (identifier) @name) @definition.method
|
||||
|
||||
(method_invocation
|
||||
name: (identifier) @name
|
||||
arguments: (argument_list) @reference.call)
|
||||
|
||||
(interface_declaration
|
||||
name: (identifier) @name) @definition.interface
|
||||
|
||||
; TODO: Update parser
|
||||
; (type_list
|
||||
; (type_identifier) @name) @reference.implementation
|
||||
|
||||
(object_creation_expression
|
||||
type: (type_identifier) @name) @reference.class
|
||||
|
||||
(superclass (type_identifier) @name) @reference.class
|
@ -3,7 +3,7 @@ scopeName: 'source.js'
|
||||
type: 'modern-tree-sitter'
|
||||
parser: 'tree-sitter-javascript'
|
||||
|
||||
injectionRegex: '^(js|javascript)$'
|
||||
injectionRegex: '^(js|javascript|JS|JAVASCRIPT)$'
|
||||
treeSitter:
|
||||
grammar: 'ts/grammar.wasm'
|
||||
highlightsQuery: 'ts/highlights.scm'
|
||||
|
@ -11,16 +11,30 @@
|
||||
(
|
||||
(comment)* @doc
|
||||
.
|
||||
[
|
||||
(class
|
||||
name: (_) @name)
|
||||
(class_declaration
|
||||
name: (_) @name)
|
||||
] @definition.class
|
||||
(#strip! @doc "^[\\s\\*/]+|^[\\s\\*/]$")
|
||||
(#select-adjacent! @doc @definition.class)
|
||||
name: (_) @name) @definition.class
|
||||
)
|
||||
|
||||
(
|
||||
(comment)* @doc
|
||||
.
|
||||
(class
|
||||
name: (_) @name) @definition.class
|
||||
)
|
||||
|
||||
; (
|
||||
; (comment)* @doc
|
||||
; .
|
||||
; [
|
||||
; (class
|
||||
; name: (_) @name)
|
||||
; (class_declaration
|
||||
; name: (_) @name)
|
||||
; ] @definition.class
|
||||
; (#strip! @doc "^[\\s\\*/]+|^[\\s\\*/]$")
|
||||
; (#select-adjacent! @doc @definition.class)
|
||||
; )
|
||||
|
||||
(
|
||||
(comment)* @doc
|
||||
.
|
||||
|
@ -70,7 +70,7 @@ exports.activate = function() {
|
||||
const TODO_PATTERN = /\b(TODO|FIXME|CHANGED|XXX|IDEA|HACK|NOTE|REVIEW|NB|BUG|QUESTION|COMBAK|TEMP|DEBUG|OPTIMIZE|WARNING)\b/;
|
||||
const HYPERLINK_PATTERN = /\bhttps?:/
|
||||
|
||||
for (const scopeName of ['source.js', 'source.flow', 'source.ts']) {
|
||||
for (const scopeName of ['source.js', 'source.ts', 'source.ts.tsx']) {
|
||||
atom.grammars.addInjectionPoint(scopeName, {
|
||||
type: 'comment',
|
||||
language(comment) {
|
||||
@ -105,27 +105,6 @@ exports.activate = function() {
|
||||
});
|
||||
}
|
||||
|
||||
// atom.grammars.addInjectionPoint(scopeName, {
|
||||
// type: 'program',
|
||||
// language: () => 'todo',
|
||||
// content: (node) => {
|
||||
// return node.descendantsOfType('comment');
|
||||
// },
|
||||
// languageScope: null
|
||||
// });
|
||||
//
|
||||
// atom.grammars.addInjectionPoint(scopeName, {
|
||||
// type: 'program',
|
||||
// language: () => 'hyperlink',
|
||||
// content: (node) => {
|
||||
// return node.descendantsOfType([
|
||||
// 'template_string',
|
||||
// 'string_fragment',
|
||||
// 'comment'
|
||||
// ]);
|
||||
// },
|
||||
// languageScope: null
|
||||
// });
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -10,6 +10,7 @@ treeSitter:
|
||||
highlightsQuery: 'tree-sitter/queries/highlights.scm'
|
||||
indentsQuery: 'tree-sitter/queries/indents.scm'
|
||||
foldsQuery: 'tree-sitter/queries/folds.scm'
|
||||
tagsQuery: 'tree-sitter/queries/tags.scm'
|
||||
|
||||
fileTypes: [
|
||||
'avsc'
|
||||
|
@ -0,0 +1,9 @@
|
||||
|
||||
|
||||
; All JSON keys are symbols as long as they descend from a chain of objects.
|
||||
; Nested keys try to prepend the symbol name of their parent's key.
|
||||
(pair key: (string (string_content) @name
|
||||
(#is-not? test.descendantOfType "array")
|
||||
(#set! symbol.prependSymbolForNode parent.parent.parent.previousNamedSibling.firstNamedChild)
|
||||
(#set! symbol.contextNode parent.parent.parent.previousNamedSibling.firstNamedChild)
|
||||
(#set! symbol.joiner ".")))
|
@ -31,6 +31,6 @@ treeSitter:
|
||||
# to add support for `match` statements.
|
||||
grammar: 'ts/tree-sitter-python.wasm'
|
||||
highlightsQuery: 'ts/highlights.scm'
|
||||
localsQuery: 'ts/locals.scm'
|
||||
tagsQuery: 'ts/tags.scm'
|
||||
foldsQuery: 'ts/folds.scm'
|
||||
indentsQuery: 'ts/indents.scm'
|
||||
|
12
packages/language-python/grammars/ts/tags.scm
Normal file
12
packages/language-python/grammars/ts/tags.scm
Normal file
@ -0,0 +1,12 @@
|
||||
(class_definition
|
||||
name: (identifier) @name) @definition.class
|
||||
|
||||
(function_definition
|
||||
name: (identifier) @name) @definition.function
|
||||
|
||||
(call
|
||||
function: [
|
||||
(identifier) @name
|
||||
(attribute
|
||||
attribute: (identifier) @name)
|
||||
]) @reference.call
|
@ -1,17 +1,29 @@
|
||||
exports.activate = function () {
|
||||
if (!atom.grammars.addInjectionPoint) return;
|
||||
|
||||
// TODO: Uncomment when performance is acceptable.
|
||||
const TODO_PATTERN = /\b(TODO|FIXME|CHANGED|XXX|IDEA|HACK|NOTE|REVIEW|NB|BUG|QUESTION|COMBAK|TEMP|DEBUG|OPTIMIZE|WARNING)\b/;
|
||||
const HYPERLINK_PATTERN = /\bhttps?:/
|
||||
|
||||
// atom.grammars.addInjectionPoint('source.python', {
|
||||
// type: 'string',
|
||||
// language() {
|
||||
// return 'hyperlink';
|
||||
// },
|
||||
// content(node) {
|
||||
// return node;
|
||||
// }
|
||||
// });
|
||||
atom.grammars.addInjectionPoint('source.python', {
|
||||
type: 'comment',
|
||||
language: (node) => {
|
||||
return TODO_PATTERN.test(node.text) ? 'todo' : undefined;
|
||||
},
|
||||
content: (node) => node,
|
||||
languageScope: null
|
||||
});
|
||||
|
||||
for (let type of ['comment', 'string']) {
|
||||
atom.grammars.addInjectionPoint('source.python', {
|
||||
type,
|
||||
language(node) {
|
||||
return HYPERLINK_PATTERN.test(node.text) ?
|
||||
'hyperlink' : undefined;
|
||||
},
|
||||
content: (node) => node,
|
||||
languageScope: null
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: There's no regex literal in Python. The TM-style grammar has a
|
||||
// very obscure option that, when enabled, assumes all raw strings are
|
||||
|
@ -3,13 +3,13 @@
|
||||
name: [
|
||||
(constant) @name
|
||||
(scope_resolution name: (_) @name)
|
||||
])
|
||||
]) @definition.class
|
||||
|
||||
(singleton_class
|
||||
value: [
|
||||
(constant) @name
|
||||
(scope_resolution name: (_) @name)
|
||||
])
|
||||
]) @definition.class
|
||||
|
||||
; Module names
|
||||
(module
|
||||
@ -17,11 +17,11 @@
|
||||
(constant) @name
|
||||
(scope_resolution
|
||||
name: (_) @name)
|
||||
])
|
||||
]) @definition.module
|
||||
|
||||
; Method names
|
||||
(method name: (_) @name)
|
||||
(singleton_method name: (_) @name)
|
||||
(method name: (_) @name) @definition.method
|
||||
(singleton_method name: (_) @name) @definition.method
|
||||
|
||||
; Aliased methods
|
||||
(alias name: (_) @name)
|
||||
(alias name: (_) @name) @definition.method
|
||||
|
@ -9,7 +9,6 @@ exports.activate = function() {
|
||||
content(node) {
|
||||
return node.descendantsOfType('heredoc_content')
|
||||
},
|
||||
// coverShallowerScopes: true
|
||||
});
|
||||
|
||||
atom.grammars.addInjectionPoint('source.ruby', {
|
||||
|
@ -15,5 +15,6 @@ comments:
|
||||
treeSitter:
|
||||
grammar: 'tree-sitter-rust/tree-sitter-rust.wasm'
|
||||
highlightsQuery: 'tree-sitter-rust/queries/highlights.scm'
|
||||
tagsQuery: 'tree-sitter-rust/queries/tags.scm'
|
||||
foldsQuery: 'tree-sitter-rust/queries/folds.scm'
|
||||
indentsQuery: 'tree-sitter-rust/queries/indents.scm'
|
||||
|
@ -0,0 +1,68 @@
|
||||
; ADT definitions
|
||||
|
||||
(struct_item
|
||||
name: (type_identifier) @name) @definition.class
|
||||
|
||||
(enum_item
|
||||
name: (type_identifier) @name) @definition.class
|
||||
|
||||
(union_item
|
||||
name: (type_identifier) @name) @definition.class
|
||||
|
||||
; type aliases
|
||||
|
||||
(type_item
|
||||
name: (type_identifier) @name) @definition.class
|
||||
|
||||
(impl_item
|
||||
(declaration_list
|
||||
(function_item
|
||||
name: (identifier) @name)
|
||||
(#set! capture.final true)
|
||||
(#set! symbol.prependTextForNode parent.parent.parent.firstNamedChild)
|
||||
(#set! symbol.joiner " ")))
|
||||
|
||||
; method definitions
|
||||
|
||||
((declaration_list
|
||||
(function_item
|
||||
name: (identifier) @name)) @definition.method
|
||||
(#set! capture.final true))
|
||||
; function definitions
|
||||
|
||||
(function_item
|
||||
name: (identifier) @name) @definition.function
|
||||
|
||||
; trait definitions
|
||||
(trait_item
|
||||
name: (type_identifier) @name) @definition.interface
|
||||
|
||||
; module definitions
|
||||
(mod_item
|
||||
name: (identifier) @name) @definition.module
|
||||
|
||||
; macro definitions
|
||||
|
||||
(macro_definition
|
||||
name: (identifier) @name) @definition.macro
|
||||
|
||||
; references
|
||||
|
||||
; (call_expression
|
||||
; function: (identifier) @name) @reference.call
|
||||
;
|
||||
; (call_expression
|
||||
; function: (field_expression
|
||||
; field: (field_identifier) @name)) @reference.call
|
||||
;
|
||||
; (macro_invocation
|
||||
; macro: (identifier) @name) @reference.call
|
||||
|
||||
; implementations
|
||||
|
||||
(impl_item
|
||||
trait: (type_identifier) @name) @reference.implementation
|
||||
|
||||
(impl_item
|
||||
type: (type_identifier) @name
|
||||
!trait) @reference.implementation
|
@ -23,6 +23,7 @@ injectionRegex: '(^(bash|BASH)$|sh^|SH^)'
|
||||
treeSitter:
|
||||
grammar: 'tree-sitter/tree-sitter-bash.wasm'
|
||||
highlightsQuery: 'tree-sitter/highlights.scm'
|
||||
tagsQuery: 'tree-sitter/tags.scm'
|
||||
foldsQuery: 'tree-sitter/folds.scm'
|
||||
indentsQuery: 'tree-sitter/indents.scm'
|
||||
|
||||
|
@ -0,0 +1,2 @@
|
||||
|
||||
(function_definition name: (_) @name)
|
@ -1,20 +1,31 @@
|
||||
(function_declaration
|
||||
name: (identifier) @name) @definition.function
|
||||
name: (identifier) @name
|
||||
(#set! symbol.tag "function")) @definition.function
|
||||
|
||||
(function
|
||||
name: (identifier) @name) @definition.function
|
||||
name: (identifier) @name
|
||||
(#set! symbol.tag "function")) @definition.function
|
||||
|
||||
(method_definition
|
||||
name: (property_identifier) @name) @definition.method
|
||||
name: (property_identifier) @name
|
||||
(#set! symbol.tag "method")) @definition.method
|
||||
|
||||
(abstract_method_signature
|
||||
name: (property_identifier) @name) @definition.method
|
||||
name: (property_identifier) @name
|
||||
(#set! symbol.tag "method")) @definition.method
|
||||
|
||||
(class_declaration
|
||||
name: (type_identifier) @name) @definition.class
|
||||
name: (type_identifier) @name
|
||||
(#set! symbol.tag "class")) @definition.class
|
||||
|
||||
(module
|
||||
name: (identifier) @name) @definition.module
|
||||
name: (identifier) @name
|
||||
(#set! symbol.tag "module")) @definition.module
|
||||
|
||||
(interface_declaration
|
||||
name: (type_identifier) @name) @definition.interface
|
||||
name: (type_identifier) @name
|
||||
(#set! symbol.tag "interface")) @definition.interface
|
||||
|
||||
(function_signature
|
||||
name: (identifier) @name
|
||||
(#set! symbol.tag "function")) @definition.function
|
||||
|
@ -1,5 +1,5 @@
|
||||
exports.activate = function() {
|
||||
for (const scopeName of ['source.ts', 'source.flow']) {
|
||||
for (const scopeName of ['source.ts', 'source.tsx', 'source.flow']) {
|
||||
atom.grammars.addInjectionPoint(scopeName, {
|
||||
type: 'call_expression',
|
||||
|
||||
|
@ -154,7 +154,8 @@
|
||||
}
|
||||
|
||||
.syntax--support {
|
||||
&.syntax--class {
|
||||
&.syntax--class,
|
||||
&.syntax--module {
|
||||
color: @hue-6-2;
|
||||
}
|
||||
|
||||
|
@ -154,7 +154,8 @@
|
||||
}
|
||||
|
||||
.syntax--support {
|
||||
&.syntax--class {
|
||||
&.syntax--class,
|
||||
&.syntax--module {
|
||||
color: @hue-6-2;
|
||||
}
|
||||
|
||||
|
1
packages/pulsar-updater/.gitignore
vendored
Normal file
1
packages/pulsar-updater/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
node_modules/
|
48
packages/pulsar-updater/README.md
Normal file
48
packages/pulsar-updater/README.md
Normal file
@ -0,0 +1,48 @@
|
||||
# Pulsar Updater
|
||||
|
||||
Update utility for Pulsar. On launch of Pulsar, `pulsar-updater` will check for any new releases available via GitHub APIs. And if one is available will display a notification for the user to be able to install the new version.
|
||||
|
||||
If the user seems to have installed Pulsar manually, a link will be opened directly to the resource on GitHub, allowing the user to then download the correct file as needed, and install it. Otherwise if it seems the user has installed Pulsar via various recognized package managers, then Pulsar Updater will present a notification that an update is available, and provide the commands needed to preform the update themselves if they so wish.
|
||||
|
||||
This package is made to be minimally invasive, while still allowing users to be aware of new Pulsar versions without any manual effort.
|
||||
|
||||
Additionally, since the entire process of actually installation is done by the user, there is no need for complex Squirrel logic, or expensive certifications to allow Squirrel to work.
|
||||
|
||||
## Command Palette
|
||||
|
||||
If a user would prefer to manually check for any updates available then the following commands are exposed from Pulsar Updater to do so:
|
||||
|
||||
* `pulsar-updater:check-for-update`: Performs an update check and shows a notification if a newer version of Pulsar is available.
|
||||
* `pulsar-updater:clear-cache`: Clears the package's cache and forgets any requests to suppress update checking.
|
||||
|
||||
## The Update Notification
|
||||
|
||||
If an update is available, the notification that is shown is intended to be as non-invasive as possible, providing a few possible options:
|
||||
|
||||
* Dismiss this Version: This will remove the notification, and prevent an additional notification ever appearing for this version again. Bypassing any cache expirations.
|
||||
* Dismiss until next launch: This will remove the notification, but only until the next update check. Which happens automatically at launch, or otherwise can be invoked manually.
|
||||
* Download from GitHub: This option is only shown if the installation method was determined to be manually. And clicking it will open the GitHub page containing the specific version to update to.
|
||||
|
||||
## Supported/Checked/Recognized for Installation Methods
|
||||
|
||||
Since a major part of the functionality of this package is attempting to determine the installation method, it's important to list them all here:
|
||||
|
||||
* Universal: Developer Mode
|
||||
* Universal: Safe Mode
|
||||
* Universal: Spec Mode
|
||||
* Windows: Chocolatey Installation
|
||||
* Windows: winget Installation
|
||||
* Windows: User Installation
|
||||
* Windows: Machine Installation
|
||||
* Windows: Portable Installation
|
||||
* Linux: Flatpak Installation
|
||||
* Linux: Deb-Get Installation
|
||||
* Linux: Nix Installation
|
||||
* Linux: Home Brew Installation
|
||||
* Linux: Manual Installation
|
||||
* macOS: Home Brew Installation
|
||||
* macOS: Manual Installation
|
||||
|
||||
## Known Issues
|
||||
|
||||
It's important to remember that this update system is in no way integrated with the rest of Pulsar. The toggles within Pulsar to update automatically are ignored. The About view will still be unable to alert of new versions, nor track progress on installation. Those systems should eventually be removed, or mothballed, in favour of this.
|
847
packages/pulsar-updater/package-lock.json
generated
Normal file
847
packages/pulsar-updater/package-lock.json
generated
Normal file
@ -0,0 +1,847 @@
|
||||
{
|
||||
"name": "pulsar-updater",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "pulsar-updater",
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"event-kit": "github:pulsar-edit/event-kit",
|
||||
"shelljs": "^0.8.5",
|
||||
"superagent": "^8.0.9",
|
||||
"winreg": "^1.2.4"
|
||||
},
|
||||
"engines": {
|
||||
"atom": ">=1.106.0 <2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/asap": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
|
||||
"integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA=="
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/call-bind": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
|
||||
"integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.1",
|
||||
"get-intrinsic": "^1.0.2"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"dependencies": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/component-emitter": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
|
||||
"integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
||||
},
|
||||
"node_modules/cookiejar": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz",
|
||||
"integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw=="
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
|
||||
"dependencies": {
|
||||
"ms": "2.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"supports-color": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/dezalgo": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz",
|
||||
"integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==",
|
||||
"dependencies": {
|
||||
"asap": "^2.0.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/event-kit": {
|
||||
"version": "2.5.3",
|
||||
"resolved": "git+ssh://git@github.com/pulsar-edit/event-kit.git#80b551c1d03dd05795500f0c71dcf15be3a23c63",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fast-safe-stringify": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
|
||||
"integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA=="
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
||||
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/formidable": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz",
|
||||
"integrity": "sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==",
|
||||
"dependencies": {
|
||||
"dezalgo": "^1.0.4",
|
||||
"hexoid": "^1.0.0",
|
||||
"once": "^1.4.0",
|
||||
"qs": "^6.11.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://ko-fi.com/tunnckoCore/commissions"
|
||||
}
|
||||
},
|
||||
"node_modules/fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
|
||||
},
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
|
||||
},
|
||||
"node_modules/get-intrinsic": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
|
||||
"integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.1",
|
||||
"has": "^1.0.3",
|
||||
"has-proto": "^1.0.1",
|
||||
"has-symbols": "^1.0.3"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/glob": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
||||
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.1.1",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/has": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
||||
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/has-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-symbols": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
||||
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/hexoid": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz",
|
||||
"integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
||||
"dependencies": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"node_modules/interpret": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
|
||||
"integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
|
||||
"engines": {
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/is-core-module": {
|
||||
"version": "2.12.1",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz",
|
||||
"integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==",
|
||||
"dependencies": {
|
||||
"has": "^1.0.3"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"dependencies": {
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/methods": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||
"integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
|
||||
"integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
|
||||
"bin": {
|
||||
"mime": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-types": {
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"dependencies": {
|
||||
"mime-db": "1.52.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"node_modules/object-inspect": {
|
||||
"version": "1.12.3",
|
||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
|
||||
"integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/path-parse": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
|
||||
},
|
||||
"node_modules/qs": {
|
||||
"version": "6.11.2",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz",
|
||||
"integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==",
|
||||
"dependencies": {
|
||||
"side-channel": "^1.0.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/rechoir": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
|
||||
"integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==",
|
||||
"dependencies": {
|
||||
"resolve": "^1.1.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/resolve": {
|
||||
"version": "1.22.2",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz",
|
||||
"integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==",
|
||||
"dependencies": {
|
||||
"is-core-module": "^2.11.0",
|
||||
"path-parse": "^1.0.7",
|
||||
"supports-preserve-symlinks-flag": "^1.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"resolve": "bin/resolve"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.5.3",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz",
|
||||
"integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==",
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/shelljs": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz",
|
||||
"integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==",
|
||||
"dependencies": {
|
||||
"glob": "^7.0.0",
|
||||
"interpret": "^1.0.0",
|
||||
"rechoir": "^0.6.2"
|
||||
},
|
||||
"bin": {
|
||||
"shjs": "bin/shjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/side-channel": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
|
||||
"integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.0",
|
||||
"get-intrinsic": "^1.0.2",
|
||||
"object-inspect": "^1.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/superagent": {
|
||||
"version": "8.0.9",
|
||||
"resolved": "https://registry.npmjs.org/superagent/-/superagent-8.0.9.tgz",
|
||||
"integrity": "sha512-4C7Bh5pyHTvU33KpZgwrNKh/VQnvgtCSqPRfJAUdmrtSYePVzVg4E4OzsrbkhJj9O7SO6Bnv75K/F8XVZT8YHA==",
|
||||
"dependencies": {
|
||||
"component-emitter": "^1.3.0",
|
||||
"cookiejar": "^2.1.4",
|
||||
"debug": "^4.3.4",
|
||||
"fast-safe-stringify": "^2.1.1",
|
||||
"form-data": "^4.0.0",
|
||||
"formidable": "^2.1.2",
|
||||
"methods": "^1.1.2",
|
||||
"mime": "2.6.0",
|
||||
"qs": "^6.11.0",
|
||||
"semver": "^7.3.8"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.4.0 <13 || >=14"
|
||||
}
|
||||
},
|
||||
"node_modules/supports-preserve-symlinks-flag": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
|
||||
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/winreg": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/winreg/-/winreg-1.2.4.tgz",
|
||||
"integrity": "sha512-IHpzORub7kYlb8A43Iig3reOvlcBJGX9gZ0WycHhghHtA65X0LYnMRuJs+aH1abVnMJztQkvQNlltnbPi5aGIA=="
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||
},
|
||||
"node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"asap": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
|
||||
"integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA=="
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"call-bind": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
|
||||
"integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
|
||||
"requires": {
|
||||
"function-bind": "^1.1.1",
|
||||
"get-intrinsic": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"requires": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"component-emitter": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
|
||||
"integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
||||
},
|
||||
"cookiejar": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz",
|
||||
"integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw=="
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
}
|
||||
},
|
||||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
|
||||
},
|
||||
"dezalgo": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz",
|
||||
"integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==",
|
||||
"requires": {
|
||||
"asap": "^2.0.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"event-kit": {
|
||||
"version": "git+ssh://git@github.com/pulsar-edit/event-kit.git#80b551c1d03dd05795500f0c71dcf15be3a23c63",
|
||||
"from": "event-kit@pulsar-edit/event-kit"
|
||||
},
|
||||
"fast-safe-stringify": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
|
||||
"integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA=="
|
||||
},
|
||||
"form-data": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
||||
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
||||
"requires": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"mime-types": "^2.1.12"
|
||||
}
|
||||
},
|
||||
"formidable": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz",
|
||||
"integrity": "sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==",
|
||||
"requires": {
|
||||
"dezalgo": "^1.0.4",
|
||||
"hexoid": "^1.0.0",
|
||||
"once": "^1.4.0",
|
||||
"qs": "^6.11.0"
|
||||
}
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
|
||||
},
|
||||
"function-bind": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
|
||||
},
|
||||
"get-intrinsic": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
|
||||
"integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
|
||||
"requires": {
|
||||
"function-bind": "^1.1.1",
|
||||
"has": "^1.0.3",
|
||||
"has-proto": "^1.0.1",
|
||||
"has-symbols": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
||||
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.1.1",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"has": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
||||
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
|
||||
"requires": {
|
||||
"function-bind": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"has-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg=="
|
||||
},
|
||||
"has-symbols": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
||||
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
|
||||
},
|
||||
"hexoid": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz",
|
||||
"integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g=="
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
||||
"requires": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"interpret": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
|
||||
"integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA=="
|
||||
},
|
||||
"is-core-module": {
|
||||
"version": "2.12.1",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz",
|
||||
"integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==",
|
||||
"requires": {
|
||||
"has": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"requires": {
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"methods": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||
"integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w=="
|
||||
},
|
||||
"mime": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
|
||||
"integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg=="
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"requires": {
|
||||
"mime-db": "1.52.0"
|
||||
}
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"object-inspect": {
|
||||
"version": "1.12.3",
|
||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
|
||||
"integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g=="
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="
|
||||
},
|
||||
"path-parse": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.11.2",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz",
|
||||
"integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==",
|
||||
"requires": {
|
||||
"side-channel": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"rechoir": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
|
||||
"integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==",
|
||||
"requires": {
|
||||
"resolve": "^1.1.6"
|
||||
}
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.22.2",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz",
|
||||
"integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==",
|
||||
"requires": {
|
||||
"is-core-module": "^2.11.0",
|
||||
"path-parse": "^1.0.7",
|
||||
"supports-preserve-symlinks-flag": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "7.5.3",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz",
|
||||
"integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==",
|
||||
"requires": {
|
||||
"lru-cache": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"shelljs": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz",
|
||||
"integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==",
|
||||
"requires": {
|
||||
"glob": "^7.0.0",
|
||||
"interpret": "^1.0.0",
|
||||
"rechoir": "^0.6.2"
|
||||
}
|
||||
},
|
||||
"side-channel": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
|
||||
"integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
|
||||
"requires": {
|
||||
"call-bind": "^1.0.0",
|
||||
"get-intrinsic": "^1.0.2",
|
||||
"object-inspect": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"superagent": {
|
||||
"version": "8.0.9",
|
||||
"resolved": "https://registry.npmjs.org/superagent/-/superagent-8.0.9.tgz",
|
||||
"integrity": "sha512-4C7Bh5pyHTvU33KpZgwrNKh/VQnvgtCSqPRfJAUdmrtSYePVzVg4E4OzsrbkhJj9O7SO6Bnv75K/F8XVZT8YHA==",
|
||||
"requires": {
|
||||
"component-emitter": "^1.3.0",
|
||||
"cookiejar": "^2.1.4",
|
||||
"debug": "^4.3.4",
|
||||
"fast-safe-stringify": "^2.1.1",
|
||||
"form-data": "^4.0.0",
|
||||
"formidable": "^2.1.2",
|
||||
"methods": "^1.1.2",
|
||||
"mime": "2.6.0",
|
||||
"qs": "^6.11.0",
|
||||
"semver": "^7.3.8"
|
||||
}
|
||||
},
|
||||
"supports-preserve-symlinks-flag": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
|
||||
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="
|
||||
},
|
||||
"winreg": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/winreg/-/winreg-1.2.4.tgz",
|
||||
"integrity": "sha512-IHpzORub7kYlb8A43Iig3reOvlcBJGX9gZ0WycHhghHtA65X0LYnMRuJs+aH1abVnMJztQkvQNlltnbPi5aGIA=="
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||
},
|
||||
"yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
}
|
||||
}
|
||||
}
|
28
packages/pulsar-updater/package.json
Normal file
28
packages/pulsar-updater/package.json
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "pulsar-updater",
|
||||
"version": "1.0.0",
|
||||
"description": "Detect Pulsar updates on Launch.",
|
||||
"main": "./src/main.js",
|
||||
"scripts": {
|
||||
"test": "pulsar --test spec"
|
||||
},
|
||||
"engines": {
|
||||
"atom": ">=1.106.0 <2.0.0"
|
||||
},
|
||||
"author": "confused-Techie",
|
||||
"license": "MIT",
|
||||
"repository": "https://github.com/pulsar-edit/pulsar",
|
||||
"dependencies": {
|
||||
"event-kit": "github:pulsar-edit/event-kit",
|
||||
"shelljs": "^0.8.5",
|
||||
"superagent": "^8.0.9",
|
||||
"winreg": "^1.2.4"
|
||||
},
|
||||
"configSchema": {
|
||||
"checkForUpdatesOnLaunch": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"description": "If Pulsar Updater should check for an update to Pulsar as soon as Pulsar launches."
|
||||
}
|
||||
}
|
||||
}
|
20
packages/pulsar-updater/spec/cache-spec.js
Normal file
20
packages/pulsar-updater/spec/cache-spec.js
Normal file
@ -0,0 +1,20 @@
|
||||
const cache = require("../src/cache.js");
|
||||
|
||||
describe("pulsar-updater cache", () => {
|
||||
it("returns key for path", () => {
|
||||
let key = cache.cacheKeyForPath("test");
|
||||
expect(key).toBe("pulsar-updater:test");
|
||||
});
|
||||
|
||||
it("returns expired properly according to date", () => {
|
||||
let expiry = cache.isItemExpired({ createdOn: Date.now() });
|
||||
expect(expiry).toBe(false);
|
||||
});
|
||||
|
||||
it("returns not expired if offline", () => {
|
||||
spyOn(cache, "online").andReturn(true);
|
||||
|
||||
let expiry = cache.isItemExpired({ createdOn: 0 });
|
||||
expect(expiry).toBe(false);
|
||||
})
|
||||
});
|
137
packages/pulsar-updater/spec/find-install-channel-spec.js
Normal file
137
packages/pulsar-updater/spec/find-install-channel-spec.js
Normal file
@ -0,0 +1,137 @@
|
||||
const findInstallChannel = require("../src/find-install-channel.js");
|
||||
const shell = require("shelljs");
|
||||
|
||||
describe("pulsar-updater findInstallChannel", () => {
|
||||
describe("windows choco install", () => {
|
||||
it("fails if 'choco' isn't found", () => {
|
||||
spyOn(shell, "which").andReturn(false);
|
||||
|
||||
let installCheck = findInstallChannel.windows_chocoInstalled();
|
||||
expect(installCheck).toBe(false);
|
||||
});
|
||||
it("fails if pulsar isn't included in stdout", () => {
|
||||
spyOn(shell, "which").andReturn(true);
|
||||
spyOn(shell, "exec").andReturn({ code: 0, stdout: "not -pu-l-sar" });
|
||||
|
||||
let installCheck = findInstallChannel.windows_chocoInstalled();
|
||||
expect(installCheck).toBe(false);
|
||||
});
|
||||
it("fails if exit code is not 0", () => {
|
||||
spyOn(shell, "which").andReturn(true);
|
||||
spyOn(shell, "exec").andReturn({ code: 1, stdout: "" });
|
||||
|
||||
let installCheck = findInstallChannel.windows_chocoInstalled();
|
||||
expect(installCheck).toBe(false);
|
||||
});
|
||||
it("succeeds if pulsar is included in stdout", () => {
|
||||
spyOn(shell, "which").andReturn(true);
|
||||
spyOn(shell, "exec").andReturn({ code: 0, stdout: "pulsar" });
|
||||
|
||||
let installCheck = findInstallChannel.windows_chocoInstalled();
|
||||
expect(installCheck).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("windows winget install", () => {
|
||||
it("fails if winget isn't found", () => {
|
||||
spyOn(shell, "which").andReturn(false);
|
||||
|
||||
let installCheck = findInstallChannel.windows_wingetInstalled();
|
||||
expect(installCheck).toBe(false);
|
||||
});
|
||||
it("fails if pulsar isn't found in stdout", () => {
|
||||
spyOn(shell, "which").andReturn(true);
|
||||
spyOn(shell, "exec").andReturn({ code: 0, stdout: "not -pu-l-sar" });
|
||||
|
||||
let installCheck = findInstallChannel.windows_wingetInstalled();
|
||||
expect(installCheck).toBe(false);
|
||||
});
|
||||
it("fails if exit code is not 0", () => {
|
||||
spyOn(shell, "which").andReturn(true);
|
||||
spyOn(shell, "exec").andReturn({ code: 1, stdout: "" });
|
||||
|
||||
let installCheck = findInstallChannel.windows_wingetInstalled();
|
||||
expect(installCheck).toBe(false);
|
||||
});
|
||||
it("succeeds if pulsar is included in stdout", () => {
|
||||
spyOn(shell, "which").andReturn(true);
|
||||
spyOn(shell, "exec").andReturn({ code: 0, stdout: "Pulsar" });
|
||||
|
||||
let installCheck = findInstallChannel.windows_wingetInstalled();
|
||||
expect(installCheck).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("linux/macos homebrew install", () => {
|
||||
it("fails if brew isn't found", () => {
|
||||
spyOn(shell, "which").andReturn(false);
|
||||
|
||||
let installCheck = findInstallChannel.linux_macos_homebrewInstalled();
|
||||
expect(installCheck).toBe(false);
|
||||
});
|
||||
it("fails if pulsar isn't found in stdout", () => {
|
||||
spyOn(shell, "which").andReturn(true);
|
||||
spyOn(shell, "exec").andReturn({ code: 0, stdout: "not -pu-l-sar" });
|
||||
|
||||
let installCheck = findInstallChannel.linux_macos_homebrewInstalled();
|
||||
expect(installCheck).toBe(false);
|
||||
});
|
||||
it("fails if exit code is not 0", () => {
|
||||
spyOn(shell, "which").andReturn(true);
|
||||
spyOn(shell, "exec").andReturn({ code: 1, stdout: "" });
|
||||
|
||||
let installCheck = findInstallChannel.linux_macos_homebrewInstalled();
|
||||
expect(installCheck).toBe(false);
|
||||
});
|
||||
it("succeeds if pulsar is included in stdout", () => {
|
||||
spyOn(shell, "which").andReturn(true);
|
||||
spyOn(shell, "exec").andReturn({ code: 0, stdout: "pulsar" });
|
||||
|
||||
let installCheck = findInstallChannel.linux_macos_homebrewInstalled();
|
||||
expect(installCheck).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("linux debget install", () => {
|
||||
it("fails if deb-get isn't found", () => {
|
||||
spyOn(shell, "which").andReturn(false);
|
||||
|
||||
let installCheck = findInstallChannel.linux_debGetInstalled();
|
||||
expect(installCheck).toBe(false);
|
||||
});
|
||||
it("fails if pulsar isn't found in stdout", () => {
|
||||
spyOn(shell, "which").andReturn(true);
|
||||
spyOn(shell, "exec").andReturn({ code: 0, stdout: "not -pu-l-sar" });
|
||||
|
||||
let installCheck = findInstallChannel.linux_debGetInstalled();
|
||||
expect(installCheck).toBe(false);
|
||||
});
|
||||
it("fails if exit code is not 0", () => {
|
||||
spyOn(shell, "which").andReturn(false);
|
||||
spyOn(shell, "exec").andReturn({ code: 1, stdout: "" });
|
||||
|
||||
let installCheck = findInstallChannel.linux_debGetInstalled();
|
||||
expect(installCheck).toBe(false);
|
||||
});
|
||||
it("succeeds if pulsar is included in stdout", () => {
|
||||
spyOn(shell, "which").andReturn(true);
|
||||
spyOn(shell, "exec").andReturn({ code: 0, stdout: "pulsar" });
|
||||
|
||||
let installCheck = findInstallChannel.linux_debGetInstalled();
|
||||
expect(installCheck).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("linux flatpak install", () => {
|
||||
it("fails if flatpak_id is not pulsar", () => {
|
||||
process.env.FLATPAK_ID = "not-pulsar";
|
||||
let installCheck = findInstallChannel.linux_flatpakInstalled();
|
||||
expect(installCheck).toBe(false);
|
||||
});
|
||||
it("succeeds if flatpak_id is pulsar", () => {
|
||||
process.env.FLATPAK_ID = "dev.pulsar_edit.Pulsar";
|
||||
let installCheck = findInstallChannel.linux_flatpakInstalled();
|
||||
expect(installCheck).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
18
packages/pulsar-updater/spec/find-install-method-spec.js
Normal file
18
packages/pulsar-updater/spec/find-install-method-spec.js
Normal file
@ -0,0 +1,18 @@
|
||||
const findInstallMethod = require("../src/find-install-method.js");
|
||||
|
||||
describe("find-install-method main", async () => {
|
||||
|
||||
const platform = process.platform;
|
||||
const arch = process.arch;
|
||||
|
||||
it("Returns spec mode if applicable", async () => {
|
||||
// We can't mock the atom api return from a package,
|
||||
// So we will just know that if tests are running, it's in the Atom SpecMode
|
||||
|
||||
let method = await findInstallMethod();
|
||||
|
||||
expect(method.installMethod).toBe("Spec Mode");
|
||||
expect(method.platform).toBe(platform);
|
||||
expect(method.arch).toBe(arch);
|
||||
});
|
||||
});
|
111
packages/pulsar-updater/spec/pulsar-updater-spec.js
Normal file
111
packages/pulsar-updater/spec/pulsar-updater-spec.js
Normal file
@ -0,0 +1,111 @@
|
||||
|
||||
function wait(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms, true));
|
||||
}
|
||||
|
||||
describe('PulsarUpdater', () => {
|
||||
|
||||
let pack, workspaceElement;
|
||||
beforeEach(async () => {
|
||||
atom.config.set("pulsar-updater.checkForUpdatesOnLaunch", false);
|
||||
workspaceElement = atom.views.getView(atom.workspace);
|
||||
pack = await atom.packages.activatePackage('pulsar-updater');
|
||||
pack.mainModule.cache?.empty("last-update-check");
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
pack.mainModule.cache?.empty("last-update-check");
|
||||
await atom.packages.deactivatePackage('pulsar-updater');
|
||||
});
|
||||
|
||||
describe('when pulsar-updater:check-for-updates is triggered', () => {
|
||||
beforeEach(async () => {
|
||||
spyOn(pack.mainModule, 'checkForUpdates');
|
||||
})
|
||||
it('triggers an update check', () => {
|
||||
atom.commands.dispatch(workspaceElement, 'pulsar-updater:check-for-update');
|
||||
expect(pack.mainModule.checkForUpdates).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("when the remote version is greater than ours", () => {
|
||||
beforeEach(() => {
|
||||
spyOn(atom, "getVersion").andReturn("1.0.0");
|
||||
spyOn(pack.mainModule, 'findNewestRelease').andCallFake(() => {
|
||||
return "2.0.0";
|
||||
})
|
||||
spyOn(pack.mainModule, 'notifyAboutUpdate').andCallThrough();
|
||||
spyOn(pack.mainModule, 'notifyAboutCurrent').andCallThrough();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
pack.mainModule.notifyAboutUpdate.reset();
|
||||
pack.mainModule.notifyAboutCurrent.reset();
|
||||
})
|
||||
|
||||
it("signals that the user should update", async () => {
|
||||
jasmine.useRealClock();
|
||||
atom.commands.dispatch(workspaceElement, 'pulsar-updater:check-for-update');
|
||||
await wait(200);
|
||||
expect(pack.mainModule.notifyAboutUpdate).toHaveBeenCalledWith("2.0.0");
|
||||
expect(pack.mainModule.notifyAboutCurrent).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("when the remote version is equal to ours", () => {
|
||||
beforeEach(() => {
|
||||
spyOn(atom, "getVersion").andReturn("1.0.5");
|
||||
spyOn(pack.mainModule, 'findNewestRelease').andCallFake(() => {
|
||||
return "1.0.5";
|
||||
})
|
||||
spyOn(pack.mainModule, 'notifyAboutUpdate');
|
||||
spyOn(pack.mainModule, 'notifyAboutCurrent');
|
||||
});
|
||||
|
||||
it("takes no action", async () => {
|
||||
jasmine.useRealClock();
|
||||
atom.commands.dispatch(workspaceElement, 'pulsar-updater:check-for-update');
|
||||
await wait(200);
|
||||
expect(pack.mainModule.notifyAboutUpdate).not.toHaveBeenCalled();
|
||||
expect(pack.mainModule.notifyAboutCurrent).toHaveBeenCalledWith("1.0.5", true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("when the user tells us to ignore until the next version", () => {
|
||||
let latestVersion = "1.0.6";
|
||||
beforeEach(() => {
|
||||
spyOn(atom, "getVersion").andReturn("1.0.5");
|
||||
spyOn(pack.mainModule, 'findNewestRelease').andCallFake(() => {
|
||||
return latestVersion;
|
||||
});
|
||||
spyOn(pack.mainModule, 'notifyAboutUpdate').andCallThrough();
|
||||
spyOn(pack.mainModule, 'notifyAboutCurrent').andCallThrough();
|
||||
});
|
||||
|
||||
it("subsequent checks do not result in notifications", async () => {
|
||||
jasmine.useRealClock();
|
||||
atom.commands.dispatch(workspaceElement, 'pulsar-updater:check-for-update');
|
||||
await wait(200);
|
||||
|
||||
expect(pack.mainModule.notifyAboutUpdate).toHaveBeenCalledWith("1.0.6");
|
||||
expect(pack.mainModule.notifyAboutCurrent).not.toHaveBeenCalled();
|
||||
|
||||
pack.mainModule.ignoreForThisVersion("1.0.6");
|
||||
// Calling the method directly here because eventually we'll want a
|
||||
// user-initiated check for updates to ignore this cache.
|
||||
pack.mainModule.checkForUpdates();
|
||||
await wait(200);
|
||||
|
||||
expect(pack.mainModule.notifyAboutUpdate.callCount).toBe(1);
|
||||
expect(pack.mainModule.notifyAboutCurrent).not.toHaveBeenCalled();
|
||||
|
||||
latestVersion = "1.0.7";
|
||||
|
||||
pack.mainModule.checkForUpdates();
|
||||
await wait(200);
|
||||
expect(pack.mainModule.notifyAboutUpdate).toHaveBeenCalledWith("1.0.7");
|
||||
expect(pack.mainModule.notifyAboutCurrent).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
73
packages/pulsar-updater/src/cache.js
Normal file
73
packages/pulsar-updater/src/cache.js
Normal file
@ -0,0 +1,73 @@
|
||||
// Simple caching utilities
|
||||
|
||||
// The rough shape of an object will be: (This matches the cache in settings-view)
|
||||
// {
|
||||
// "createdOn": "epoch time",
|
||||
// "data": "cache object"
|
||||
// }
|
||||
|
||||
function setCacheItem(key, item) {
|
||||
let obj = {
|
||||
createdOn: Date.now(),
|
||||
data: JSON.stringify(item),
|
||||
};
|
||||
|
||||
localStorage.setItem(cacheKeyForPath(key), JSON.stringify(obj));
|
||||
}
|
||||
|
||||
function getCacheItem(key) {
|
||||
let obj = localStorage.getItem(cacheKeyForPath(key));
|
||||
if (!obj) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let cached = JSON.parse(obj);
|
||||
|
||||
if (typeof cached === "object" && !isItemExpired(cached)) {
|
||||
return JSON.parse(cached.data);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function empty(key) {
|
||||
localStorage.removeItem(cacheKeyForPath(key));
|
||||
}
|
||||
|
||||
function isItemExpired(item, key) {
|
||||
if (key === "last-update-check") {
|
||||
// the last update check item never expires, to ensure skipping version
|
||||
// preferences are permanent
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!online() || Date.now() - item.createdOn < expiry()) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function online() {
|
||||
return navigator.onLine;
|
||||
}
|
||||
|
||||
function cacheKeyForPath(path) {
|
||||
return `pulsar-updater:${path}`;
|
||||
}
|
||||
|
||||
function expiry() {
|
||||
// TODO get this from the package's config
|
||||
|
||||
// 5 hour expiry by default
|
||||
return 1000 * 60 * 60 * 5;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
setCacheItem,
|
||||
getCacheItem,
|
||||
isItemExpired,
|
||||
empty,
|
||||
cacheKeyForPath,
|
||||
online,
|
||||
};
|
135
packages/pulsar-updater/src/find-install-channel.js
Normal file
135
packages/pulsar-updater/src/find-install-channel.js
Normal file
@ -0,0 +1,135 @@
|
||||
const Registry = require("winreg");
|
||||
const shell = require("shelljs");
|
||||
const fs = require("fs");
|
||||
|
||||
// https://github.com/shelljs/shelljs/wiki/Electron-compatibility
|
||||
// ShellJS is not totally compatible within Electron.
|
||||
// We may need to look at running this within a task, but otherwise this should be
|
||||
// sufficient to get `exec` working
|
||||
shell.config.execPath = shell.which("node").toString();
|
||||
|
||||
function windows_isUserInstalled() {
|
||||
return new Promise((resolve, reject) => {
|
||||
let userInstallReg = new Registry({
|
||||
hive: "HKCU",
|
||||
key: "\\SOFTWARE\\0949b555-c22c-56b7-873a-a960bdefa81f",
|
||||
});
|
||||
|
||||
userInstallReg.keyExists((err, exists) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
}
|
||||
|
||||
resolve(exists);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function windows_isMachineInstalled() {
|
||||
return new Promise((resolve, reject) => {
|
||||
let machineInstallReg = new Registry({
|
||||
hive: "HKLM",
|
||||
key: "\\SOFTWARE\\0949b555-c22c-56b7-873a-a960bdefa81f",
|
||||
});
|
||||
|
||||
machineInstallReg.keyExists((err, exists) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
}
|
||||
|
||||
resolve(exists);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function windows_chocoInstalled() {
|
||||
if (!shell.which("choco")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let chocoCheck = shell.exec("choco list --local-only");
|
||||
|
||||
if (chocoCheck.code !== 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return chocoCheck.stdout.includes("pulsar");
|
||||
}
|
||||
|
||||
function windows_wingetInstalled() {
|
||||
if (!shell.which("winget")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let wingetCheck = shell.exec("winget show Pulsar");
|
||||
|
||||
if (wingetCheck.code !== 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return wingetCheck.stdout.includes("Pulsar");
|
||||
}
|
||||
|
||||
function linux_macos_homebrewInstalled() {
|
||||
if (!shell.which("brew")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let homebrewCheck = shell.exec("brew list 'pulsar'");
|
||||
|
||||
if (homebrewCheck.code !== 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return homebrewCheck.stdout.includes("pulsar");
|
||||
}
|
||||
|
||||
function linux_nixInstalled() {
|
||||
if (!fs.existsSync("/nix/store")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!shell.which("find")) {
|
||||
// A little dishonest, but we need this to check if it exists so..
|
||||
return false;
|
||||
}
|
||||
|
||||
shell.cd("/nix/store");
|
||||
|
||||
let nixCheck = shell.exec('find -maxdepth 1 -name "*pulsar.nemo_action"');
|
||||
|
||||
if (nixCheck.code !== 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return nixCheck.stdout.includes("pulsar.nemo_action");
|
||||
}
|
||||
|
||||
function linux_debGetInstalled() {
|
||||
if (!shell.which("deb-get")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let debGetCheck = shell.exec("deb-get list --installed");
|
||||
|
||||
if (debGetCheck.code !== 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return debGetCheck.stdout.includes("pulsar");
|
||||
}
|
||||
|
||||
function linux_flatpakInstalled() {
|
||||
return process.env.FLATPAK_ID === "dev.pulsar_edit.Pulsar";
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
windows_isUserInstalled,
|
||||
windows_isMachineInstalled,
|
||||
windows_chocoInstalled,
|
||||
windows_wingetInstalled,
|
||||
linux_macos_homebrewInstalled,
|
||||
linux_nixInstalled,
|
||||
linux_debGetInstalled,
|
||||
linux_flatpakInstalled,
|
||||
};
|
134
packages/pulsar-updater/src/find-install-method.js
Normal file
134
packages/pulsar-updater/src/find-install-method.js
Normal file
@ -0,0 +1,134 @@
|
||||
const findInstallChannel = require("./find-install-channel.js");
|
||||
|
||||
const INSTALL_CHANNELS = {
|
||||
macos: {
|
||||
fallback: "Manual Installation",
|
||||
channels: [
|
||||
{
|
||||
string: "Homebrew Installation",
|
||||
func: findInstallChannel.linux_macos_homebrewInstalled,
|
||||
},
|
||||
],
|
||||
},
|
||||
linux: {
|
||||
fallback: "Manual Installation",
|
||||
channels: [
|
||||
{
|
||||
string: "Flatpak Installation",
|
||||
func: findInstallChannel.linux_flatpakInstalled,
|
||||
},
|
||||
{
|
||||
string: "Deb-Get Installation",
|
||||
func: findInstallChannel.linux_debGetInstalled,
|
||||
},
|
||||
{
|
||||
string: "Nix Installation",
|
||||
func: findInstallChannel.linux_nixInstalled,
|
||||
},
|
||||
{
|
||||
string: "Homebrew Installation",
|
||||
func: findInstallChannel.linux_macos_homebrewInstalled,
|
||||
},
|
||||
// TODO AUR
|
||||
],
|
||||
},
|
||||
windows: {
|
||||
fallback: "Portable Installation",
|
||||
channels: [
|
||||
{
|
||||
string: "Chocolatey Installation",
|
||||
func: findInstallChannel.windows_chocoInstalled,
|
||||
},
|
||||
{
|
||||
string: "winget Installation",
|
||||
func: findInstallChannel.windows_wingetInstalled,
|
||||
},
|
||||
// We must check for package installs on windows before, user & machine
|
||||
// Since package installs trigger either a user or machine install
|
||||
{
|
||||
string: "User Installation",
|
||||
func: findInstallChannel.windows_isUserInstalled,
|
||||
},
|
||||
{
|
||||
string: "Machine Installation",
|
||||
func: findInstallChannel.windows_isMachineInstalled,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
// This module will do whatever it can to determine the installation method.
|
||||
// This doesn't just mean to determine what platform Pulsar is installed on
|
||||
// this also means to determine what program installed it, and what variant
|
||||
// of the Pulsar binary is in use.
|
||||
|
||||
async function main() {
|
||||
let returnValue = "";
|
||||
|
||||
if (atom.inDevMode()) {
|
||||
returnValue = "Developer Mode";
|
||||
}
|
||||
|
||||
if (atom.inSafeMode()) {
|
||||
returnValue = "Safe Mode";
|
||||
}
|
||||
|
||||
if (atom.inSpecMode()) {
|
||||
returnValue = "Spec Mode";
|
||||
}
|
||||
|
||||
if (returnValue.length > 0) {
|
||||
// Return early
|
||||
return {
|
||||
platform: process.platform,
|
||||
arch: process.arch,
|
||||
installMethod: returnValue,
|
||||
};
|
||||
}
|
||||
|
||||
if (process.platform === "win32") {
|
||||
returnValue = await determineChannel(
|
||||
INSTALL_CHANNELS.windows.channels,
|
||||
INSTALL_CHANNELS.windows.fallback
|
||||
);
|
||||
} else if (process.platform === "darwin") {
|
||||
returnValue = await determineChannel(
|
||||
INSTALL_CHANNELS.macos.channels,
|
||||
INSTALL_CHANNELS.macos.fallback
|
||||
);
|
||||
} else if (process.platform === "linux") {
|
||||
returnValue = await determineChannel(
|
||||
INSTALL_CHANNELS.linux.channels,
|
||||
INSTALL_CHANNELS.linux.fallback
|
||||
);
|
||||
}
|
||||
// Unused aix, freebsd, openbsd, sunos, android
|
||||
|
||||
return {
|
||||
platform: process.platform,
|
||||
arch: process.arch,
|
||||
installMethod: returnValue,
|
||||
};
|
||||
}
|
||||
|
||||
async function determineChannel(channels, fallback) {
|
||||
for (let i = 0; i < channels.length; i++) {
|
||||
let channel = channels[i];
|
||||
|
||||
let install = await channel.func();
|
||||
|
||||
if (
|
||||
typeof install === "boolean" &&
|
||||
install &&
|
||||
typeof channel.string === "string"
|
||||
) {
|
||||
return channel.string;
|
||||
}
|
||||
}
|
||||
|
||||
// Since we know that Pulsar hasn't been installed via an above method,
|
||||
// we should assume the fallback method
|
||||
return fallback;
|
||||
}
|
||||
|
||||
module.exports = main;
|
20
packages/pulsar-updater/src/find-newest-release.js
Normal file
20
packages/pulsar-updater/src/find-newest-release.js
Normal file
@ -0,0 +1,20 @@
|
||||
let superagent;
|
||||
|
||||
module.exports =
|
||||
async function findNewestRelease() {
|
||||
superagent ??= require("superagent");
|
||||
|
||||
let res = await superagent
|
||||
.get("https://api.github.com/repos/pulsar-edit/pulsar/releases")
|
||||
.set("Accept", "application/vnd.github+json")
|
||||
.set("User-Agent", "Pulsar.Pulsar-Updater");
|
||||
|
||||
if (res.status !== 200) {
|
||||
// Lie and say it's something that will never update
|
||||
return "0.0.0";
|
||||
}
|
||||
|
||||
// We can be fast and simply check if the top of the array is newer than our
|
||||
// current version. Since the return is ordered.
|
||||
return res.body[0].tag_name;
|
||||
}
|
231
packages/pulsar-updater/src/main.js
Normal file
231
packages/pulsar-updater/src/main.js
Normal file
@ -0,0 +1,231 @@
|
||||
const { CompositeDisposable } = require("atom");
|
||||
|
||||
let shell;
|
||||
let superagent;
|
||||
let findInstallMethod;
|
||||
|
||||
class PulsarUpdater {
|
||||
activate() {
|
||||
this.disposables = new CompositeDisposable();
|
||||
this.cache = require("./cache.js");
|
||||
|
||||
this.disposables.add(
|
||||
atom.commands.add("atom-workspace", {
|
||||
"pulsar-updater:check-for-update": () => {
|
||||
this.checkForUpdates({ manual: true });
|
||||
},
|
||||
"pulsar-updater:clear-cache": () => {
|
||||
this.cache.empty("last-update-check");
|
||||
this.cache.empty(`installMethod.${atom.getVersion()}`);
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
if (atom.config.get("pulsar-updater.checkForUpdatesOnLaunch")) {
|
||||
this.checkForUpdates();
|
||||
}
|
||||
}
|
||||
|
||||
deactivate() {
|
||||
this.disposables.dispose();
|
||||
this.cache = null;
|
||||
}
|
||||
|
||||
async findNewestRelease() {
|
||||
superagent ??= require("superagent");
|
||||
|
||||
let res = await superagent
|
||||
.get("https://api.github.com/repos/pulsar-edit/pulsar/releases")
|
||||
.set("Accept", "application/vnd.github+json")
|
||||
.set("User-Agent", "Pulsar.Pulsar-Updater");
|
||||
|
||||
if (res.status !== 200) {
|
||||
// Lie and say it's something that will never update
|
||||
return "0.0.0";
|
||||
}
|
||||
|
||||
// We get the results ordered by newest tag first, so we can just check the
|
||||
// first item.
|
||||
return res.body[0].tag_name;
|
||||
}
|
||||
|
||||
async checkForUpdates({ manual = false } = {}) {
|
||||
let cachedUpdateCheck = this.cache.getCacheItem("last-update-check");
|
||||
|
||||
// Null means that there is no previous check, or the last check expired
|
||||
let latestVersion = await this.findNewestRelease();
|
||||
let shouldUpdate = !atom.versionSatisfies(`>= ${latestVersion}`);
|
||||
|
||||
if (
|
||||
cachedUpdateCheck?.latestVersion === latestVersion &&
|
||||
!cachedUpdateCheck?.shouldUpdate
|
||||
) {
|
||||
// The user has already been notified about this version and told us not
|
||||
// to notify them again until the next release.
|
||||
if (manual) {
|
||||
await this.notifyAboutUpdate(latestVersion);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (shouldUpdate) {
|
||||
await this.notifyAboutUpdate(latestVersion);
|
||||
} else {
|
||||
// This can be a no-op or something that generates an actual notification
|
||||
// based on how the update check was invoked.
|
||||
await this.notifyAboutCurrent(latestVersion, manual);
|
||||
}
|
||||
}
|
||||
|
||||
notifyAboutCurrent(latestVersion, manual) {
|
||||
if (!manual) return;
|
||||
atom.notifications.addInfo(
|
||||
"Pulsar is already up to date.",
|
||||
{ dismissable: true }
|
||||
);
|
||||
}
|
||||
|
||||
async notifyAboutUpdate(latestVersion) {
|
||||
this.cache.setCacheItem("last-update-check", {
|
||||
latestVersion: latestVersion,
|
||||
shouldUpdate: true
|
||||
});
|
||||
|
||||
findInstallMethod ??= require("./find-install-method.js");
|
||||
|
||||
let installMethod =
|
||||
this.cache.getCacheItem(`installMethod.${atom.getVersion()}`) ??
|
||||
(await findInstallMethod());
|
||||
|
||||
this.cache.setCacheItem(
|
||||
`installMethod.${atom.getVersion()}`,
|
||||
installMethod
|
||||
);
|
||||
|
||||
let objButtonForInstallMethod = this.getObjButtonForInstallMethod(installMethod);
|
||||
let notificationDetailText = this.getNotificationText(installMethod, latestVersion);
|
||||
|
||||
// Notification text of `null` means that we shouldn't show a notification
|
||||
// after all.
|
||||
if (notificationDetailText === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const notification = atom.notifications.addInfo(
|
||||
"An update for Pulsar is available.",
|
||||
{
|
||||
description: notificationDetailText,
|
||||
dismissable: true,
|
||||
buttons: [
|
||||
{
|
||||
text: "Dismiss this Version",
|
||||
onDidClick: () => {
|
||||
this.ignoreForThisVersion(latestVersion);
|
||||
notification.dismiss();
|
||||
},
|
||||
},
|
||||
{
|
||||
text: "Dismiss until next launch",
|
||||
onDidClick: () => {
|
||||
this.ignoreUntilNextLaunch();
|
||||
notification.dismiss();
|
||||
},
|
||||
},
|
||||
// Below we optionally add a button for the install method. That may
|
||||
// open to a pulsar download URL, if available for installation method
|
||||
typeof objButtonForInstallMethod === "object" &&
|
||||
objButtonForInstallMethod
|
||||
],
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
ignoreForThisVersion(version) {
|
||||
this.cache.setCacheItem("last-update-check", {
|
||||
latestVersion: version,
|
||||
shouldUpdate: false
|
||||
});
|
||||
}
|
||||
|
||||
ignoreUntilNextLaunch() {
|
||||
// emptying the cache, will cause the next check to succeed
|
||||
this.cache.empty("last-update-check");
|
||||
}
|
||||
|
||||
getNotificationText(installMethod, latestVersion) {
|
||||
let returnText = `Pulsar ${latestVersion} is available.\n`;
|
||||
|
||||
switch (installMethod.installMethod) {
|
||||
case "Developer Mode":
|
||||
returnText +=
|
||||
"Since you're in developer mode, Pulsy trusts you know how to update. :)";
|
||||
break;
|
||||
case "Safe Mode":
|
||||
return null;
|
||||
break;
|
||||
case "Spec Mode":
|
||||
return null;
|
||||
break;
|
||||
case "Flatpak Installation":
|
||||
returnText += "Install the latest version by running `flatpak update`.";
|
||||
break;
|
||||
case "Deb-Get Installation":
|
||||
returnText +=
|
||||
"Install the latest version by running `sudo deb-get update`.";
|
||||
break;
|
||||
case "Nix Installation":
|
||||
// TODO find nix update command
|
||||
returnText += "Install the latest version via Nix.";
|
||||
break;
|
||||
case "Homebrew Installation":
|
||||
returnText +=
|
||||
"Install the latest version by running `brew upgrade pulsar`.";
|
||||
break;
|
||||
case "winget Installation":
|
||||
returnText +=
|
||||
"Install the latest version by running `winget upgrade pulsar`.";
|
||||
break;
|
||||
case "Chocolatey Installation":
|
||||
returnText +=
|
||||
"Install the latest version by running `choco upgrade pulsar`.";
|
||||
break;
|
||||
case "User Installation":
|
||||
case "Machine Installation":
|
||||
case "Portable Installation":
|
||||
case "Manual Installation":
|
||||
default:
|
||||
returnText +=
|
||||
"Download the latest version from the Pulsar Website or GitHub.";
|
||||
break;
|
||||
}
|
||||
|
||||
return returnText;
|
||||
}
|
||||
|
||||
getObjButtonForInstallMethod(installMethod) {
|
||||
let returnObj = null;
|
||||
|
||||
const openWebGitHub = (e) => {
|
||||
e.preventDefault();
|
||||
shell ??= shell || require("electron").shell;
|
||||
let latestVersion = this.cache.getCacheItem("last-update-check")?.latestVersion;
|
||||
let tagSegment = latestVersion ? `tag/${latestVersion}` : "";
|
||||
shell.openExternal(`https://github.com/pulsar-edit/pulsar/releases/${tagSegment}`);
|
||||
};
|
||||
|
||||
switch (installMethod.installMethod) {
|
||||
case "User Installation":
|
||||
case "Machine Installation":
|
||||
default:
|
||||
returnObj = {
|
||||
text: "Download from GitHub",
|
||||
onDidClick: openWebGitHub,
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
return returnObj;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new PulsarUpdater();
|
@ -225,6 +225,26 @@ describe('StyleManager', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('recognizes valid less variables: right side', () => {
|
||||
let upgradedSheet = mathStyleManager.upgradeDeprecatedMathUsageForStyleSheet(
|
||||
"p { padding: @size + 12px; }",
|
||||
{}
|
||||
);
|
||||
expect(upgradedSheet.source).toEqual(
|
||||
"p { padding: calc(@size + 12px); }"
|
||||
);
|
||||
});
|
||||
|
||||
it('recognizes valid less variables: left side', () => {
|
||||
let upgradedSheet = mathStyleManager.upgradeDeprecatedMathUsageForStyleSheet(
|
||||
"p { padding: 12px + @size; }",
|
||||
{}
|
||||
);
|
||||
expect(upgradedSheet.source).toEqual(
|
||||
"p { padding: calc(12px + @size); }"
|
||||
);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('when a sourcePath parameter is specified', () => {
|
||||
|
@ -437,7 +437,7 @@ function transformDeprecatedMathUsage(css, context) {
|
||||
const cssValueIgnoreList = /hsl|abs|acos|asin|atan|atan2|cos|mod|rem|sign|sin|tan|url/g;
|
||||
|
||||
const mathExpressionRegex =
|
||||
/-*(\d(\.\d)?)+(cm|mm|Q|in|pc|pt|px|em|ex|ch|rem|lh|rlh|vw|vh|vmin|vmax|vb|vi|svw|svh|lvw|lvh|dvw|dvh|%)?(\s*([\/\+\*]|(\-\s+))\s*(\d(\.\d)*)+(cm|mm|Q|in|pc|pt|px|em|ex|ch|rem|lh|rlh|vw|vh|vmin|vmax|vb|vi|svw|svh|lvw|lvh|dvw|dvh|%)?)+/g;
|
||||
/(-*(\d(\.\d)?)+(cm|mm|Q|in|pc|pt|px|em|ex|ch|rem|lh|rlh|vw|vh|vmin|vmax|vb|vi|svw|svh|lvw|lvh|dvw|dvh|%)?|@?[\w-]+)(\s*([\/\+\*]|(\-\s+))\s*((\d(\.\d)*)+(cm|mm|Q|in|pc|pt|px|em|ex|ch|rem|lh|rlh|vw|vh|vmin|vmax|vb|vi|svw|svh|lvw|lvh|dvw|dvh|%)?|@?[\w-]+))+/g;
|
||||
|
||||
try {
|
||||
transformedSource = postcss.parse(css);
|
||||
|
131
yarn.lock
131
yarn.lock
@ -2198,7 +2198,7 @@ array.prototype.reduce@^1.0.5:
|
||||
es-array-method-boxes-properly "^1.0.0"
|
||||
is-string "^1.0.7"
|
||||
|
||||
asap@~2.0.3:
|
||||
asap@^2.0.0, asap@~2.0.3:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
|
||||
integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==
|
||||
@ -3237,6 +3237,11 @@ compare-version@^0.1.2:
|
||||
resolved "https://registry.yarnpkg.com/compare-version/-/compare-version-0.1.2.tgz#0162ec2d9351f5ddd59a9202cba935366a725080"
|
||||
integrity sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==
|
||||
|
||||
component-emitter@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0"
|
||||
integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==
|
||||
|
||||
compress-commons@^4.1.0:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-4.1.1.tgz#df2a09a7ed17447642bad10a85cc9a19e5c42a7d"
|
||||
@ -3299,6 +3304,11 @@ convert-source-map@^1.1.0, convert-source-map@^1.7.0:
|
||||
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f"
|
||||
integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==
|
||||
|
||||
cookiejar@^2.1.4:
|
||||
version "2.1.4"
|
||||
resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.4.tgz#ee669c1fea2cf42dc31585469d193fef0d65771b"
|
||||
integrity sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==
|
||||
|
||||
copy-anything@^2.0.1:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/copy-anything/-/copy-anything-2.0.6.tgz#092454ea9584a7b7ad5573062b2a87f5900fc480"
|
||||
@ -3676,6 +3686,14 @@ devtools@7.20.8:
|
||||
ua-parser-js "^1.0.1"
|
||||
uuid "^8.0.0"
|
||||
|
||||
dezalgo@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.4.tgz#751235260469084c132157dfa857f386d4c33d81"
|
||||
integrity sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==
|
||||
dependencies:
|
||||
asap "^2.0.0"
|
||||
wrappy "1"
|
||||
|
||||
diff@3.5.0:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
|
||||
@ -4365,6 +4383,10 @@ event-kit@^1.0.0, event-kit@^1.0.2:
|
||||
dependencies:
|
||||
grim "^1.2.1"
|
||||
|
||||
"event-kit@github:pulsar-edit/event-kit":
|
||||
version "2.5.3"
|
||||
resolved "https://codeload.github.com/pulsar-edit/event-kit/tar.gz/80b551c1d03dd05795500f0c71dcf15be3a23c63"
|
||||
|
||||
event-stream@~3.1.0:
|
||||
version "3.1.7"
|
||||
resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.1.7.tgz#b4c540012d0fe1498420f3d8946008db6393c37a"
|
||||
@ -4453,6 +4475,11 @@ fast-levenshtein@^2.0.6:
|
||||
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
|
||||
integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
|
||||
|
||||
fast-safe-stringify@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884"
|
||||
integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==
|
||||
|
||||
fastq@^1.6.0:
|
||||
version "1.13.0"
|
||||
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c"
|
||||
@ -4624,6 +4651,16 @@ form-data@~2.3.2:
|
||||
combined-stream "^1.0.6"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
formidable@^2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/formidable/-/formidable-2.1.2.tgz#fa973a2bec150e4ce7cac15589d7a25fc30ebd89"
|
||||
integrity sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==
|
||||
dependencies:
|
||||
dezalgo "^1.0.4"
|
||||
hexoid "^1.0.0"
|
||||
once "^1.4.0"
|
||||
qs "^6.11.0"
|
||||
|
||||
from@~0:
|
||||
version "0.1.7"
|
||||
resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe"
|
||||
@ -4992,7 +5029,7 @@ glob@7.1.3:
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.2.0:
|
||||
glob@^7.0.0, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.2.0:
|
||||
version "7.2.3"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
|
||||
integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
|
||||
@ -5234,6 +5271,11 @@ he@1.2.0:
|
||||
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
|
||||
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
|
||||
|
||||
hexoid@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/hexoid/-/hexoid-1.0.0.tgz#ad10c6573fb907de23d9ec63a711267d9dc9bc18"
|
||||
integrity sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==
|
||||
|
||||
hosted-git-info@^2.8.9:
|
||||
version "2.8.9"
|
||||
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9"
|
||||
@ -5437,6 +5479,11 @@ internal-slot@^1.0.3:
|
||||
has "^1.0.3"
|
||||
side-channel "^1.0.4"
|
||||
|
||||
interpret@^1.0.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e"
|
||||
integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==
|
||||
|
||||
invert-kv@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6"
|
||||
@ -5523,6 +5570,13 @@ is-core-module@^2.0.0, is-core-module@^2.9.0:
|
||||
dependencies:
|
||||
has "^1.0.3"
|
||||
|
||||
is-core-module@^2.11.0:
|
||||
version "2.12.1"
|
||||
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd"
|
||||
integrity sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==
|
||||
dependencies:
|
||||
has "^1.0.3"
|
||||
|
||||
is-date-object@^1.0.1, is-date-object@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f"
|
||||
@ -6652,6 +6706,11 @@ mdurl@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
|
||||
integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==
|
||||
|
||||
methods@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
|
||||
integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==
|
||||
|
||||
mime-db@1.52.0:
|
||||
version "1.52.0"
|
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
|
||||
@ -6664,16 +6723,16 @@ mime-types@^2.1.12, mime-types@~2.1.19:
|
||||
dependencies:
|
||||
mime-db "1.52.0"
|
||||
|
||||
mime@2.6.0, mime@^2.5.2:
|
||||
version "2.6.0"
|
||||
resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367"
|
||||
integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==
|
||||
|
||||
mime@^1.4.1:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
|
||||
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
|
||||
|
||||
mime@^2.5.2:
|
||||
version "2.6.0"
|
||||
resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367"
|
||||
integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==
|
||||
|
||||
mimic-fn@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
|
||||
@ -7792,6 +7851,14 @@ psl@^1.1.28:
|
||||
resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7"
|
||||
integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==
|
||||
|
||||
"pulsar-updater@file:packages/pulsar-updater":
|
||||
version "1.0.0"
|
||||
dependencies:
|
||||
event-kit "github:pulsar-edit/event-kit"
|
||||
shelljs "^0.8.5"
|
||||
superagent "^8.0.9"
|
||||
winreg "^1.2.4"
|
||||
|
||||
pump@^1.0.0:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.3.tgz#5dfe8311c33bbf6fc18261f9f34702c47c08a954"
|
||||
@ -7846,6 +7913,13 @@ puppeteer-core@^13.1.3:
|
||||
unbzip2-stream "1.4.3"
|
||||
ws "8.5.0"
|
||||
|
||||
qs@^6.11.0:
|
||||
version "6.11.2"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.2.tgz#64bea51f12c1f5da1bc01496f48ffcff7c69d7d9"
|
||||
integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==
|
||||
dependencies:
|
||||
side-channel "^1.0.4"
|
||||
|
||||
qs@~6.5.2:
|
||||
version "6.5.3"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad"
|
||||
@ -7993,6 +8067,13 @@ readdirp@~3.6.0:
|
||||
dependencies:
|
||||
picomatch "^2.2.1"
|
||||
|
||||
rechoir@^0.6.2:
|
||||
version "0.6.2"
|
||||
resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
|
||||
integrity sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==
|
||||
dependencies:
|
||||
resolve "^1.1.6"
|
||||
|
||||
reduce-extract@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/reduce-extract/-/reduce-extract-1.0.0.tgz#67f2385beda65061b5f5f4312662e8b080ca1525"
|
||||
@ -8177,6 +8258,15 @@ resolve@1.18.1:
|
||||
is-core-module "^2.0.0"
|
||||
path-parse "^1.0.6"
|
||||
|
||||
resolve@^1.1.6:
|
||||
version "1.22.2"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f"
|
||||
integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==
|
||||
dependencies:
|
||||
is-core-module "^2.11.0"
|
||||
path-parse "^1.0.7"
|
||||
supports-preserve-symlinks-flag "^1.0.0"
|
||||
|
||||
resolve@^1.10.1, resolve@^1.12.0, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.3.2:
|
||||
version "1.22.1"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177"
|
||||
@ -8495,6 +8585,15 @@ shebang-regex@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
|
||||
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
|
||||
|
||||
shelljs@^0.8.5:
|
||||
version "0.8.5"
|
||||
resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c"
|
||||
integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==
|
||||
dependencies:
|
||||
glob "^7.0.0"
|
||||
interpret "^1.0.0"
|
||||
rechoir "^0.6.2"
|
||||
|
||||
side-channel@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
|
||||
@ -8928,6 +9027,22 @@ sumchecker@^3.0.1:
|
||||
dependencies:
|
||||
debug "^4.1.0"
|
||||
|
||||
superagent@^8.0.9:
|
||||
version "8.0.9"
|
||||
resolved "https://registry.yarnpkg.com/superagent/-/superagent-8.0.9.tgz#2c6fda6fadb40516515f93e9098c0eb1602e0535"
|
||||
integrity sha512-4C7Bh5pyHTvU33KpZgwrNKh/VQnvgtCSqPRfJAUdmrtSYePVzVg4E4OzsrbkhJj9O7SO6Bnv75K/F8XVZT8YHA==
|
||||
dependencies:
|
||||
component-emitter "^1.3.0"
|
||||
cookiejar "^2.1.4"
|
||||
debug "^4.3.4"
|
||||
fast-safe-stringify "^2.1.1"
|
||||
form-data "^4.0.0"
|
||||
formidable "^2.1.2"
|
||||
methods "^1.1.2"
|
||||
mime "2.6.0"
|
||||
qs "^6.11.0"
|
||||
semver "^7.3.8"
|
||||
|
||||
superstring@^2.4.4:
|
||||
version "2.4.4"
|
||||
resolved "https://registry.yarnpkg.com/superstring/-/superstring-2.4.4.tgz#d5df5b080deb5605ffd88b6cdbaf17a0b30d5f0e"
|
||||
@ -9912,7 +10027,7 @@ window-size@^0.1.4:
|
||||
resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876"
|
||||
integrity sha512-2thx4pB0cV3h+Bw7QmMXcEbdmOzv9t0HFplJH/Lz6yu60hXYy5RT8rUu+wlIreVxWsGN20mo+MHeCSfUpQBwPw==
|
||||
|
||||
winreg@^1.2.1:
|
||||
winreg@^1.2.1, winreg@^1.2.4:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/winreg/-/winreg-1.2.4.tgz#ba065629b7a925130e15779108cf540990e98d1b"
|
||||
integrity sha512-IHpzORub7kYlb8A43Iig3reOvlcBJGX9gZ0WycHhghHtA65X0LYnMRuJs+aH1abVnMJztQkvQNlltnbPi5aGIA==
|
||||
|
Loading…
Reference in New Issue
Block a user