mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-13 15:35:20 +01:00
Merge branch 'main' into notebook-serialization-worker
This commit is contained in:
+4
-1
@@ -693,6 +693,7 @@
|
||||
"when": "hasNode",
|
||||
"allow": [
|
||||
"@parcel/watcher",
|
||||
"@bpasero/watcher",
|
||||
"@vscode/sqlite3",
|
||||
"@vscode/vscode-languagedetection",
|
||||
"@vscode/ripgrep",
|
||||
@@ -846,7 +847,8 @@
|
||||
"vs/platform/*/~",
|
||||
"vs/editor/~",
|
||||
"vs/editor/contrib/*/~",
|
||||
"vs/editor/standalone/~"
|
||||
"vs/editor/standalone/~",
|
||||
"@vscode/tree-sitter-wasm" // type import
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -932,6 +934,7 @@
|
||||
"tas-client-umd", // node module allowed even in /common/
|
||||
"vscode-textmate", // node module allowed even in /common/
|
||||
"@vscode/vscode-languagedetection", // node module allowed even in /common/
|
||||
"@vscode/tree-sitter-wasm", // type import
|
||||
{
|
||||
"when": "hasBrowser",
|
||||
"pattern": "@xterm/xterm"
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
"languages-basic": {"assign": ["aeschli"]},
|
||||
"languages-diagnostics": {"assign": ["jrieken"]},
|
||||
"languages-guessing": {"assign": ["TylerLeonhardt"]},
|
||||
"layout": {"assign": ["sbatten"]},
|
||||
"layout": {"assign": ["benibenj"]},
|
||||
"lcd-text-rendering": {"assign": []},
|
||||
"list-widget": {"assign": ["joaomoreno"]},
|
||||
"live-preview": {"assign": ["andreamah"]},
|
||||
@@ -249,7 +249,7 @@
|
||||
"timeline": {"assign": ["lramos15"]},
|
||||
"timeline-git": {"assign": ["lszomoru"]},
|
||||
"timeline-local-history": {"assign": ["bpasero"]},
|
||||
"titlebar": {"assign": ["sbatten"]},
|
||||
"titlebar": {"assign": ["benibenj"]},
|
||||
"tokenization": {"assign": ["alexdima"]},
|
||||
"touch/pointer": {"assign": []},
|
||||
"trackpad/scroll": {"assign": []},
|
||||
@@ -278,7 +278,7 @@
|
||||
"workbench-cli": {"assign": ["bpasero"]},
|
||||
"workbench-diagnostics": {"assign": ["Tyriar"]},
|
||||
"workbench-dnd": {"assign": ["bpasero"]},
|
||||
"workbench-editor-grid": {"assign": ["sbatten"]},
|
||||
"workbench-editor-grid": {"assign": ["benibenj"]},
|
||||
"workbench-editor-groups": {"assign": ["bpasero"]},
|
||||
"workbench-editor-resolver": {"assign": ["lramos15"]},
|
||||
"workbench-editors": {"assign": ["bpasero"]},
|
||||
@@ -299,11 +299,11 @@
|
||||
"workbench-tabs": {"assign": ["benibenj"]},
|
||||
"workbench-touchbar": {"assign": ["bpasero"]},
|
||||
"workbench-untitled-editors": {"assign": ["bpasero"]},
|
||||
"workbench-views": {"assign": ["sbatten"]},
|
||||
"workbench-views": {"assign": ["benibenj"]},
|
||||
"workbench-welcome": {"assign": ["lramos15"]},
|
||||
"workbench-window": {"assign": ["bpasero"]},
|
||||
"workbench-workspace": {"assign": []},
|
||||
"workbench-zen": {"assign": ["sbatten"]},
|
||||
"workbench-zen": {"assign": ["benibenj"]},
|
||||
"workspace-edit": {"assign": ["jrieken"]},
|
||||
"workspace-symbols": {"assign": []},
|
||||
"workspace-trust": {"assign": ["lszomoru", "sbatten"]},
|
||||
|
||||
@@ -8,6 +8,7 @@ import * as vscode from 'vscode';
|
||||
import { TestCase, TestConstruct, TestSuite, VSCodeTest } from './testTree';
|
||||
|
||||
const suiteNames = new Set(['suite', 'flakySuite']);
|
||||
const testNames = new Set(['test']);
|
||||
|
||||
export const enum Action {
|
||||
Skip,
|
||||
@@ -19,22 +20,19 @@ export const extractTestFromNode = (src: ts.SourceFile, node: ts.Node, parent: V
|
||||
return Action.Recurse;
|
||||
}
|
||||
|
||||
let lhs = node.expression;
|
||||
if (isSkipCall(lhs)) {
|
||||
const asSuite = identifyCall(node.expression, suiteNames);
|
||||
const asTest = identifyCall(node.expression, testNames);
|
||||
const either = asSuite || asTest;
|
||||
if (either === IdentifiedCall.Skipped) {
|
||||
return Action.Skip;
|
||||
}
|
||||
|
||||
if (isPropertyCall(lhs) && lhs.name.text === 'only') {
|
||||
lhs = lhs.expression;
|
||||
if (either === IdentifiedCall.Nothing) {
|
||||
return Action.Recurse;
|
||||
}
|
||||
|
||||
const name = node.arguments[0];
|
||||
const func = node.arguments[1];
|
||||
if (!name || !ts.isIdentifier(lhs) || !ts.isStringLiteralLike(name)) {
|
||||
return Action.Recurse;
|
||||
}
|
||||
|
||||
if (!func) {
|
||||
if (!name || !ts.isStringLiteralLike(name) || !func) {
|
||||
return Action.Recurse;
|
||||
}
|
||||
|
||||
@@ -46,23 +44,45 @@ export const extractTestFromNode = (src: ts.SourceFile, node: ts.Node, parent: V
|
||||
);
|
||||
|
||||
const cparent = parent instanceof TestConstruct ? parent : undefined;
|
||||
if (lhs.escapedText === 'test') {
|
||||
|
||||
// we know this is either a suite or a test because we checked for skipped/nothing above
|
||||
|
||||
if (asTest) {
|
||||
return new TestCase(name.text, range, cparent);
|
||||
}
|
||||
|
||||
if (suiteNames.has(lhs.escapedText.toString())) {
|
||||
if (asSuite) {
|
||||
return new TestSuite(name.text, range, cparent);
|
||||
}
|
||||
|
||||
return Action.Recurse;
|
||||
throw new Error('unreachable');
|
||||
};
|
||||
|
||||
const enum IdentifiedCall {
|
||||
Nothing,
|
||||
Skipped,
|
||||
IsThing,
|
||||
}
|
||||
|
||||
const identifyCall = (lhs: ts.Node, needles: ReadonlySet<string>): IdentifiedCall => {
|
||||
if (ts.isIdentifier(lhs)) {
|
||||
return needles.has(lhs.escapedText || lhs.text) ? IdentifiedCall.IsThing : IdentifiedCall.Nothing;
|
||||
}
|
||||
|
||||
if (isPropertyCall(lhs) && lhs.name.text === 'skip') {
|
||||
return needles.has(lhs.expression.text) ? IdentifiedCall.Skipped : IdentifiedCall.Nothing;
|
||||
}
|
||||
|
||||
if (ts.isParenthesizedExpression(lhs) && ts.isConditionalExpression(lhs.expression)) {
|
||||
return Math.max(identifyCall(lhs.expression.whenTrue, needles), identifyCall(lhs.expression.whenFalse, needles));
|
||||
}
|
||||
|
||||
return IdentifiedCall.Nothing;
|
||||
};
|
||||
|
||||
const isPropertyCall = (
|
||||
lhs: ts.LeftHandSideExpression
|
||||
lhs: ts.Node
|
||||
): lhs is ts.PropertyAccessExpression & { expression: ts.Identifier; name: ts.Identifier } =>
|
||||
ts.isPropertyAccessExpression(lhs) &&
|
||||
ts.isIdentifier(lhs.expression) &&
|
||||
ts.isIdentifier(lhs.name);
|
||||
|
||||
const isSkipCall = (lhs: ts.LeftHandSideExpression) =>
|
||||
isPropertyCall(lhs) && suiteNames.has(lhs.expression.text) && lhs.name.text === 'skip';
|
||||
|
||||
@@ -110,6 +110,12 @@ node-pty/third_party/**
|
||||
@parcel/watcher/src/**
|
||||
!@parcel/watcher/build/Release/*.node
|
||||
|
||||
@bpasero/watcher/binding.gyp
|
||||
@bpasero/watcher/build/**
|
||||
@bpasero/watcher/prebuilds/**
|
||||
@bpasero/watcher/src/**
|
||||
!@bpasero/watcher/build/Release/*.node
|
||||
|
||||
vsda/build/**
|
||||
vsda/ci/**
|
||||
vsda/src/**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
parameters:
|
||||
- name: channel
|
||||
type: string
|
||||
default: 1.77
|
||||
default: 1.81
|
||||
- name: targets
|
||||
default: []
|
||||
type: object
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
parameters:
|
||||
- name: channel
|
||||
type: string
|
||||
default: 1.77
|
||||
default: 1.81
|
||||
- name: targets
|
||||
default: []
|
||||
type: object
|
||||
|
||||
@@ -101,7 +101,6 @@ const tasks = compilations.map(function (tsconfigFile) {
|
||||
}
|
||||
|
||||
function createPipeline(build, emitError, transpileOnly) {
|
||||
const nlsDev = require('vscode-nls-dev');
|
||||
const tsb = require('./lib/tsb');
|
||||
const sourcemaps = require('gulp-sourcemaps');
|
||||
|
||||
@@ -126,7 +125,6 @@ const tasks = compilations.map(function (tsconfigFile) {
|
||||
.pipe(tsFilter)
|
||||
.pipe(util.loadSourcemaps())
|
||||
.pipe(compilation())
|
||||
.pipe(build ? nlsDev.rewriteLocalizeCalls() : es.through())
|
||||
.pipe(build ? util.stripSourceMappingURL() : es.through())
|
||||
.pipe(sourcemaps.write('.', {
|
||||
sourceMappingURL: !build ? null : f => `${baseUrl}/${f.relative}.map`,
|
||||
@@ -136,9 +134,6 @@ const tasks = compilations.map(function (tsconfigFile) {
|
||||
sourceRoot: '../src/',
|
||||
}))
|
||||
.pipe(tsFilter.restore)
|
||||
.pipe(build ? nlsDev.bundleMetaDataFiles(headerId, headerOut) : es.through())
|
||||
// Filter out *.nls.json file. We needed them only to bundle meta data file.
|
||||
.pipe(filter(['**', '!**/*.nls.json'], { dot: true }))
|
||||
.pipe(reporter.end(emitError));
|
||||
|
||||
return es.duplex(input, output);
|
||||
|
||||
@@ -83,7 +83,8 @@ function nodeModules(destinationExe, destinationPdb, platform) {
|
||||
// We don't build the prebuilt node files so we don't scan them
|
||||
'!**/prebuilds/**/*.node',
|
||||
// These are 3rd party modules that we should ignore
|
||||
'!**/@parcel/watcher/**/*']))
|
||||
'!**/@parcel/watcher/**/*',
|
||||
'!**/@bpasero/watcher/**/*']))
|
||||
.pipe(gulp.dest(destinationExe));
|
||||
};
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ const pkg = require('../package.json');
|
||||
const product = require('../product.json');
|
||||
const vfs = require('vinyl-fs');
|
||||
const rcedit = require('rcedit');
|
||||
const mkdirp = require('mkdirp');
|
||||
|
||||
const repoPath = path.dirname(__dirname);
|
||||
const buildPath = (/** @type {string} */ arch) => path.join(path.dirname(repoPath), `VSCode-win32-${arch}`);
|
||||
@@ -75,7 +74,7 @@ function buildWin32Setup(arch, target) {
|
||||
|
||||
const sourcePath = buildPath(arch);
|
||||
const outputPath = setupDir(arch, target);
|
||||
mkdirp.sync(outputPath);
|
||||
fs.mkdirSync(outputPath, { recursive: true });
|
||||
|
||||
const originalProductJsonPath = path.join(sourcePath, 'resources/app/product.json');
|
||||
const productJsonPath = path.join(outputPath, 'product.json');
|
||||
|
||||
@@ -16,7 +16,6 @@ const vfs = require("vinyl-fs");
|
||||
const ext = require("./extensions");
|
||||
const fancyLog = require("fancy-log");
|
||||
const ansiColors = require("ansi-colors");
|
||||
const mkdirp = require('mkdirp');
|
||||
const root = path.dirname(path.dirname(__dirname));
|
||||
const productjson = JSON.parse(fs.readFileSync(path.join(__dirname, '../../product.json'), 'utf8'));
|
||||
const builtInExtensions = productjson.builtInExtensions || [];
|
||||
@@ -107,7 +106,7 @@ function readControlFile() {
|
||||
}
|
||||
}
|
||||
function writeControlFile(control) {
|
||||
mkdirp.sync(path.dirname(controlFilePath));
|
||||
fs.mkdirSync(path.dirname(controlFilePath), { recursive: true });
|
||||
fs.writeFileSync(controlFilePath, JSON.stringify(control, null, 2));
|
||||
}
|
||||
function getBuiltInExtensions() {
|
||||
|
||||
@@ -15,8 +15,6 @@ import * as fancyLog from 'fancy-log';
|
||||
import * as ansiColors from 'ansi-colors';
|
||||
import { Stream } from 'stream';
|
||||
|
||||
const mkdirp = require('mkdirp');
|
||||
|
||||
export interface IExtensionDefinition {
|
||||
name: string;
|
||||
version: string;
|
||||
@@ -147,7 +145,7 @@ function readControlFile(): IControlFile {
|
||||
}
|
||||
|
||||
function writeControlFile(control: IControlFile): void {
|
||||
mkdirp.sync(path.dirname(controlFilePath));
|
||||
fs.mkdirSync(path.dirname(controlFilePath), { recursive: true });
|
||||
fs.writeFileSync(controlFilePath, JSON.stringify(control, null, 2));
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,12 @@ function extractEditor(options) {
|
||||
// Add extra .d.ts files from `node_modules/@types/`
|
||||
if (Array.isArray(options.compilerOptions?.types)) {
|
||||
options.compilerOptions.types.forEach((type) => {
|
||||
options.typings.push(`../node_modules/@types/${type}/index.d.ts`);
|
||||
if (type === '@webgpu/types') {
|
||||
options.typings.push(`../node_modules/${type}/dist/index.d.ts`);
|
||||
}
|
||||
else {
|
||||
options.typings.push(`../node_modules/@types/${type}/index.d.ts`);
|
||||
}
|
||||
});
|
||||
}
|
||||
const result = tss.shake(options);
|
||||
|
||||
@@ -59,7 +59,11 @@ export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: str
|
||||
// Add extra .d.ts files from `node_modules/@types/`
|
||||
if (Array.isArray(options.compilerOptions?.types)) {
|
||||
options.compilerOptions.types.forEach((type: string) => {
|
||||
options.typings.push(`../node_modules/@types/${type}/index.d.ts`);
|
||||
if (type === '@webgpu/types') {
|
||||
options.typings.push(`../node_modules/${type}/dist/index.d.ts`);
|
||||
} else {
|
||||
options.typings.push(`../node_modules/@types/${type}/index.d.ts`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -546,9 +546,9 @@
|
||||
"--vscode-scmGraph-foreground1",
|
||||
"--vscode-scmGraph-foreground2",
|
||||
"--vscode-scmGraph-foreground3",
|
||||
"--vscode-scmGraph-historyItemGroupBase",
|
||||
"--vscode-scmGraph-historyItemGroupLocal",
|
||||
"--vscode-scmGraph-historyItemGroupRemote",
|
||||
"--vscode-scmGraph-historyItemBaseRefColor",
|
||||
"--vscode-scmGraph-historyItemRefColor",
|
||||
"--vscode-scmGraph-historyItemRemoteRefColor",
|
||||
"--vscode-scmGraph-historyItemHoverAdditionsForeground",
|
||||
"--vscode-scmGraph-historyItemHoverDefaultLabelBackground",
|
||||
"--vscode-scmGraph-historyItemHoverDefaultLabelForeground",
|
||||
@@ -881,4 +881,4 @@
|
||||
"--widget-color",
|
||||
"--text-link-decoration"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+8
-52
@@ -31,7 +31,6 @@
|
||||
"@types/mime": "0.0.29",
|
||||
"@types/minimatch": "^3.0.3",
|
||||
"@types/minimist": "^1.2.1",
|
||||
"@types/mkdirp": "^1.0.1",
|
||||
"@types/mocha": "^9.1.1",
|
||||
"@types/node": "20.x",
|
||||
"@types/pump": "^1.0.1",
|
||||
@@ -54,7 +53,6 @@
|
||||
"gulp-sort": "^2.0.0",
|
||||
"jsonc-parser": "^2.3.0",
|
||||
"mime": "^1.4.1",
|
||||
"mkdirp": "^1.0.4",
|
||||
"source-map": "0.6.1",
|
||||
"ternary-stream": "^3.0.0",
|
||||
"through2": "^4.0.2",
|
||||
@@ -133,9 +131,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@azure/core-http": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-3.0.0.tgz",
|
||||
"integrity": "sha512-BxI2SlGFPPz6J1XyZNIVUf0QZLBKFX+ViFjKOkzqD18J1zOINIQ8JSBKKr+i+v8+MB6LacL6Nn/sP/TE13+s2Q==",
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-3.0.4.tgz",
|
||||
"integrity": "sha512-Fok9VVhMdxAFOtqiiAtg74fL0UJkt0z3D+ouUUxcRLzZNBioPRAMJFVxiWoJljYpXsRi4GDQHzQHDc9AiYaIUQ==",
|
||||
"deprecated": "deprecating as we migrated to core v2",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@azure/abort-controller": "^1.0.0",
|
||||
@@ -151,7 +150,7 @@
|
||||
"tslib": "^2.2.0",
|
||||
"tunnel": "^0.0.6",
|
||||
"uuid": "^8.3.0",
|
||||
"xml2js": "^0.4.19"
|
||||
"xml2js": "^0.5.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
@@ -1123,15 +1122,6 @@
|
||||
"integrity": "sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/mkdirp": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-1.0.1.tgz",
|
||||
"integrity": "sha512-HkGSK7CGAXncr8Qn/0VqNtExEE+PHMWb+qlR1faHMao7ng6P3tAaoWWBMdva0gL5h4zprjIO89GJOLXsMcDm1Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/mocha": {
|
||||
"version": "9.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz",
|
||||
@@ -1372,28 +1362,6 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@vscode/vsce/node_modules/xml2js": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz",
|
||||
"integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"sax": ">=0.6.0",
|
||||
"xmlbuilder": "~11.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@vscode/vsce/node_modules/xmlbuilder": {
|
||||
"version": "11.0.1",
|
||||
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
|
||||
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@xmldom/xmldom": {
|
||||
"version": "0.8.10",
|
||||
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz",
|
||||
@@ -3374,18 +3342,6 @@
|
||||
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
|
||||
"devOptional": true
|
||||
},
|
||||
"node_modules/mkdirp": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
|
||||
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"mkdirp": "bin/cmd.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/mkdirp-classic": {
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
|
||||
@@ -4594,9 +4550,9 @@
|
||||
"devOptional": true
|
||||
},
|
||||
"node_modules/xml2js": {
|
||||
"version": "0.4.23",
|
||||
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz",
|
||||
"integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz",
|
||||
"integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"sax": ">=0.6.0",
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"@types/mime": "0.0.29",
|
||||
"@types/minimatch": "^3.0.3",
|
||||
"@types/minimist": "^1.2.1",
|
||||
"@types/mkdirp": "^1.0.1",
|
||||
"@types/mocha": "^9.1.1",
|
||||
"@types/node": "20.x",
|
||||
"@types/pump": "^1.0.1",
|
||||
@@ -48,7 +47,6 @@
|
||||
"gulp-sort": "^2.0.0",
|
||||
"jsonc-parser": "^2.3.0",
|
||||
"mime": "^1.4.1",
|
||||
"mkdirp": "^1.0.4",
|
||||
"source-map": "0.6.1",
|
||||
"ternary-stream": "^3.0.0",
|
||||
"through2": "^4.0.2",
|
||||
|
||||
@@ -241,33 +241,6 @@
|
||||
"CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
|
||||
]
|
||||
},
|
||||
{
|
||||
// Reason: The substack org has been deleted on GH
|
||||
"name": "mkdirp",
|
||||
"fullLicenseText": [
|
||||
"Copyright 2010 James Halliday (mail@substack.net)",
|
||||
"",
|
||||
"This project is free software released under the MIT/X11 license:",
|
||||
"",
|
||||
"Permission is hereby granted, free of charge, to any person obtaining a copy",
|
||||
"of this software and associated documentation files (the \"Software\"), to deal",
|
||||
"in the Software without restriction, including without limitation the rights",
|
||||
"to use, copy, modify, merge, publish, distribute, sublicense, and/or sell",
|
||||
"copies of the Software, and to permit persons to whom the Software is",
|
||||
"furnished to do so, subject to the following conditions:",
|
||||
"",
|
||||
"The above copyright notice and this permission notice shall be included in",
|
||||
"all copies or substantial portions of the Software.",
|
||||
"",
|
||||
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR",
|
||||
"IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,",
|
||||
"FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE",
|
||||
"AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER",
|
||||
"LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,",
|
||||
"OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN",
|
||||
"THE SOFTWARE."
|
||||
]
|
||||
},
|
||||
{
|
||||
// Reason: repo URI is wrong on crate, pending https://github.com/warp-tech/russh/pull/53
|
||||
"name": "russh-cryptovec",
|
||||
|
||||
@@ -81,4 +81,5 @@ codegen-units = 1
|
||||
|
||||
[features]
|
||||
default = []
|
||||
vsda = []
|
||||
vscode-encrypt = []
|
||||
|
||||
+1
-1
@@ -723,7 +723,7 @@ impl Auth {
|
||||
|
||||
match &init_code_json.message {
|
||||
Some(m) => self.log.result(m),
|
||||
None => self.log.result(&format!(
|
||||
None => self.log.result(format!(
|
||||
"To grant access to the server, please log into {} and use code {}",
|
||||
init_code_json.verification_uri, init_code_json.user_code
|
||||
)),
|
||||
|
||||
@@ -15,7 +15,7 @@ use std::time::{Duration, Instant};
|
||||
use hyper::service::{make_service_fn, service_fn};
|
||||
use hyper::{Body, Request, Response, Server};
|
||||
use tokio::io::{AsyncBufReadExt, BufReader};
|
||||
use tokio::pin;
|
||||
use tokio::{pin, time};
|
||||
|
||||
use crate::async_pipe::{
|
||||
get_socket_name, get_socket_rw_stream, listen_socket_rw_stream, AsyncPipe,
|
||||
@@ -50,7 +50,7 @@ const SERVER_IDLE_TIMEOUT_SECS: u64 = 60 * 60;
|
||||
/// (should be large enough to basically never happen)
|
||||
const SERVER_ACTIVE_TIMEOUT_SECS: u64 = SERVER_IDLE_TIMEOUT_SECS * 24 * 30 * 12;
|
||||
/// How long to cache the "latest" version we get from the update service.
|
||||
const RELEASE_CACHE_SECS: u64 = 60 * 60;
|
||||
const RELEASE_CHECK_INTERVAL: u64 = 60 * 60;
|
||||
|
||||
/// Number of bytes for the secret keys. See workbench.ts for their usage.
|
||||
const SECRET_KEY_BYTES: usize = 32;
|
||||
@@ -86,7 +86,11 @@ pub async fn serve_web(ctx: CommandContext, mut args: ServeWebArgs) -> Result<i3
|
||||
}
|
||||
}
|
||||
|
||||
let cm = ConnectionManager::new(&ctx, platform, args.clone());
|
||||
let cm: Arc<ConnectionManager> = ConnectionManager::new(&ctx, platform, args.clone());
|
||||
let update_check_interval = 3600;
|
||||
cm.clone()
|
||||
.start_update_checker(Duration::from_secs(update_check_interval));
|
||||
|
||||
let key = get_server_key_half(&ctx.paths);
|
||||
let make_svc = move || {
|
||||
let ctx = HandleContext {
|
||||
@@ -175,7 +179,7 @@ async fn handle_proxied(ctx: &HandleContext, req: Request<Body>) -> Response<Bod
|
||||
let release = if let Some((r, _)) = get_release_from_path(req.uri().path(), ctx.cm.platform) {
|
||||
r
|
||||
} else {
|
||||
match ctx.cm.get_latest_release().await {
|
||||
match ctx.cm.get_release_from_cache().await {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
error!(ctx.log, "error getting latest version: {}", e);
|
||||
@@ -538,21 +542,67 @@ impl ConnectionManager {
|
||||
pub fn new(ctx: &CommandContext, platform: Platform, args: ServeWebArgs) -> Arc<Self> {
|
||||
let base_path = normalize_base_path(args.server_base_path.as_deref().unwrap_or_default());
|
||||
|
||||
let cache = DownloadCache::new(ctx.paths.web_server_storage());
|
||||
let target_kind = TargetKind::Web;
|
||||
|
||||
let quality = VSCODE_CLI_QUALITY.map_or(Quality::Stable, |q| match Quality::try_from(q) {
|
||||
Ok(q) => q,
|
||||
Err(_) => Quality::Stable,
|
||||
});
|
||||
|
||||
let latest_version = tokio::sync::Mutex::new(cache.get().first().map(|latest_commit| {
|
||||
(
|
||||
Instant::now() - Duration::from_secs(RELEASE_CHECK_INTERVAL),
|
||||
Release {
|
||||
name: String::from("0.0.0"), // Version information not stored on cache
|
||||
commit: latest_commit.clone(),
|
||||
platform,
|
||||
target: target_kind,
|
||||
quality,
|
||||
},
|
||||
)
|
||||
}));
|
||||
|
||||
Arc::new(Self {
|
||||
platform,
|
||||
args,
|
||||
base_path,
|
||||
log: ctx.log.clone(),
|
||||
cache: DownloadCache::new(ctx.paths.web_server_storage()),
|
||||
cache,
|
||||
update_service: UpdateService::new(
|
||||
ctx.log.clone(),
|
||||
Arc::new(ReqwestSimpleHttp::with_client(ctx.http.clone())),
|
||||
),
|
||||
state: ConnectionStateMap::default(),
|
||||
latest_version: tokio::sync::Mutex::default(),
|
||||
latest_version,
|
||||
})
|
||||
}
|
||||
|
||||
// spawns a task that checks for updates every n seconds duration
|
||||
pub fn start_update_checker(self: Arc<Self>, duration: Duration) {
|
||||
tokio::spawn(async move {
|
||||
let mut interval = time::interval(duration);
|
||||
loop {
|
||||
interval.tick().await;
|
||||
|
||||
if let Err(e) = self.get_latest_release().await {
|
||||
warning!(self.log, "error getting latest version: {}", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Returns the latest release from the cache, if one exists.
|
||||
pub async fn get_release_from_cache(&self) -> Result<Release, CodeError> {
|
||||
let latest = self.latest_version.lock().await;
|
||||
if let Some((_, release)) = &*latest {
|
||||
return Ok(release.clone());
|
||||
}
|
||||
|
||||
drop(latest);
|
||||
self.get_latest_release().await
|
||||
}
|
||||
|
||||
/// Gets a connection to a server version
|
||||
pub async fn get_connection(
|
||||
&self,
|
||||
@@ -571,11 +621,7 @@ impl ConnectionManager {
|
||||
pub async fn get_latest_release(&self) -> Result<Release, CodeError> {
|
||||
let mut latest = self.latest_version.lock().await;
|
||||
let now = Instant::now();
|
||||
if let Some((checked_at, release)) = &*latest {
|
||||
if checked_at.elapsed() < Duration::from_secs(RELEASE_CACHE_SECS) {
|
||||
return Ok(release.clone());
|
||||
}
|
||||
}
|
||||
let target_kind = TargetKind::Web;
|
||||
|
||||
let quality = VSCODE_CLI_QUALITY
|
||||
.ok_or_else(|| CodeError::UpdatesNotConfigured("no configured quality"))
|
||||
@@ -585,13 +631,14 @@ impl ConnectionManager {
|
||||
|
||||
let release = self
|
||||
.update_service
|
||||
.get_latest_commit(self.platform, TargetKind::Web, quality)
|
||||
.get_latest_commit(self.platform, target_kind, quality)
|
||||
.await
|
||||
.map_err(|e| CodeError::UpdateCheckFailed(e.to_string()));
|
||||
|
||||
// If the update service is unavailable and we have stale data, use that
|
||||
if let (Err(e), Some((_, previous))) = (&release, &*latest) {
|
||||
if let (Err(e), Some((_, previous))) = (&release, latest.clone()) {
|
||||
warning!(self.log, "error getting latest release, using stale: {}", e);
|
||||
*latest = Some((now, previous.clone()));
|
||||
return Ok(previous.clone());
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ const KEEP_LRU: usize = 5;
|
||||
const STAGING_SUFFIX: &str = ".staging";
|
||||
const RENAME_ATTEMPTS: u32 = 20;
|
||||
const RENAME_DELAY: std::time::Duration = std::time::Duration::from_millis(200);
|
||||
const PERSISTED_STATE_FILE_NAME: &str = "lru.json";
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct DownloadCache {
|
||||
@@ -30,11 +31,16 @@ pub struct DownloadCache {
|
||||
impl DownloadCache {
|
||||
pub fn new(path: PathBuf) -> DownloadCache {
|
||||
DownloadCache {
|
||||
state: PersistedState::new(path.join("lru.json")),
|
||||
state: PersistedState::new(path.join(PERSISTED_STATE_FILE_NAME)),
|
||||
path,
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the value stored on the state
|
||||
pub fn get(&self) -> Vec<String> {
|
||||
self.state.load()
|
||||
}
|
||||
|
||||
/// Gets the download cache path. Names of cache entries can be formed by
|
||||
/// joining them to the path.
|
||||
pub fn path(&self) -> &Path {
|
||||
|
||||
@@ -674,7 +674,7 @@ where
|
||||
let write_line = |line: &str| -> std::io::Result<()> {
|
||||
if let Some(mut f) = log_file.as_ref() {
|
||||
f.write_all(line.as_bytes())?;
|
||||
f.write_all(&[b'\n'])?;
|
||||
f.write_all(b"\n")?;
|
||||
}
|
||||
if write_directly {
|
||||
println!("{}", line);
|
||||
|
||||
@@ -4,7 +4,6 @@ tsconfig.json
|
||||
out/**
|
||||
extension.webpack.config.js
|
||||
extension-browser.webpack.config.js
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
build/**
|
||||
schemas/devContainer.codespaces.schema.json
|
||||
|
||||
@@ -11,10 +11,8 @@ server/tsconfig.json
|
||||
server/test/**
|
||||
server/bin/**
|
||||
server/build/**
|
||||
server/yarn.lock
|
||||
server/package-lock.json
|
||||
server/.npmignore
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
server/extension.webpack.config.js
|
||||
extension.webpack.config.js
|
||||
|
||||
@@ -2,5 +2,4 @@ src/**
|
||||
tsconfig.json
|
||||
out/**
|
||||
extension.webpack.config.js
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
|
||||
@@ -2,6 +2,5 @@ src/**
|
||||
tsconfig.json
|
||||
out/**
|
||||
extension.webpack.config.js
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
.vscode
|
||||
|
||||
@@ -7,6 +7,5 @@ extension.webpack.config.js
|
||||
extension-browser.webpack.config.js
|
||||
CONTRIBUTING.md
|
||||
cgmanifest.json
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
.vscode
|
||||
|
||||
@@ -4,5 +4,4 @@ tsconfig.json
|
||||
out/**
|
||||
extension.webpack.config.js
|
||||
extension-browser.webpack.config.js
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
|
||||
@@ -4,5 +4,4 @@ out/**
|
||||
tsconfig.json
|
||||
build/**
|
||||
extension.webpack.config.js
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
|
||||
@@ -3059,7 +3059,7 @@ export class CommandCenter {
|
||||
|
||||
@command('git.fetchRef', { repository: true })
|
||||
async fetchRef(repository: Repository, ref?: string): Promise<void> {
|
||||
ref = ref ?? repository?.historyProvider.currentHistoryItemGroup?.remote?.id;
|
||||
ref = ref ?? repository?.historyProvider.currentHistoryItemRemoteRef?.id;
|
||||
if (!repository || !ref) {
|
||||
return;
|
||||
}
|
||||
@@ -3132,7 +3132,7 @@ export class CommandCenter {
|
||||
|
||||
@command('git.pullRef', { repository: true })
|
||||
async pullRef(repository: Repository, ref?: string): Promise<void> {
|
||||
ref = ref ?? repository?.historyProvider.currentHistoryItemGroup?.remote?.id;
|
||||
ref = ref ?? repository?.historyProvider.currentHistoryItemRemoteRef?.id;
|
||||
if (!repository || !ref) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -164,11 +164,11 @@ class GitIncomingChangesFileDecorationProvider implements FileDecorationProvider
|
||||
constructor(private readonly repository: Repository) {
|
||||
this.disposables.push(
|
||||
window.registerFileDecorationProvider(this),
|
||||
runAndSubscribeEvent(repository.historyProvider.onDidChangeCurrentHistoryItemGroup, () => this.onDidChangeCurrentHistoryItemGroup())
|
||||
runAndSubscribeEvent(repository.historyProvider.onDidChangeCurrentHistoryItemRefs, () => this.onDidChangeCurrentHistoryItemRefs())
|
||||
);
|
||||
}
|
||||
|
||||
private async onDidChangeCurrentHistoryItemGroup(): Promise<void> {
|
||||
private async onDidChangeCurrentHistoryItemRefs(): Promise<void> {
|
||||
const newDecorations = new Map<string, FileDecoration>();
|
||||
await this.collectIncomingChangesFileDecorations(newDecorations);
|
||||
const uris = new Set([...this.decorations.keys()].concat([...newDecorations.keys()]));
|
||||
@@ -218,18 +218,19 @@ class GitIncomingChangesFileDecorationProvider implements FileDecorationProvider
|
||||
private async getIncomingChanges(): Promise<Change[]> {
|
||||
try {
|
||||
const historyProvider = this.repository.historyProvider;
|
||||
const currentHistoryItemGroup = historyProvider.currentHistoryItemGroup;
|
||||
const currentHistoryItemRef = historyProvider.currentHistoryItemRef;
|
||||
const currentHistoryItemRemoteRef = historyProvider.currentHistoryItemRemoteRef;
|
||||
|
||||
if (!currentHistoryItemGroup?.remote) {
|
||||
if (!currentHistoryItemRef || !currentHistoryItemRemoteRef) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const ancestor = await historyProvider.resolveHistoryItemGroupCommonAncestor([currentHistoryItemGroup.id, currentHistoryItemGroup.remote.id]);
|
||||
const ancestor = await historyProvider.resolveHistoryItemRefsCommonAncestor([currentHistoryItemRef.id, currentHistoryItemRemoteRef.id]);
|
||||
if (!ancestor) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const changes = await this.repository.diffBetween(ancestor, currentHistoryItemGroup.remote.id);
|
||||
const changes = await this.repository.diffBetween(ancestor, currentHistoryItemRemoteRef.id);
|
||||
return changes;
|
||||
} catch (err) {
|
||||
return [];
|
||||
|
||||
@@ -4,36 +4,69 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
import { Disposable, Event, EventEmitter, FileDecoration, FileDecorationProvider, SourceControlHistoryItem, SourceControlHistoryItemChange, SourceControlHistoryItemGroup, SourceControlHistoryOptions, SourceControlHistoryProvider, ThemeIcon, Uri, window, LogOutputChannel, SourceControlHistoryItemLabel } from 'vscode';
|
||||
import { Disposable, Event, EventEmitter, FileDecoration, FileDecorationProvider, SourceControlHistoryItem, SourceControlHistoryItemChange, SourceControlHistoryOptions, SourceControlHistoryProvider, ThemeIcon, Uri, window, LogOutputChannel, SourceControlHistoryItemRef, l10n, SourceControlHistoryItemRefsChangeEvent } from 'vscode';
|
||||
import { Repository, Resource } from './repository';
|
||||
import { IDisposable, dispose } from './util';
|
||||
import { IDisposable, deltaHistoryItemRefs, dispose } from './util';
|
||||
import { toGitUri } from './uri';
|
||||
import { Branch, LogOptions, RefType } from './api/git';
|
||||
import { Branch, LogOptions, Ref, RefType } from './api/git';
|
||||
import { emojify, ensureEmojis } from './emoji';
|
||||
import { Commit } from './git';
|
||||
|
||||
function toSourceControlHistoryItemRef(ref: Ref): SourceControlHistoryItemRef {
|
||||
switch (ref.type) {
|
||||
case RefType.RemoteHead:
|
||||
return {
|
||||
id: `refs/remotes/${ref.name}`,
|
||||
name: ref.name ?? '',
|
||||
description: ref.commit ? l10n.t('Remote branch at {0}', ref.commit.substring(0, 8)) : undefined,
|
||||
revision: ref.commit,
|
||||
icon: new ThemeIcon('cloud'),
|
||||
category: l10n.t('remote branches')
|
||||
};
|
||||
case RefType.Tag:
|
||||
return {
|
||||
id: `refs/tags/${ref.name}`,
|
||||
name: ref.name ?? '',
|
||||
description: ref.commit ? l10n.t('Tag at {0}', ref.commit.substring(0, 8)) : undefined,
|
||||
revision: ref.commit,
|
||||
icon: new ThemeIcon('tag'),
|
||||
category: l10n.t('tags')
|
||||
};
|
||||
default:
|
||||
return {
|
||||
id: `refs/heads/${ref.name}`,
|
||||
name: ref.name ?? '',
|
||||
description: ref.commit ? ref.commit.substring(0, 8) : undefined,
|
||||
revision: ref.commit,
|
||||
icon: new ThemeIcon('git-branch'),
|
||||
category: l10n.t('branches')
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class GitHistoryProvider implements SourceControlHistoryProvider, FileDecorationProvider, IDisposable {
|
||||
|
||||
private readonly _onDidChangeCurrentHistoryItemGroup = new EventEmitter<void>();
|
||||
readonly onDidChangeCurrentHistoryItemGroup: Event<void> = this._onDidChangeCurrentHistoryItemGroup.event;
|
||||
|
||||
private readonly _onDidChangeDecorations = new EventEmitter<Uri[]>();
|
||||
readonly onDidChangeFileDecorations: Event<Uri[]> = this._onDidChangeDecorations.event;
|
||||
|
||||
private _currentHistoryItemGroup: SourceControlHistoryItemGroup | undefined;
|
||||
get currentHistoryItemGroup(): SourceControlHistoryItemGroup | undefined { return this._currentHistoryItemGroup; }
|
||||
set currentHistoryItemGroup(value: SourceControlHistoryItemGroup | undefined) {
|
||||
this._currentHistoryItemGroup = value;
|
||||
this._onDidChangeCurrentHistoryItemGroup.fire();
|
||||
}
|
||||
private _currentHistoryItemRef: SourceControlHistoryItemRef | undefined;
|
||||
get currentHistoryItemRef(): SourceControlHistoryItemRef | undefined { return this._currentHistoryItemRef; }
|
||||
|
||||
private _currentHistoryItemRemoteRef: SourceControlHistoryItemRef | undefined;
|
||||
get currentHistoryItemRemoteRef(): SourceControlHistoryItemRef | undefined { return this._currentHistoryItemRemoteRef; }
|
||||
|
||||
private _currentHistoryItemBaseRef: SourceControlHistoryItemRef | undefined;
|
||||
get currentHistoryItemBaseRef(): SourceControlHistoryItemRef | undefined { return this._currentHistoryItemBaseRef; }
|
||||
|
||||
private readonly _onDidChangeCurrentHistoryItemRefs = new EventEmitter<void>();
|
||||
readonly onDidChangeCurrentHistoryItemRefs: Event<void> = this._onDidChangeCurrentHistoryItemRefs.event;
|
||||
|
||||
private readonly _onDidChangeHistoryItemRefs = new EventEmitter<SourceControlHistoryItemRefsChangeEvent>();
|
||||
readonly onDidChangeHistoryItemRefs: Event<SourceControlHistoryItemRefsChangeEvent> = this._onDidChangeHistoryItemRefs.event;
|
||||
|
||||
private _HEAD: Branch | undefined;
|
||||
private historyItemRefs: SourceControlHistoryItemRef[] = [];
|
||||
|
||||
private historyItemDecorations = new Map<string, FileDecoration>();
|
||||
private historyItemLabels = new Map<string, ThemeIcon>([
|
||||
['HEAD -> refs/heads/', new ThemeIcon('target')],
|
||||
['tag: refs/tags/', new ThemeIcon('tag')],
|
||||
['refs/heads/', new ThemeIcon('git-branch')],
|
||||
['refs/remotes/', new ThemeIcon('cloud')],
|
||||
]);
|
||||
|
||||
private disposables: Disposable[] = [];
|
||||
|
||||
@@ -45,53 +78,124 @@ export class GitHistoryProvider implements SourceControlHistoryProvider, FileDec
|
||||
private async onDidRunGitStatus(): Promise<void> {
|
||||
if (!this.repository.HEAD) {
|
||||
this.logger.trace('[GitHistoryProvider][onDidRunGitStatus] repository.HEAD is undefined');
|
||||
this.currentHistoryItemGroup = undefined;
|
||||
this._currentHistoryItemRef = this._currentHistoryItemRemoteRef = this._currentHistoryItemBaseRef = undefined;
|
||||
this._onDidChangeCurrentHistoryItemRefs.fire();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the merge base of the current history item group
|
||||
const mergeBase = await this.resolveHEADMergeBase();
|
||||
let historyItemRefId = '';
|
||||
let historyItemRefName = '';
|
||||
|
||||
// Handle tag, and detached commit
|
||||
const currentHistoryItemGroupId =
|
||||
this.repository.HEAD.name === undefined ?
|
||||
this.repository.HEAD.commit :
|
||||
this.repository.HEAD.type === RefType.Tag ?
|
||||
`refs/tags/${this.repository.HEAD.name}` :
|
||||
`refs/heads/${this.repository.HEAD.name}`;
|
||||
switch (this.repository.HEAD.type) {
|
||||
case RefType.Head: {
|
||||
if (this.repository.HEAD.name !== undefined) {
|
||||
// Branch
|
||||
historyItemRefId = `refs/heads/${this.repository.HEAD.name}`;
|
||||
historyItemRefName = this.repository.HEAD.name;
|
||||
|
||||
// Detached commit
|
||||
const currentHistoryItemGroupName =
|
||||
this.repository.HEAD.name ?? this.repository.HEAD.commit;
|
||||
// Remote
|
||||
this._currentHistoryItemRemoteRef = this.repository.HEAD.upstream ? {
|
||||
id: `refs/remotes/${this.repository.HEAD.upstream.remote}/${this.repository.HEAD.upstream.name}`,
|
||||
name: `${this.repository.HEAD.upstream.remote}/${this.repository.HEAD.upstream.name}`,
|
||||
revision: this.repository.HEAD.upstream.commit,
|
||||
icon: new ThemeIcon('cloud')
|
||||
} : undefined;
|
||||
|
||||
this.currentHistoryItemGroup = {
|
||||
id: currentHistoryItemGroupId ?? '',
|
||||
name: currentHistoryItemGroupName ?? '',
|
||||
// Base - compute only if the branch has changed
|
||||
if (this._HEAD?.name !== this.repository.HEAD.name) {
|
||||
const mergeBase = await this.resolveHEADMergeBase();
|
||||
|
||||
this._currentHistoryItemBaseRef = mergeBase &&
|
||||
(mergeBase.remote !== this.repository.HEAD.upstream?.remote ||
|
||||
mergeBase.name !== this.repository.HEAD.upstream?.name) ? {
|
||||
id: `refs/remotes/${mergeBase.remote}/${mergeBase.name}`,
|
||||
name: `${mergeBase.remote}/${mergeBase.name}`,
|
||||
revision: mergeBase.commit
|
||||
} : undefined;
|
||||
}
|
||||
} else {
|
||||
// Detached commit
|
||||
historyItemRefId = this.repository.HEAD.commit ?? '';
|
||||
historyItemRefName = this.repository.HEAD.commit ?? '';
|
||||
|
||||
this._currentHistoryItemRemoteRef = undefined;
|
||||
this._currentHistoryItemBaseRef = undefined;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RefType.Tag: {
|
||||
// Tag
|
||||
historyItemRefId = `refs/tags/${this.repository.HEAD.name}`;
|
||||
historyItemRefName = this.repository.HEAD.name ?? this.repository.HEAD.commit ?? '';
|
||||
|
||||
this._currentHistoryItemRemoteRef = undefined;
|
||||
this._currentHistoryItemBaseRef = undefined;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this._HEAD = this.repository.HEAD;
|
||||
|
||||
this._currentHistoryItemRef = {
|
||||
id: historyItemRefId,
|
||||
name: historyItemRefName,
|
||||
revision: this.repository.HEAD.commit,
|
||||
remote: this.repository.HEAD.upstream ? {
|
||||
id: `refs/remotes/${this.repository.HEAD.upstream.remote}/${this.repository.HEAD.upstream.name}`,
|
||||
name: `${this.repository.HEAD.upstream.remote}/${this.repository.HEAD.upstream.name}`,
|
||||
revision: this.repository.HEAD.upstream.commit
|
||||
} : undefined,
|
||||
base: mergeBase &&
|
||||
(mergeBase.remote !== this.repository.HEAD.upstream?.remote ||
|
||||
mergeBase.name !== this.repository.HEAD.upstream?.name) ? {
|
||||
id: `refs/remotes/${mergeBase.remote}/${mergeBase.name}`,
|
||||
name: `${mergeBase.remote}/${mergeBase.name}`,
|
||||
revision: mergeBase.commit
|
||||
} : undefined
|
||||
icon: new ThemeIcon('target'),
|
||||
};
|
||||
|
||||
this.logger.trace(`[GitHistoryProvider][onDidRunGitStatus] currentHistoryItemGroup: ${JSON.stringify(this.currentHistoryItemGroup)}`);
|
||||
this._onDidChangeCurrentHistoryItemRefs.fire();
|
||||
this.logger.trace(`[GitHistoryProvider][onDidRunGitStatus] currentHistoryItemRef: ${JSON.stringify(this._currentHistoryItemRef)}`);
|
||||
this.logger.trace(`[GitHistoryProvider][onDidRunGitStatus] currentHistoryItemRemoteRef: ${JSON.stringify(this._currentHistoryItemRemoteRef)}`);
|
||||
this.logger.trace(`[GitHistoryProvider][onDidRunGitStatus] currentHistoryItemBaseRef: ${JSON.stringify(this._currentHistoryItemBaseRef)}`);
|
||||
|
||||
// Refs (alphabetically)
|
||||
const refs = await this.repository.getRefs({ sort: 'alphabetically' });
|
||||
const historyItemRefs = refs.map(ref => toSourceControlHistoryItemRef(ref));
|
||||
|
||||
const delta = deltaHistoryItemRefs(this.historyItemRefs, historyItemRefs);
|
||||
this._onDidChangeHistoryItemRefs.fire(delta);
|
||||
this.historyItemRefs = historyItemRefs;
|
||||
|
||||
const deltaLog = {
|
||||
added: delta.added.map(ref => ref.id),
|
||||
modified: delta.modified.map(ref => ref.id),
|
||||
removed: delta.removed.map(ref => ref.id)
|
||||
};
|
||||
this.logger.trace(`[GitHistoryProvider][onDidRunGitStatus] historyItemRefs: ${JSON.stringify(deltaLog)}`);
|
||||
}
|
||||
|
||||
async provideHistoryItemRefs(): Promise<SourceControlHistoryItemRef[]> {
|
||||
const refs = await this.repository.getRefs();
|
||||
|
||||
const branches: SourceControlHistoryItemRef[] = [];
|
||||
const remoteBranches: SourceControlHistoryItemRef[] = [];
|
||||
const tags: SourceControlHistoryItemRef[] = [];
|
||||
|
||||
for (const ref of refs) {
|
||||
switch (ref.type) {
|
||||
case RefType.RemoteHead:
|
||||
remoteBranches.push(toSourceControlHistoryItemRef(ref));
|
||||
break;
|
||||
case RefType.Tag:
|
||||
tags.push(toSourceControlHistoryItemRef(ref));
|
||||
break;
|
||||
default:
|
||||
branches.push(toSourceControlHistoryItemRef(ref));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return [...branches, ...remoteBranches, ...tags];
|
||||
}
|
||||
|
||||
async provideHistoryItems(options: SourceControlHistoryOptions): Promise<SourceControlHistoryItem[]> {
|
||||
if (!this.currentHistoryItemGroup || !options.historyItemGroupIds) {
|
||||
if (!this.currentHistoryItemRef || !options.historyItemRefs) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Deduplicate refNames
|
||||
const refNames = Array.from(new Set<string>(options.historyItemGroupIds));
|
||||
const refNames = Array.from(new Set<string>(options.historyItemRefs));
|
||||
|
||||
let logOptions: LogOptions = { refNames, shortStats: true };
|
||||
|
||||
@@ -115,7 +219,7 @@ export class GitHistoryProvider implements SourceControlHistoryProvider, FileDec
|
||||
await ensureEmojis();
|
||||
|
||||
return commits.map(commit => {
|
||||
const labels = this.resolveHistoryItemLabels(commit);
|
||||
const references = this.resolveHistoryItemRefs(commit);
|
||||
|
||||
return {
|
||||
id: commit.hash,
|
||||
@@ -126,7 +230,7 @@ export class GitHistoryProvider implements SourceControlHistoryProvider, FileDec
|
||||
displayId: commit.hash.substring(0, 8),
|
||||
timestamp: commit.authorDate?.getTime(),
|
||||
statistics: commit.shortStat ?? { files: 0, insertions: 0, deletions: 0 },
|
||||
labels: labels.length !== 0 ? labels : undefined
|
||||
references: references.length !== 0 ? references : undefined
|
||||
};
|
||||
});
|
||||
} catch (err) {
|
||||
@@ -169,21 +273,21 @@ export class GitHistoryProvider implements SourceControlHistoryProvider, FileDec
|
||||
return historyItemChanges;
|
||||
}
|
||||
|
||||
async resolveHistoryItemGroupCommonAncestor(historyItemGroupIds: string[]): Promise<string | undefined> {
|
||||
async resolveHistoryItemRefsCommonAncestor(historyItemRefs: string[]): Promise<string | undefined> {
|
||||
try {
|
||||
if (historyItemGroupIds.length === 0) {
|
||||
if (historyItemRefs.length === 0) {
|
||||
// TODO@lszomoru - log
|
||||
return undefined;
|
||||
} else if (historyItemGroupIds.length === 1 && historyItemGroupIds[0] === this.currentHistoryItemGroup?.id) {
|
||||
} else if (historyItemRefs.length === 1 && historyItemRefs[0] === this.currentHistoryItemRef?.id) {
|
||||
// Remote
|
||||
if (this.currentHistoryItemGroup.remote) {
|
||||
const ancestor = await this.repository.getMergeBase(historyItemGroupIds[0], this.currentHistoryItemGroup.remote.id);
|
||||
if (this.currentHistoryItemRemoteRef) {
|
||||
const ancestor = await this.repository.getMergeBase(historyItemRefs[0], this.currentHistoryItemRemoteRef.id);
|
||||
return ancestor;
|
||||
}
|
||||
|
||||
// Base
|
||||
if (this.currentHistoryItemGroup.base) {
|
||||
const ancestor = await this.repository.getMergeBase(historyItemGroupIds[0], this.currentHistoryItemGroup.base.id);
|
||||
if (this.currentHistoryItemBaseRef) {
|
||||
const ancestor = await this.repository.getMergeBase(historyItemRefs[0], this.currentHistoryItemBaseRef.id);
|
||||
return ancestor;
|
||||
}
|
||||
|
||||
@@ -192,13 +296,13 @@ export class GitHistoryProvider implements SourceControlHistoryProvider, FileDec
|
||||
if (commits.length > 0) {
|
||||
return commits[0].hash;
|
||||
}
|
||||
} else if (historyItemGroupIds.length > 1) {
|
||||
const ancestor = await this.repository.getMergeBase(historyItemGroupIds[0], historyItemGroupIds[1], ...historyItemGroupIds.slice(2));
|
||||
} else if (historyItemRefs.length > 1) {
|
||||
const ancestor = await this.repository.getMergeBase(historyItemRefs[0], historyItemRefs[1], ...historyItemRefs.slice(2));
|
||||
return ancestor;
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
this.logger.error(`[GitHistoryProvider][resolveHistoryItemGroupCommonAncestor] Failed to resolve common ancestor for ${historyItemGroupIds.join(',')}: ${err}`);
|
||||
this.logger.error(`[GitHistoryProvider][resolveHistoryItemRefsCommonAncestor] Failed to resolve common ancestor for ${historyItemRefs.join(',')}: ${err}`);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
@@ -208,19 +312,47 @@ export class GitHistoryProvider implements SourceControlHistoryProvider, FileDec
|
||||
return this.historyItemDecorations.get(uri.toString());
|
||||
}
|
||||
|
||||
private resolveHistoryItemLabels(commit: Commit): SourceControlHistoryItemLabel[] {
|
||||
const labels: SourceControlHistoryItemLabel[] = [];
|
||||
private resolveHistoryItemRefs(commit: Commit): SourceControlHistoryItemRef[] {
|
||||
const references: SourceControlHistoryItemRef[] = [];
|
||||
|
||||
for (const label of commit.refNames) {
|
||||
for (const [key, value] of this.historyItemLabels) {
|
||||
if (label.startsWith(key)) {
|
||||
labels.push({ title: label.substring(key.length), icon: value });
|
||||
for (const ref of commit.refNames) {
|
||||
switch (true) {
|
||||
case ref.startsWith('HEAD -> refs/heads/'):
|
||||
references.push({
|
||||
id: ref.substring('HEAD -> '.length),
|
||||
name: ref.substring('HEAD -> refs/heads/'.length),
|
||||
revision: commit.hash,
|
||||
icon: new ThemeIcon('target')
|
||||
});
|
||||
break;
|
||||
case ref.startsWith('tag: refs/tags/'):
|
||||
references.push({
|
||||
id: ref.substring('tag: '.length),
|
||||
name: ref.substring('tag: refs/tags/'.length),
|
||||
revision: commit.hash,
|
||||
icon: new ThemeIcon('tag')
|
||||
});
|
||||
break;
|
||||
case ref.startsWith('refs/heads/'):
|
||||
references.push({
|
||||
id: ref,
|
||||
name: ref.substring('refs/heads/'.length),
|
||||
revision: commit.hash,
|
||||
icon: new ThemeIcon('git-branch')
|
||||
});
|
||||
break;
|
||||
case ref.startsWith('refs/remotes/'):
|
||||
references.push({
|
||||
id: ref,
|
||||
name: ref.substring('refs/remotes/'.length),
|
||||
revision: commit.hash,
|
||||
icon: new ThemeIcon('cloud')
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return labels;
|
||||
return references;
|
||||
}
|
||||
|
||||
private async resolveHEADMergeBase(): Promise<Branch | undefined> {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Event, Disposable, EventEmitter } from 'vscode';
|
||||
import { Event, Disposable, EventEmitter, SourceControlHistoryItemRef } from 'vscode';
|
||||
import { dirname, sep, relative } from 'path';
|
||||
import { Readable } from 'stream';
|
||||
import { promises as fs, createReadStream } from 'fs';
|
||||
@@ -513,3 +513,58 @@ export namespace Versions {
|
||||
return from(major, minor, patch, pre);
|
||||
}
|
||||
}
|
||||
|
||||
export function deltaHistoryItemRefs(before: SourceControlHistoryItemRef[], after: SourceControlHistoryItemRef[]): {
|
||||
added: SourceControlHistoryItemRef[];
|
||||
modified: SourceControlHistoryItemRef[];
|
||||
removed: SourceControlHistoryItemRef[];
|
||||
} {
|
||||
if (before.length === 0) {
|
||||
return { added: after, modified: [], removed: [] };
|
||||
}
|
||||
|
||||
const added: SourceControlHistoryItemRef[] = [];
|
||||
const modified: SourceControlHistoryItemRef[] = [];
|
||||
const removed: SourceControlHistoryItemRef[] = [];
|
||||
|
||||
let beforeIdx = 0;
|
||||
let afterIdx = 0;
|
||||
|
||||
while (true) {
|
||||
if (beforeIdx === before.length) {
|
||||
added.push(...after.slice(afterIdx));
|
||||
break;
|
||||
}
|
||||
if (afterIdx === after.length) {
|
||||
removed.push(...before.slice(beforeIdx));
|
||||
break;
|
||||
}
|
||||
|
||||
const beforeElement = before[beforeIdx];
|
||||
const afterElement = after[afterIdx];
|
||||
|
||||
const result = beforeElement.id.localeCompare(afterElement.id);
|
||||
|
||||
if (result === 0) {
|
||||
if (beforeElement.revision !== afterElement.revision) {
|
||||
// modified
|
||||
modified.push(afterElement);
|
||||
}
|
||||
|
||||
beforeIdx += 1;
|
||||
afterIdx += 1;
|
||||
} else if (result < 0) {
|
||||
// beforeElement is smaller -> before element removed
|
||||
removed.push(beforeElement);
|
||||
|
||||
beforeIdx += 1;
|
||||
} else if (result > 0) {
|
||||
// beforeElement is greater -> after element added
|
||||
added.push(afterElement);
|
||||
|
||||
afterIdx += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return { added, modified, removed };
|
||||
}
|
||||
|
||||
@@ -6,5 +6,4 @@ build/**
|
||||
extension.webpack.config.js
|
||||
extension-browser.webpack.config.js
|
||||
tsconfig.json
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
|
||||
@@ -18,7 +18,9 @@ interface SessionData {
|
||||
account?: {
|
||||
label?: string;
|
||||
displayName?: string;
|
||||
id: string;
|
||||
// Unfortunately, for some time the id was a number, so we need to support both.
|
||||
// This can be removed once we are confident that all users have migrated to the new id.
|
||||
id: string | number;
|
||||
};
|
||||
scopes: string[];
|
||||
accessToken: string;
|
||||
@@ -239,9 +241,14 @@ export class GitHubAuthenticationProvider implements vscode.AuthenticationProvid
|
||||
return [];
|
||||
}
|
||||
|
||||
// Unfortunately, we were using a number secretly for the account id for some time... this is due to a bad `any`.
|
||||
// AuthenticationSession's account id is a string, so we need to detect when there is a number accountId and re-store
|
||||
// the sessions to migrate away from the bad number usage.
|
||||
// TODO@TylerLeonhardt: Remove this after we are confident that all users have migrated to the new id.
|
||||
let seenNumberAccountId: boolean = false;
|
||||
// TODO: eventually remove this Set because we should only have one session per set of scopes.
|
||||
const scopesSeen = new Set<string>();
|
||||
const sessionPromises = sessionData.map(async (session: SessionData) => {
|
||||
const sessionPromises = sessionData.map(async (session: SessionData): Promise<vscode.AuthenticationSession | undefined> => {
|
||||
// For GitHub scope list, order doesn't matter so we immediately sort the scopes
|
||||
const scopesStr = [...session.scopes].sort().join(' ');
|
||||
if (!this._supportsMultipleAccounts && scopesSeen.has(scopesStr)) {
|
||||
@@ -262,13 +269,23 @@ export class GitHubAuthenticationProvider implements vscode.AuthenticationProvid
|
||||
|
||||
this._logger.trace(`Read the following session from the keychain with the following scopes: ${scopesStr}`);
|
||||
scopesSeen.add(scopesStr);
|
||||
|
||||
let accountId: string;
|
||||
if (session.account?.id) {
|
||||
if (typeof session.account.id === 'number') {
|
||||
seenNumberAccountId = true;
|
||||
}
|
||||
accountId = `${session.account.id}`;
|
||||
} else {
|
||||
accountId = userInfo?.id ?? '<unknown>';
|
||||
}
|
||||
return {
|
||||
id: session.id,
|
||||
account: {
|
||||
label: session.account
|
||||
? session.account.label ?? session.account.displayName ?? '<unknown>'
|
||||
: userInfo?.accountName ?? '<unknown>',
|
||||
id: session.account?.id ?? userInfo?.id ?? '<unknown>'
|
||||
id: accountId
|
||||
},
|
||||
// we set this to session.scopes to maintain the original order of the scopes requested
|
||||
// by the extension that called getSession()
|
||||
@@ -283,7 +300,7 @@ export class GitHubAuthenticationProvider implements vscode.AuthenticationProvid
|
||||
.filter(<T>(p?: T): p is T => Boolean(p));
|
||||
|
||||
this._logger.info(`Got ${verifiedSessions.length} verified sessions.`);
|
||||
if (verifiedSessions.length !== sessionData.length) {
|
||||
if (seenNumberAccountId || verifiedSessions.length !== sessionData.length) {
|
||||
await this.storeSessions(verifiedSessions);
|
||||
}
|
||||
|
||||
|
||||
@@ -228,9 +228,9 @@ export class GitHubServer implements IGitHubServer {
|
||||
|
||||
if (result.ok) {
|
||||
try {
|
||||
const json = await result.json();
|
||||
const json = await result.json() as { id: number; login: string };
|
||||
this._logger.info('Got account info!');
|
||||
return { id: json.id, accountName: json.login };
|
||||
return { id: `${json.id}`, accountName: json.login };
|
||||
} catch (e) {
|
||||
this._logger.error(`Unexpected error parsing response from GitHub: ${e.message ?? e}`);
|
||||
throw e;
|
||||
|
||||
@@ -4,5 +4,4 @@ out/**
|
||||
build/**
|
||||
extension.webpack.config.js
|
||||
tsconfig.json
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
|
||||
@@ -3,5 +3,4 @@ src/**
|
||||
tsconfig.json
|
||||
out/**
|
||||
extension.webpack.config.js
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
|
||||
@@ -2,5 +2,4 @@ src/**
|
||||
tsconfig.json
|
||||
out/**
|
||||
extension.webpack.config.js
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
|
||||
@@ -13,10 +13,8 @@ server/test/**
|
||||
server/bin/**
|
||||
server/build/**
|
||||
server/lib/cgmanifest.json
|
||||
server/yarn.lock
|
||||
server/package-lock.json
|
||||
server/.npmignore
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
server/extension.webpack.config.js
|
||||
extension.webpack.config.js
|
||||
|
||||
@@ -5,7 +5,6 @@ out/**
|
||||
tsconfig.json
|
||||
extension.webpack.config.js
|
||||
extension-browser.webpack.config.js
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
.gitignore
|
||||
esbuild.js
|
||||
|
||||
@@ -2,5 +2,4 @@ src/**
|
||||
tsconfig.json
|
||||
out/**
|
||||
extension.webpack.config.js
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
|
||||
@@ -10,11 +10,9 @@ server/tsconfig.json
|
||||
server/test/**
|
||||
server/bin/**
|
||||
server/build/**
|
||||
server/yarn.lock
|
||||
server/package-lock.json
|
||||
server/.npmignore
|
||||
server/README.md
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
CONTRIBUTING.md
|
||||
server/extension.webpack.config.js
|
||||
|
||||
@@ -5,7 +5,6 @@ src/
|
||||
test/
|
||||
tsconfig.json
|
||||
.gitignore
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
extension.webpack.config.js
|
||||
vscode-json-languageserver-*.tgz
|
||||
|
||||
@@ -9,7 +9,6 @@ out/**
|
||||
extension.webpack.config.js
|
||||
extension-browser.webpack.config.js
|
||||
cgmanifest.json
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
preview-src/**
|
||||
webpack.config.js
|
||||
|
||||
@@ -4,7 +4,6 @@ extension-browser.webpack.config.js
|
||||
extension.webpack.config.js
|
||||
esbuild.js
|
||||
cgmanifest.json
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
webpack.config.js
|
||||
tsconfig.json
|
||||
|
||||
@@ -6,7 +6,6 @@ out/**
|
||||
extension.webpack.config.js
|
||||
extension-browser.webpack.config.js
|
||||
cgmanifest.json
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
preview-src/**
|
||||
webpack.config.js
|
||||
|
||||
@@ -12,6 +12,7 @@ html, body {
|
||||
body img {
|
||||
max-width: none;
|
||||
max-height: none;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.container:focus {
|
||||
@@ -31,20 +32,20 @@ body img {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.container.image img {
|
||||
.container.image .transparency-grid {
|
||||
padding: 0;
|
||||
background-position: 0 0, 8px 8px;
|
||||
background-size: 16px 16px;
|
||||
border: 1px solid var(--vscode-imagePreview-border);
|
||||
}
|
||||
|
||||
.container.image img {
|
||||
.container.image .transparency-grid {
|
||||
background-image:
|
||||
linear-gradient(45deg, rgb(230, 230, 230) 25%, transparent 25%, transparent 75%, rgb(230, 230, 230) 75%, rgb(230, 230, 230)),
|
||||
linear-gradient(45deg, rgb(230, 230, 230) 25%, transparent 25%, transparent 75%, rgb(230, 230, 230) 75%, rgb(230, 230, 230));
|
||||
}
|
||||
|
||||
.vscode-dark.container.image img {
|
||||
.vscode-dark.container.image .transparency-grid {
|
||||
background-image:
|
||||
linear-gradient(45deg, rgb(20, 20, 20) 25%, transparent 25%, transparent 75%, rgb(20, 20, 20) 75%, rgb(20, 20, 20)),
|
||||
linear-gradient(45deg, rgb(20, 20, 20) 25%, transparent 25%, transparent 75%, rgb(20, 20, 20) 75%, rgb(20, 20, 20));
|
||||
@@ -54,13 +55,13 @@ body img {
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
|
||||
.container img.scale-to-fit {
|
||||
.container .transparency-grid.scale-to-fit {
|
||||
max-width: calc(100% - 20px);
|
||||
max-height: calc(100% - 20px);
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.container img {
|
||||
.container .transparency-grid {
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
|
||||
@@ -76,6 +76,8 @@
|
||||
|
||||
// Elements
|
||||
const container = document.body;
|
||||
const transparencyGrid = document.createElement('div');
|
||||
transparencyGrid.classList.add('transparency-grid');
|
||||
const image = document.createElement('img');
|
||||
|
||||
function updateScale(newScale) {
|
||||
@@ -85,7 +87,7 @@
|
||||
|
||||
if (newScale === 'fit') {
|
||||
scale = 'fit';
|
||||
image.classList.add('scale-to-fit');
|
||||
transparencyGrid.classList.add('scale-to-fit');
|
||||
image.classList.remove('pixelated');
|
||||
// @ts-ignore Non-standard CSS property
|
||||
image.style.zoom = 'normal';
|
||||
@@ -292,7 +294,9 @@
|
||||
|
||||
document.body.classList.remove('loading');
|
||||
document.body.classList.add('ready');
|
||||
document.body.append(image);
|
||||
|
||||
document.body.append(transparencyGrid);
|
||||
transparencyGrid.appendChild(image);
|
||||
|
||||
updateScale(scale);
|
||||
|
||||
|
||||
@@ -3,5 +3,4 @@ tsconfig.json
|
||||
out/**
|
||||
extension.webpack.config.js
|
||||
extension-browser.webpack.config.js
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
|
||||
@@ -4,7 +4,6 @@ out/test/**
|
||||
out/**
|
||||
extension.webpack.config.js
|
||||
extension-browser.webpack.config.js
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
src/**
|
||||
.gitignore
|
||||
|
||||
@@ -7,6 +7,8 @@ import type { Disposable, Event } from 'vscode';
|
||||
|
||||
export interface ICachedPublicClientApplication extends Disposable {
|
||||
initialize(): Promise<void>;
|
||||
onDidAccountsChange: Event<{ added: AccountInfo[]; changed: AccountInfo[]; deleted: AccountInfo[] }>;
|
||||
onDidRemoveLastAccount: Event<void>;
|
||||
acquireTokenSilent(request: SilentFlowRequest): Promise<AuthenticationResult>;
|
||||
acquireTokenInteractive(request: InteractiveRequest): Promise<AuthenticationResult>;
|
||||
removeAccount(account: AccountInfo): Promise<void>;
|
||||
@@ -16,6 +18,7 @@ export interface ICachedPublicClientApplication extends Disposable {
|
||||
}
|
||||
|
||||
export interface ICachedPublicClientApplicationManager {
|
||||
onDidAccountsChange: Event<{ added: AccountInfo[]; changed: AccountInfo[]; deleted: AccountInfo[] }>;
|
||||
getOrCreate(clientId: string, authority: string): Promise<ICachedPublicClientApplication>;
|
||||
getAll(): ICachedPublicClientApplication[];
|
||||
}
|
||||
|
||||
@@ -48,15 +48,12 @@ export class MsalAuthProvider implements AuthenticationProvider {
|
||||
private readonly _env: Environment = Environment.AzureCloud
|
||||
) {
|
||||
this._disposables = context.subscriptions;
|
||||
this._publicClientManager = new CachedPublicClientApplicationManager(
|
||||
context.globalState,
|
||||
context.secrets,
|
||||
this._logger,
|
||||
(e) => this._handleAccountChange(e)
|
||||
this._publicClientManager = new CachedPublicClientApplicationManager(context.globalState, context.secrets, this._logger);
|
||||
this._disposables.push(
|
||||
this._onDidChangeSessionsEmitter,
|
||||
this._publicClientManager,
|
||||
this._publicClientManager.onDidAccountsChange(e => this._handleAccountChange(e))
|
||||
);
|
||||
this._disposables.push(this._publicClientManager);
|
||||
this._disposables.push(this._onDidChangeSessionsEmitter);
|
||||
|
||||
}
|
||||
|
||||
async initialize(): Promise<void> {
|
||||
@@ -79,40 +76,43 @@ export class MsalAuthProvider implements AuthenticationProvider {
|
||||
* See {@link onDidChangeSessions} for more information on how this is used.
|
||||
* @param param0 Event that contains the added and removed accounts
|
||||
*/
|
||||
private _handleAccountChange({ added, deleted }: { added: AccountInfo[]; deleted: AccountInfo[] }) {
|
||||
const process = (a: AccountInfo) => ({
|
||||
// This shouldn't be needed
|
||||
accessToken: '1234',
|
||||
id: a.homeAccountId,
|
||||
scopes: [],
|
||||
account: {
|
||||
id: a.homeAccountId,
|
||||
label: a.username
|
||||
},
|
||||
idToken: a.idToken,
|
||||
private _handleAccountChange({ added, changed, deleted }: { added: AccountInfo[]; changed: AccountInfo[]; deleted: AccountInfo[] }) {
|
||||
this._onDidChangeSessionsEmitter.fire({
|
||||
added: added.map(this.sessionFromAccountInfo),
|
||||
changed: changed.map(this.sessionFromAccountInfo),
|
||||
removed: deleted.map(this.sessionFromAccountInfo)
|
||||
});
|
||||
this._onDidChangeSessionsEmitter.fire({ added: added.map(process), changed: [], removed: deleted.map(process) });
|
||||
}
|
||||
|
||||
//#region AuthenticationProvider methods
|
||||
|
||||
async getSessions(scopes: string[] | undefined, options?: AuthenticationGetSessionOptions): Promise<AuthenticationSession[]> {
|
||||
const askingForAll = scopes === undefined;
|
||||
const scopeData = new ScopeData(scopes);
|
||||
this._logger.info('[getSessions]', scopes ? scopeData.scopeStr : 'all', 'starting');
|
||||
if (!scopes) {
|
||||
// Do NOT use `scopes` beyond this place in the code. Use `scopeData` instead.
|
||||
// Do NOT use `scopes` beyond this place in the code. Use `scopeData` instead.
|
||||
this._logger.info('[getSessions]', askingForAll ? '[all]' : `[${scopeData.scopeStr}]`, 'starting');
|
||||
|
||||
const allSessions: AuthenticationSession[] = [];
|
||||
// This branch only gets called by Core for sign out purposes and initial population of the account menu. Since we are
|
||||
// living in a world where a "session" from Core's perspective is an account, we return 1 session per account.
|
||||
// See the large comment on `onDidChangeSessions` for more information.
|
||||
if (askingForAll) {
|
||||
const allSessionsForAccounts = new Map<string, AuthenticationSession>();
|
||||
for (const cachedPca of this._publicClientManager.getAll()) {
|
||||
const sessions = await this.getAllSessionsForPca(cachedPca, scopeData.originalScopes, scopeData.scopesToSend, options?.account);
|
||||
allSessions.push(...sessions);
|
||||
for (const account of cachedPca.accounts) {
|
||||
if (allSessionsForAccounts.has(account.homeAccountId)) {
|
||||
continue;
|
||||
}
|
||||
allSessionsForAccounts.set(account.homeAccountId, this.sessionFromAccountInfo(account));
|
||||
}
|
||||
}
|
||||
const allSessions = Array.from(allSessionsForAccounts.values());
|
||||
this._logger.info('[getSessions] [all]', `returned ${allSessions.length} session(s)`);
|
||||
return allSessions;
|
||||
}
|
||||
|
||||
const cachedPca = await this.getOrCreatePublicClientApplication(scopeData.clientId, scopeData.tenant);
|
||||
const sessions = await this.getAllSessionsForPca(cachedPca, scopeData.originalScopes, scopeData.scopesToSend, options?.account);
|
||||
this._logger.info(`[getSessions] returned ${sessions.length} sessions`);
|
||||
this._logger.info(`[getSessions] [${scopeData.scopeStr}] returned ${sessions.length} session(s)`);
|
||||
return sessions;
|
||||
|
||||
}
|
||||
@@ -121,7 +121,7 @@ export class MsalAuthProvider implements AuthenticationProvider {
|
||||
const scopeData = new ScopeData(scopes);
|
||||
// Do NOT use `scopes` beyond this place in the code. Use `scopeData` instead.
|
||||
|
||||
this._logger.info('[createSession]', scopeData.scopeStr, 'starting');
|
||||
this._logger.info('[createSession]', `[${scopeData.scopeStr}]`, 'starting');
|
||||
const cachedPca = await this.getOrCreatePublicClientApplication(scopeData.clientId, scopeData.tenant);
|
||||
let result: AuthenticationResult;
|
||||
try {
|
||||
@@ -169,32 +169,43 @@ export class MsalAuthProvider implements AuthenticationProvider {
|
||||
}
|
||||
}
|
||||
|
||||
const session = this.toAuthenticationSession(result, scopeData.originalScopes);
|
||||
const session = this.sessionFromAuthenticationResult(result, scopeData.originalScopes);
|
||||
this._telemetryReporter.sendLoginEvent(session.scopes);
|
||||
this._logger.info('[createSession]', scopeData.scopeStr, 'returned session');
|
||||
this._logger.info('[createSession]', `[${scopeData.scopeStr}]`, 'returned session');
|
||||
// This is the only scenario in which we need to fire the _onDidChangeSessionsEmitter out of band...
|
||||
// the badge flow (when the client passes no options in to getSession) will only remove a badge if a session
|
||||
// was created that _matches the scopes_ that that badge requests. See `onDidChangeSessions` for more info.
|
||||
// TODO: This should really be fixed in Core.
|
||||
this._onDidChangeSessionsEmitter.fire({ added: [session], changed: [], removed: [] });
|
||||
return session;
|
||||
}
|
||||
|
||||
async removeSession(sessionId: string): Promise<void> {
|
||||
this._logger.info('[removeSession]', sessionId, 'starting');
|
||||
const promises = new Array<Promise<void>>();
|
||||
for (const cachedPca of this._publicClientManager.getAll()) {
|
||||
const accounts = cachedPca.accounts;
|
||||
for (const account of accounts) {
|
||||
if (account.homeAccountId === sessionId) {
|
||||
this._telemetryReporter.sendLogoutEvent();
|
||||
try {
|
||||
await cachedPca.removeAccount(account);
|
||||
} catch (e) {
|
||||
this._telemetryReporter.sendLogoutFailedEvent();
|
||||
throw e;
|
||||
}
|
||||
this._logger.info('[removeSession]', sessionId, 'removed session');
|
||||
return;
|
||||
promises.push(cachedPca.removeAccount(account));
|
||||
this._logger.info(`[removeSession] [${sessionId}] [${cachedPca.clientId}] [${cachedPca.authority}] removing session...`);
|
||||
}
|
||||
}
|
||||
}
|
||||
this._logger.info('[removeSession]', sessionId, 'session not found');
|
||||
if (!promises.length) {
|
||||
this._logger.info('[removeSession]', sessionId, 'session not found');
|
||||
return;
|
||||
}
|
||||
const results = await Promise.allSettled(promises);
|
||||
for (const result of results) {
|
||||
if (result.status === 'rejected') {
|
||||
this._telemetryReporter.sendLogoutFailedEvent();
|
||||
this._logger.error('[removeSession]', sessionId, 'error removing session', result.reason);
|
||||
}
|
||||
}
|
||||
|
||||
this._logger.info('[removeSession]', sessionId, `attempted to remove ${promises.length} sessions`);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
@@ -217,7 +228,7 @@ export class MsalAuthProvider implements AuthenticationProvider {
|
||||
for (const account of accounts) {
|
||||
try {
|
||||
const result = await cachedPca.acquireTokenSilent({ account, scopes: scopesToSend, redirectUri });
|
||||
sessions.push(this.toAuthenticationSession(result, originalScopes));
|
||||
sessions.push(this.sessionFromAuthenticationResult(result, originalScopes));
|
||||
} catch (e) {
|
||||
// If we can't get a token silently, the account is probably in a bad state so we should skip it
|
||||
// MSAL will log this already, so we don't need to log it again
|
||||
@@ -227,7 +238,7 @@ export class MsalAuthProvider implements AuthenticationProvider {
|
||||
return sessions;
|
||||
}
|
||||
|
||||
private toAuthenticationSession(result: AuthenticationResult, scopes: readonly string[]): AuthenticationSession & { idToken: string } {
|
||||
private sessionFromAuthenticationResult(result: AuthenticationResult, scopes: readonly string[]): AuthenticationSession & { idToken: string } {
|
||||
return {
|
||||
accessToken: result.accessToken,
|
||||
idToken: result.idToken,
|
||||
@@ -239,4 +250,17 @@ export class MsalAuthProvider implements AuthenticationProvider {
|
||||
scopes
|
||||
};
|
||||
}
|
||||
|
||||
private sessionFromAccountInfo(account: AccountInfo): AuthenticationSession {
|
||||
return {
|
||||
accessToken: '1234',
|
||||
id: account.homeAccountId,
|
||||
scopes: [],
|
||||
account: {
|
||||
id: account.homeAccountId,
|
||||
label: account.username
|
||||
},
|
||||
idToken: account.idToken,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { PublicClientApplication, AccountInfo, Configuration, SilentFlowRequest, AuthenticationResult, InteractiveRequest } from '@azure/msal-node';
|
||||
import { Disposable, Memento, SecretStorage, LogOutputChannel, window, ProgressLocation, l10n, EventEmitter } from 'vscode';
|
||||
import { raceCancellationAndTimeoutError } from '../common/async';
|
||||
import { SecretStorageCachePlugin } from '../common/cachePlugin';
|
||||
import { MsalLoggerOptions } from '../common/loggerOptions';
|
||||
import { ICachedPublicClientApplication } from '../common/publicClientCache';
|
||||
|
||||
export class CachedPublicClientApplication implements ICachedPublicClientApplication {
|
||||
private _pca: PublicClientApplication;
|
||||
|
||||
private _accounts: AccountInfo[] = [];
|
||||
private readonly _disposable: Disposable;
|
||||
|
||||
private readonly _loggerOptions = new MsalLoggerOptions(this._logger);
|
||||
private readonly _secretStorageCachePlugin = new SecretStorageCachePlugin(
|
||||
this._secretStorage,
|
||||
// Include the prefix as a differentiator to other secrets
|
||||
`pca:${JSON.stringify({ clientId: this._clientId, authority: this._authority })}`
|
||||
);
|
||||
private readonly _config: Configuration = {
|
||||
auth: { clientId: this._clientId, authority: this._authority },
|
||||
system: {
|
||||
loggerOptions: {
|
||||
correlationId: `${this._clientId}] [${this._authority}`,
|
||||
loggerCallback: (level, message, containsPii) => this._loggerOptions.loggerCallback(level, message, containsPii),
|
||||
}
|
||||
},
|
||||
cache: {
|
||||
cachePlugin: this._secretStorageCachePlugin
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* We keep track of the last time an account was removed so we can recreate the PCA if we detect that an account was removed.
|
||||
* This is due to MSAL-node not providing a way to detect when an account is removed from the cache. An internal issue has been
|
||||
* filed to track this. If MSAL-node ever provides a way to detect this or handle this better in the Persistant Cache Plugin,
|
||||
* we can remove this logic.
|
||||
*/
|
||||
private _lastCreated: Date;
|
||||
|
||||
//#region Events
|
||||
|
||||
private readonly _onDidAccountsChangeEmitter = new EventEmitter<{ added: AccountInfo[]; changed: AccountInfo[]; deleted: AccountInfo[] }>;
|
||||
readonly onDidAccountsChange = this._onDidAccountsChangeEmitter.event;
|
||||
|
||||
private readonly _onDidRemoveLastAccountEmitter = new EventEmitter<void>();
|
||||
readonly onDidRemoveLastAccount = this._onDidRemoveLastAccountEmitter.event;
|
||||
|
||||
//#endregion
|
||||
|
||||
constructor(
|
||||
private readonly _clientId: string,
|
||||
private readonly _authority: string,
|
||||
private readonly _globalMemento: Memento,
|
||||
private readonly _secretStorage: SecretStorage,
|
||||
private readonly _logger: LogOutputChannel
|
||||
) {
|
||||
this._pca = new PublicClientApplication(this._config);
|
||||
this._lastCreated = new Date();
|
||||
this._disposable = Disposable.from(
|
||||
this._registerOnSecretStorageChanged(),
|
||||
this._onDidAccountsChangeEmitter,
|
||||
this._onDidRemoveLastAccountEmitter
|
||||
);
|
||||
}
|
||||
|
||||
get accounts(): AccountInfo[] { return this._accounts; }
|
||||
get clientId(): string { return this._clientId; }
|
||||
get authority(): string { return this._authority; }
|
||||
|
||||
initialize(): Promise<void> {
|
||||
return this._update();
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this._disposable.dispose();
|
||||
}
|
||||
|
||||
async acquireTokenSilent(request: SilentFlowRequest): Promise<AuthenticationResult> {
|
||||
this._logger.debug(`[acquireTokenSilent] [${this._clientId}] [${this._authority}] [${request.scopes.join(' ')}]`);
|
||||
const result = await this._pca.acquireTokenSilent(request);
|
||||
if (result.account && !result.fromCache) {
|
||||
this._onDidAccountsChangeEmitter.fire({ added: [], changed: [result.account], deleted: [] });
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
async acquireTokenInteractive(request: InteractiveRequest): Promise<AuthenticationResult> {
|
||||
this._logger.debug(`[acquireTokenInteractive] [${this._clientId}] [${this._authority}] [${request.scopes?.join(' ')}] loopbackClientOverride: ${request.loopbackClient ? 'true' : 'false'}`);
|
||||
return await window.withProgress(
|
||||
{
|
||||
location: ProgressLocation.Notification,
|
||||
cancellable: true,
|
||||
title: l10n.t('Signing in to Microsoft...')
|
||||
},
|
||||
(_process, token) => raceCancellationAndTimeoutError(
|
||||
this._pca.acquireTokenInteractive(request),
|
||||
token,
|
||||
1000 * 60 * 5
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
removeAccount(account: AccountInfo): Promise<void> {
|
||||
this._globalMemento.update(`lastRemoval:${this._clientId}:${this._authority}`, new Date());
|
||||
return this._pca.getTokenCache().removeAccount(account);
|
||||
}
|
||||
|
||||
private _registerOnSecretStorageChanged() {
|
||||
return this._secretStorageCachePlugin.onDidChange(() => this._update());
|
||||
}
|
||||
|
||||
private async _update() {
|
||||
const before = this._accounts;
|
||||
this._logger.debug(`[update] [${this._clientId}] [${this._authority}] CachedPublicClientApplication update before: ${before.length}`);
|
||||
// Dates are stored as strings in the memento
|
||||
const lastRemovalDate = this._globalMemento.get<string>(`lastRemoval:${this._clientId}:${this._authority}`);
|
||||
if (lastRemovalDate && this._lastCreated && Date.parse(lastRemovalDate) > this._lastCreated.getTime()) {
|
||||
this._logger.debug(`[update] [${this._clientId}] [${this._authority}] CachedPublicClientApplication removal detected... recreating PCA...`);
|
||||
this._pca = new PublicClientApplication(this._config);
|
||||
this._lastCreated = new Date();
|
||||
}
|
||||
|
||||
const after = await this._pca.getAllAccounts();
|
||||
this._accounts = after;
|
||||
this._logger.debug(`[update] [${this._clientId}] [${this._authority}] CachedPublicClientApplication update after: ${after.length}`);
|
||||
|
||||
const beforeSet = new Set(before.map(b => b.homeAccountId));
|
||||
const afterSet = new Set(after.map(a => a.homeAccountId));
|
||||
|
||||
const added = after.filter(a => !beforeSet.has(a.homeAccountId));
|
||||
const deleted = before.filter(b => !afterSet.has(b.homeAccountId));
|
||||
if (added.length > 0 || deleted.length > 0) {
|
||||
this._onDidAccountsChangeEmitter.fire({ added, changed: [], deleted });
|
||||
this._logger.debug(`[update] [${this._clientId}] [${this._authority}] CachedPublicClientApplication accounts changed. added: ${added.length}, deleted: ${deleted.length}`);
|
||||
if (!after.length) {
|
||||
this._logger.debug(`[update] [${this._clientId}] [${this._authority}] CachedPublicClientApplication final account deleted. Firing event.`);
|
||||
this._onDidRemoveLastAccountEmitter.fire();
|
||||
}
|
||||
}
|
||||
this._logger.debug(`[update] [${this._clientId}] [${this._authority}] CachedPublicClientApplication update complete`);
|
||||
}
|
||||
}
|
||||
@@ -3,77 +3,84 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { AccountInfo, AuthenticationResult, Configuration, InteractiveRequest, PublicClientApplication, SilentFlowRequest } from '@azure/msal-node';
|
||||
import { SecretStorageCachePlugin } from '../common/cachePlugin';
|
||||
import { SecretStorage, LogOutputChannel, Disposable, SecretStorageChangeEvent, EventEmitter, Memento, window, ProgressLocation, l10n } from 'vscode';
|
||||
import { MsalLoggerOptions } from '../common/loggerOptions';
|
||||
import { AccountInfo } from '@azure/msal-node';
|
||||
import { SecretStorage, LogOutputChannel, Disposable, EventEmitter, Memento, Event } from 'vscode';
|
||||
import { ICachedPublicClientApplication, ICachedPublicClientApplicationManager } from '../common/publicClientCache';
|
||||
import { raceCancellationAndTimeoutError } from '../common/async';
|
||||
import { CachedPublicClientApplication } from './cachedPublicClientApplication';
|
||||
|
||||
export interface IPublicClientApplicationInfo {
|
||||
clientId: string;
|
||||
authority: string;
|
||||
}
|
||||
|
||||
const _keyPrefix = 'pca:';
|
||||
|
||||
export class CachedPublicClientApplicationManager implements ICachedPublicClientApplicationManager {
|
||||
// The key is the clientId and authority stringified
|
||||
// The key is the clientId and authority JSON stringified
|
||||
private readonly _pcas = new Map<string, CachedPublicClientApplication>();
|
||||
private readonly _pcaDisposables = new Map<string, Disposable>();
|
||||
|
||||
private _initialized = false;
|
||||
private _disposable: Disposable;
|
||||
private _pcasSecretStorage: PublicClientApplicationsSecretStorage;
|
||||
|
||||
private readonly _onDidAccountsChangeEmitter = new EventEmitter<{ added: AccountInfo[]; changed: AccountInfo[]; deleted: AccountInfo[] }>();
|
||||
readonly onDidAccountsChange = this._onDidAccountsChangeEmitter.event;
|
||||
|
||||
constructor(
|
||||
private readonly _globalMemento: Memento,
|
||||
private readonly _secretStorage: SecretStorage,
|
||||
private readonly _logger: LogOutputChannel,
|
||||
private readonly _accountChangeHandler: (e: { added: AccountInfo[]; deleted: AccountInfo[] }) => void
|
||||
private readonly _logger: LogOutputChannel
|
||||
) {
|
||||
this._disposable = _secretStorage.onDidChange(e => this._handleSecretStorageChange(e));
|
||||
this._pcasSecretStorage = new PublicClientApplicationsSecretStorage(_secretStorage);
|
||||
this._disposable = Disposable.from(
|
||||
this._pcasSecretStorage,
|
||||
this._registerSecretStorageHandler(),
|
||||
this._onDidAccountsChangeEmitter
|
||||
);
|
||||
}
|
||||
|
||||
private _registerSecretStorageHandler() {
|
||||
return this._pcasSecretStorage.onDidChange(() => this._handleSecretStorageChange());
|
||||
}
|
||||
|
||||
async initialize() {
|
||||
this._logger.debug('[initialize] Initializing PublicClientApplicationManager');
|
||||
const keys = await this._secretStorage.get('publicClientApplications');
|
||||
let keys: string[] | undefined;
|
||||
try {
|
||||
keys = await this._pcasSecretStorage.get();
|
||||
} catch (e) {
|
||||
// data is corrupted
|
||||
this._logger.error('[initialize] Error initializing PublicClientApplicationManager:', e);
|
||||
await this._pcasSecretStorage.delete();
|
||||
}
|
||||
if (!keys) {
|
||||
this._initialized = true;
|
||||
return;
|
||||
}
|
||||
|
||||
const promises = new Array<Promise<ICachedPublicClientApplication>>();
|
||||
try {
|
||||
for (const key of JSON.parse(keys) as string[]) {
|
||||
try {
|
||||
const { clientId, authority } = JSON.parse(key) as IPublicClientApplicationInfo;
|
||||
// Load the PCA in memory
|
||||
promises.push(this.getOrCreate(clientId, authority));
|
||||
} catch (e) {
|
||||
// ignore
|
||||
}
|
||||
for (const key of keys) {
|
||||
try {
|
||||
const { clientId, authority } = JSON.parse(key) as IPublicClientApplicationInfo;
|
||||
// Load the PCA in memory
|
||||
promises.push(this._doCreatePublicClientApplication(clientId, authority, key));
|
||||
} catch (e) {
|
||||
this._logger.error('[initialize] Error intitializing PCA:', key);
|
||||
}
|
||||
} catch (e) {
|
||||
// data is corrupted
|
||||
this._logger.error('[initialize] Error initializing PublicClientApplicationManager:', e);
|
||||
await this._secretStorage.delete('publicClientApplications');
|
||||
}
|
||||
|
||||
// TODO: should we do anything for when this fails?
|
||||
await Promise.allSettled(promises);
|
||||
const results = await Promise.allSettled(promises);
|
||||
for (const result of results) {
|
||||
if (result.status === 'rejected') {
|
||||
this._logger.error('[initialize] Error getting PCA:', result.reason);
|
||||
}
|
||||
}
|
||||
this._logger.debug('[initialize] PublicClientApplicationManager initialized');
|
||||
this._initialized = true;
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this._disposable.dispose();
|
||||
Disposable.from(...this._pcas.values()).dispose();
|
||||
Disposable.from(...this._pcaDisposables.values()).dispose();
|
||||
}
|
||||
|
||||
async getOrCreate(clientId: string, authority: string): Promise<ICachedPublicClientApplication> {
|
||||
if (!this._initialized) {
|
||||
throw new Error('PublicClientApplicationManager not initialized');
|
||||
}
|
||||
|
||||
// Use the clientId and authority as the key
|
||||
const pcasKey = JSON.stringify({ clientId, authority });
|
||||
let pca = this._pcas.get(pcasKey);
|
||||
@@ -83,170 +90,127 @@ export class CachedPublicClientApplicationManager implements ICachedPublicClient
|
||||
}
|
||||
|
||||
this._logger.debug(`[getOrCreate] [${clientId}] [${authority}] PublicClientApplicationManager cache miss, creating new PCA...`);
|
||||
pca = new CachedPublicClientApplication(clientId, authority, this._globalMemento, this._secretStorage, this._accountChangeHandler, this._logger);
|
||||
this._pcas.set(pcasKey, pca);
|
||||
await pca.initialize();
|
||||
pca = await this._doCreatePublicClientApplication(clientId, authority, pcasKey);
|
||||
await this._storePublicClientApplications();
|
||||
this._logger.debug(`[getOrCreate] [${clientId}] [${authority}] PublicClientApplicationManager PCA created`);
|
||||
this._logger.debug(`[getOrCreate] [${clientId}] [${authority}] PCA created.`);
|
||||
return pca;
|
||||
}
|
||||
|
||||
private async _doCreatePublicClientApplication(clientId: string, authority: string, pcasKey: string) {
|
||||
const pca = new CachedPublicClientApplication(clientId, authority, this._globalMemento, this._secretStorage, this._logger);
|
||||
this._pcas.set(pcasKey, pca);
|
||||
const disposable = Disposable.from(
|
||||
pca,
|
||||
pca.onDidAccountsChange(e => this._onDidAccountsChangeEmitter.fire(e)),
|
||||
pca.onDidRemoveLastAccount(() => {
|
||||
// The PCA has no more accounts, so we can dispose it so we're not keeping it
|
||||
// around forever.
|
||||
disposable.dispose();
|
||||
this._pcas.delete(pcasKey);
|
||||
this._logger.debug(`[_doCreatePublicClientApplication] [${clientId}] [${authority}] PCA disposed. Firing off storing of PCAs...`);
|
||||
void this._storePublicClientApplications();
|
||||
})
|
||||
);
|
||||
this._pcaDisposables.set(pcasKey, disposable);
|
||||
// Intialize the PCA after the `onDidAccountsChange` is set so we get initial state.
|
||||
await pca.initialize();
|
||||
return pca;
|
||||
}
|
||||
|
||||
getAll(): ICachedPublicClientApplication[] {
|
||||
if (!this._initialized) {
|
||||
throw new Error('PublicClientApplicationManager not initialized');
|
||||
}
|
||||
return Array.from(this._pcas.values());
|
||||
}
|
||||
|
||||
private async _handleSecretStorageChange(e: SecretStorageChangeEvent) {
|
||||
if (!e.key.startsWith(_keyPrefix)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._logger.debug(`[handleSecretStorageChange] PublicClientApplicationManager secret storage change: ${e.key}`);
|
||||
const result = await this._secretStorage.get(e.key);
|
||||
const pcasKey = e.key.split(_keyPrefix)[1];
|
||||
|
||||
// If the cache was deleted, or the PCA has zero accounts left, remove the PCA
|
||||
if (!result || this._pcas.get(pcasKey)?.accounts.length === 0) {
|
||||
this._logger.debug(`[handleSecretStorageChange] PublicClientApplicationManager removing PCA: ${pcasKey}`);
|
||||
this._pcas.delete(pcasKey);
|
||||
private async _handleSecretStorageChange() {
|
||||
this._logger.debug(`[_handleSecretStorageChange] Handling PCAs secret storage change...`);
|
||||
let result: string[] | undefined;
|
||||
try {
|
||||
result = await this._pcasSecretStorage.get();
|
||||
} catch (_e) {
|
||||
// The data in secret storage has been corrupted somehow so
|
||||
// we store what we have in this window
|
||||
await this._storePublicClientApplications();
|
||||
this._logger.debug(`[handleSecretStorageChange] PublicClientApplicationManager PCA removed: ${pcasKey}`);
|
||||
return;
|
||||
}
|
||||
if (!result) {
|
||||
this._logger.debug(`[_handleSecretStorageChange] PCAs deleted in secret storage. Disposing all...`);
|
||||
Disposable.from(...this._pcaDisposables.values()).dispose();
|
||||
this._pcas.clear();
|
||||
this._pcaDisposables.clear();
|
||||
this._logger.debug(`[_handleSecretStorageChange] Finished PCAs secret storage change.`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Load the PCA in memory if it's not already loaded
|
||||
const { clientId, authority } = JSON.parse(pcasKey) as IPublicClientApplicationInfo;
|
||||
this._logger.debug(`[handleSecretStorageChange] PublicClientApplicationManager loading PCA: ${pcasKey}`);
|
||||
await this.getOrCreate(clientId, authority);
|
||||
this._logger.debug(`[handleSecretStorageChange] PublicClientApplicationManager PCA loaded: ${pcasKey}`);
|
||||
const pcaKeysFromStorage = new Set(result);
|
||||
// Handle the deleted ones
|
||||
for (const pcaKey of this._pcas.keys()) {
|
||||
if (!pcaKeysFromStorage.delete(pcaKey)) {
|
||||
// This PCA has been removed in another window
|
||||
this._pcaDisposables.get(pcaKey)?.dispose();
|
||||
this._pcaDisposables.delete(pcaKey);
|
||||
this._pcas.delete(pcaKey);
|
||||
this._logger.debug(`[_handleSecretStorageChange] Disposed PCA that was deleted in another window: ${pcaKey}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle the new ones
|
||||
for (const newPca of pcaKeysFromStorage) {
|
||||
try {
|
||||
const { clientId, authority } = JSON.parse(newPca);
|
||||
this._logger.debug(`[_handleSecretStorageChange] [${clientId}] [${authority}] Creating new PCA that was created in another window...`);
|
||||
await this._doCreatePublicClientApplication(clientId, authority, newPca);
|
||||
this._logger.debug(`[_handleSecretStorageChange] [${clientId}] [${authority}] PCA created.`);
|
||||
} catch (_e) {
|
||||
// This really shouldn't happen, but should we do something about this?
|
||||
this._logger.error(`Failed to parse new PublicClientApplication: ${newPca}`);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
this._logger.debug('[_handleSecretStorageChange] Finished handling PCAs secret storage change.');
|
||||
}
|
||||
|
||||
private async _storePublicClientApplications() {
|
||||
await this._secretStorage.store(
|
||||
'publicClientApplications',
|
||||
JSON.stringify(Array.from(this._pcas.keys()))
|
||||
);
|
||||
private _storePublicClientApplications() {
|
||||
return this._pcasSecretStorage.store(Array.from(this._pcas.keys()));
|
||||
}
|
||||
}
|
||||
|
||||
class CachedPublicClientApplication implements ICachedPublicClientApplication {
|
||||
private _pca: PublicClientApplication;
|
||||
class PublicClientApplicationsSecretStorage {
|
||||
private static key = 'publicClientApplications';
|
||||
|
||||
private _accounts: AccountInfo[] = [];
|
||||
private readonly _disposable: Disposable;
|
||||
private _disposable: Disposable;
|
||||
|
||||
private readonly _loggerOptions = new MsalLoggerOptions(this._logger);
|
||||
private readonly _secretStorageCachePlugin = new SecretStorageCachePlugin(
|
||||
this._secretStorage,
|
||||
// Include the prefix in the key so we can easily identify it later
|
||||
`${_keyPrefix}${JSON.stringify({ clientId: this._clientId, authority: this._authority })}`
|
||||
);
|
||||
private readonly _config: Configuration = {
|
||||
auth: { clientId: this._clientId, authority: this._authority },
|
||||
system: {
|
||||
loggerOptions: {
|
||||
correlationId: `${this._clientId}] [${this._authority}`,
|
||||
loggerCallback: (level, message, containsPii) => this._loggerOptions.loggerCallback(level, message, containsPii),
|
||||
}
|
||||
},
|
||||
cache: {
|
||||
cachePlugin: this._secretStorageCachePlugin
|
||||
private readonly _onDidChangeEmitter = new EventEmitter<void>;
|
||||
readonly onDidChange: Event<void> = this._onDidChangeEmitter.event;
|
||||
|
||||
constructor(private readonly _secretStorage: SecretStorage) {
|
||||
this._disposable = Disposable.from(
|
||||
this._onDidChangeEmitter,
|
||||
this._secretStorage.onDidChange(e => {
|
||||
if (e.key === PublicClientApplicationsSecretStorage.key) {
|
||||
this._onDidChangeEmitter.fire();
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
async get(): Promise<string[] | undefined> {
|
||||
const value = await this._secretStorage.get(PublicClientApplicationsSecretStorage.key);
|
||||
if (!value) {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* We keep track of the last time an account was removed so we can recreate the PCA if we detect that an account was removed.
|
||||
* This is due to MSAL-node not providing a way to detect when an account is removed from the cache. An internal issue has been
|
||||
* filed to track this. If MSAL-node ever provides a way to detect this or handle this better in the Persistant Cache Plugin,
|
||||
* we can remove this logic.
|
||||
*/
|
||||
private _lastCreated: Date;
|
||||
|
||||
constructor(
|
||||
private readonly _clientId: string,
|
||||
private readonly _authority: string,
|
||||
private readonly _globalMemento: Memento,
|
||||
private readonly _secretStorage: SecretStorage,
|
||||
private readonly _accountChangeHandler: (e: { added: AccountInfo[]; changed: AccountInfo[]; deleted: AccountInfo[] }) => void,
|
||||
private readonly _logger: LogOutputChannel
|
||||
) {
|
||||
this._pca = new PublicClientApplication(this._config);
|
||||
this._lastCreated = new Date();
|
||||
this._disposable = this._registerOnSecretStorageChanged();
|
||||
return JSON.parse(value);
|
||||
}
|
||||
|
||||
get accounts(): AccountInfo[] { return this._accounts; }
|
||||
get clientId(): string { return this._clientId; }
|
||||
get authority(): string { return this._authority; }
|
||||
|
||||
initialize(): Promise<void> {
|
||||
return this._update();
|
||||
store(value: string[]): Thenable<void> {
|
||||
return this._secretStorage.store(PublicClientApplicationsSecretStorage.key, JSON.stringify(value));
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
delete(): Thenable<void> {
|
||||
return this._secretStorage.delete(PublicClientApplicationsSecretStorage.key);
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this._disposable.dispose();
|
||||
}
|
||||
|
||||
async acquireTokenSilent(request: SilentFlowRequest): Promise<AuthenticationResult> {
|
||||
this._logger.debug(`[acquireTokenSilent] [${this._clientId}] [${this._authority}] [${request.scopes.join(' ')}]`);
|
||||
const result = await this._pca.acquireTokenSilent(request);
|
||||
if (result.account && !result.fromCache) {
|
||||
this._accountChangeHandler({ added: [], changed: [result.account], deleted: [] });
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
async acquireTokenInteractive(request: InteractiveRequest): Promise<AuthenticationResult> {
|
||||
this._logger.debug(`[acquireTokenInteractive] [${this._clientId}] [${this._authority}] [${request.scopes?.join(' ')}] loopbackClientOverride: ${request.loopbackClient ? 'true' : 'false'}`);
|
||||
return await window.withProgress(
|
||||
{
|
||||
location: ProgressLocation.Notification,
|
||||
cancellable: true,
|
||||
title: l10n.t('Signing in to Microsoft...')
|
||||
},
|
||||
(_process, token) => raceCancellationAndTimeoutError(
|
||||
this._pca.acquireTokenInteractive(request),
|
||||
token,
|
||||
1000 * 60 * 5
|
||||
), // 5 minutes
|
||||
);
|
||||
}
|
||||
|
||||
removeAccount(account: AccountInfo): Promise<void> {
|
||||
this._globalMemento.update(`lastRemoval:${this._clientId}:${this._authority}`, new Date());
|
||||
return this._pca.getTokenCache().removeAccount(account);
|
||||
}
|
||||
|
||||
private _registerOnSecretStorageChanged() {
|
||||
return this._secretStorageCachePlugin.onDidChange(() => this._update());
|
||||
}
|
||||
|
||||
private async _update() {
|
||||
const before = this._accounts;
|
||||
this._logger.debug(`[update] [${this._clientId}] [${this._authority}] CachedPublicClientApplication update before: ${before.length}`);
|
||||
// Dates are stored as strings in the memento
|
||||
const lastRemovalDate = this._globalMemento.get<string>(`lastRemoval:${this._clientId}:${this._authority}`);
|
||||
if (lastRemovalDate && this._lastCreated && Date.parse(lastRemovalDate) > this._lastCreated.getTime()) {
|
||||
this._logger.debug(`[update] [${this._clientId}] [${this._authority}] CachedPublicClientApplication removal detected... recreating PCA...`);
|
||||
this._pca = new PublicClientApplication(this._config);
|
||||
this._lastCreated = new Date();
|
||||
}
|
||||
|
||||
const after = await this._pca.getAllAccounts();
|
||||
this._accounts = after;
|
||||
this._logger.debug(`[update] [${this._clientId}] [${this._authority}] CachedPublicClientApplication update after: ${after.length}`);
|
||||
|
||||
const beforeSet = new Set(before.map(b => b.homeAccountId));
|
||||
const afterSet = new Set(after.map(a => a.homeAccountId));
|
||||
|
||||
const added = after.filter(a => !beforeSet.has(a.homeAccountId));
|
||||
const deleted = before.filter(b => !afterSet.has(b.homeAccountId));
|
||||
if (added.length > 0 || deleted.length > 0) {
|
||||
this._accountChangeHandler({ added, changed: [], deleted });
|
||||
this._logger.debug(`[update] [${this._clientId}] [${this._authority}] CachedPublicClientApplication accounts changed. added: ${added.length}, deleted: ${deleted.length}`);
|
||||
}
|
||||
this._logger.debug(`[update] [${this._clientId}] [${this._authority}] CachedPublicClientApplication update complete`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,5 +4,4 @@ tsconfig.json
|
||||
.vscode/**
|
||||
extension.webpack.config.js
|
||||
extension-browser.webpack.config.js
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
|
||||
Generated
+11
-9
@@ -193,15 +193,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/micromatch": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
|
||||
"integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
|
||||
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"braces": "^3.0.1",
|
||||
"picomatch": "^2.0.5"
|
||||
"braces": "^3.0.3",
|
||||
"picomatch": "^2.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
"node": ">=8.6"
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
@@ -252,9 +253,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
|
||||
"integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8.6"
|
||||
},
|
||||
|
||||
Generated
+5
-4
@@ -547,12 +547,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/micromatch": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
|
||||
"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
|
||||
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"braces": "^3.0.2",
|
||||
"braces": "^3.0.3",
|
||||
"picomatch": "^2.3.1"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -3,5 +3,4 @@ src/**
|
||||
out/**
|
||||
tsconfig.json
|
||||
extension.webpack.config.js
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
|
||||
@@ -3,5 +3,4 @@ src/**
|
||||
out/**
|
||||
tsconfig.json
|
||||
*.webpack.config.js
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
|
||||
@@ -3,6 +3,5 @@ out/**
|
||||
tsconfig.json
|
||||
extension.webpack.config.js
|
||||
extension-browser.webpack.config.js
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
syntaxes/generateTMLanguage.js
|
||||
|
||||
@@ -12,7 +12,6 @@ const path = require('path');
|
||||
const fs = require('fs');
|
||||
const merge = require('merge-options');
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||
const { NLSBundlePlugin } = require('vscode-nls-dev/lib/webpack-bundler');
|
||||
const { DefinePlugin, optimize } = require('webpack');
|
||||
|
||||
const tsLoaderOptions = {
|
||||
@@ -40,13 +39,6 @@ function withNodeDefaults(/**@type WebpackConfig & { context: string }*/extConfi
|
||||
test: /\.ts$/,
|
||||
exclude: /node_modules/,
|
||||
use: [{
|
||||
// vscode-nls-dev loader:
|
||||
// * rewrite nls-calls
|
||||
loader: 'vscode-nls-dev/lib/webpack-loader',
|
||||
options: {
|
||||
base: path.join(extConfig.context, 'src')
|
||||
}
|
||||
}, {
|
||||
// configure TypeScript loader:
|
||||
// * enable sources maps for end-to-end source maps
|
||||
loader: 'ts-loader',
|
||||
@@ -97,8 +89,7 @@ function nodePlugins(context) {
|
||||
patterns: [
|
||||
{ from: 'src', to: '.', globOptions: { ignore: ['**/test/**', '**/*.ts'] }, noErrorOnMissing: true }
|
||||
]
|
||||
}),
|
||||
new NLSBundlePlugin(id)
|
||||
})
|
||||
];
|
||||
}
|
||||
/**
|
||||
@@ -196,9 +187,7 @@ function browserPlugins(context) {
|
||||
'process.platform': JSON.stringify('web'),
|
||||
'process.env': JSON.stringify({}),
|
||||
'process.env.BROWSER_ENV': JSON.stringify('true')
|
||||
}),
|
||||
// TODO: bring this back once vscode-nls-dev supports browser
|
||||
// new NLSBundlePlugin(id)
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ extension.webpack.config.js
|
||||
extension-browser.webpack.config.js
|
||||
cgmanifest.json
|
||||
.gitignore
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
preview-src/**
|
||||
webpack.config.js
|
||||
|
||||
@@ -2,5 +2,4 @@ src/**
|
||||
tsconfig.json
|
||||
out/**
|
||||
extension.webpack.config.js
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
|
||||
@@ -8,5 +8,4 @@ tsconfig.json
|
||||
extension.webpack.config.js
|
||||
extension-browser.webpack.config.js
|
||||
cgmanifest.json
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
|
||||
Generated
+79
-595
@@ -10,6 +10,7 @@
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@bpasero/watcher": "https://github.com/bpasero/watcher.git#5d29cc732a03c91ecc2c861940a240b01e765c65",
|
||||
"@microsoft/1ds-core-js": "^3.2.13",
|
||||
"@microsoft/1ds-post-js": "^3.2.13",
|
||||
"@parcel/watcher": "2.1.0",
|
||||
@@ -21,7 +22,7 @@
|
||||
"@vscode/spdlog": "^0.15.0",
|
||||
"@vscode/sqlite3": "5.1.6-vscode",
|
||||
"@vscode/sudo-prompt": "9.3.1",
|
||||
"@vscode/tree-sitter-wasm": "^0.0.2",
|
||||
"@vscode/tree-sitter-wasm": "^0.0.3",
|
||||
"@vscode/vscode-languagedetection": "1.0.21",
|
||||
"@vscode/windows-mutex": "^0.5.0",
|
||||
"@vscode/windows-process-tree": "^0.6.0",
|
||||
@@ -84,6 +85,7 @@
|
||||
"@vscode/test-web": "^0.0.56",
|
||||
"@vscode/v8-heap-parser": "^0.1.0",
|
||||
"@vscode/vscode-perf": "^0.0.14",
|
||||
"@webgpu/types": "^0.1.44",
|
||||
"ansi-colors": "^3.2.3",
|
||||
"asar": "^3.0.3",
|
||||
"chromium-pickle-js": "^0.2.0",
|
||||
@@ -131,7 +133,6 @@
|
||||
"mime": "^1.4.1",
|
||||
"minimatch": "^3.0.4",
|
||||
"minimist": "^1.2.6",
|
||||
"mkdirp": "^1.0.4",
|
||||
"mocha": "^10.2.0",
|
||||
"mocha-junit-reporter": "^2.2.1",
|
||||
"mocha-multi-reporters": "^1.5.1",
|
||||
@@ -156,7 +157,6 @@
|
||||
"tslib": "^2.6.3",
|
||||
"typescript": "^5.7.0-dev.20240903",
|
||||
"util": "^0.12.4",
|
||||
"vscode-nls-dev": "^3.3.1",
|
||||
"webpack": "^5.94.0",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack-stream": "^7.0.0",
|
||||
@@ -941,6 +941,44 @@
|
||||
"integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@bpasero/watcher": {
|
||||
"version": "2.4.2-alpha.0",
|
||||
"resolved": "git+ssh://git@github.com/bpasero/watcher.git#5d29cc732a03c91ecc2c861940a240b01e765c65",
|
||||
"integrity": "sha512-8AWyO22MDRxp6zAJxDWXGFCHtBoioaku+x/IQrDT3VADhBRAeCVp/47qCVrHFyU0ixo0m8KGDBN6MtxqsFFU2g==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"detect-libc": "^1.0.3",
|
||||
"is-glob": "^4.0.3",
|
||||
"micromatch": "^4.0.5",
|
||||
"node-addon-api": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@bpasero/watcher/node_modules/detect-libc": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
|
||||
"integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"detect-libc": "bin/detect-libc.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@bpasero/watcher/node_modules/node-addon-api": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
|
||||
"integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@cspotcode/source-map-support": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
||||
@@ -3167,9 +3205,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vscode/tree-sitter-wasm": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@vscode/tree-sitter-wasm/-/tree-sitter-wasm-0.0.2.tgz",
|
||||
"integrity": "sha512-N57MR/kt4jR0H/TXeDsVYeJmvvUiK7avow0fjy+/EeKcyNBJcM2BFhj4XOAaaMbhGsOcIeSvJFouRWctXI7sKw=="
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@vscode/tree-sitter-wasm/-/tree-sitter-wasm-0.0.3.tgz",
|
||||
"integrity": "sha512-K5YmUdohFCavPqEzG2cUPcZ6555KE1qwMDCjkvSUSz+s+8Wro2xfg+syLq90y6Tq0ZSUVvpuX6yq6ukToeGaLg=="
|
||||
},
|
||||
"node_modules/@vscode/v8-heap-parser": {
|
||||
"version": "0.1.0",
|
||||
@@ -3414,6 +3452,12 @@
|
||||
"@xtuc/long": "4.2.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@webgpu/types": {
|
||||
"version": "0.1.44",
|
||||
"resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.44.tgz",
|
||||
"integrity": "sha512-JDpYJN5E/asw84LTYhKyvPpxGnD+bAKPtpW9Ilurf7cZpxaTbxkQcGwOd7jgB9BPBrTYQ+32ufo4HiuomTjHNQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@webpack-cli/configtest": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz",
|
||||
@@ -6699,119 +6743,6 @@
|
||||
"node": ">=0.8.x"
|
||||
}
|
||||
},
|
||||
"node_modules/execa": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
|
||||
"integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"cross-spawn": "^6.0.0",
|
||||
"get-stream": "^4.0.0",
|
||||
"is-stream": "^1.1.0",
|
||||
"npm-run-path": "^2.0.0",
|
||||
"p-finally": "^1.0.0",
|
||||
"signal-exit": "^3.0.0",
|
||||
"strip-eof": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/execa/node_modules/cross-spawn": {
|
||||
"version": "6.0.5",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
|
||||
"integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"nice-try": "^1.0.4",
|
||||
"path-key": "^2.0.1",
|
||||
"semver": "^5.5.0",
|
||||
"shebang-command": "^1.2.0",
|
||||
"which": "^1.2.9"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.8"
|
||||
}
|
||||
},
|
||||
"node_modules/execa/node_modules/get-stream": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
|
||||
"integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"pump": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/execa/node_modules/path-key": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
|
||||
"integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/execa/node_modules/pump": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
||||
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"end-of-stream": "^1.1.0",
|
||||
"once": "^1.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/execa/node_modules/semver": {
|
||||
"version": "5.7.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
|
||||
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"semver": "bin/semver"
|
||||
}
|
||||
},
|
||||
"node_modules/execa/node_modules/shebang-command": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
|
||||
"integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"shebang-regex": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/execa/node_modules/shebang-regex": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
|
||||
"integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/execa/node_modules/signal-exit": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
|
||||
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/execa/node_modules/which": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
||||
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"isexe": "^2.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"which": "bin/which"
|
||||
}
|
||||
},
|
||||
"node_modules/expand-brackets": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
|
||||
@@ -8836,7 +8767,7 @@
|
||||
"node_modules/gulp-cli/node_modules/ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8= sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
|
||||
"integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -8845,7 +8776,7 @@
|
||||
"node_modules/gulp-cli/node_modules/camelcase": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
|
||||
"integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo= sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==",
|
||||
"integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -8947,9 +8878,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/gulp-cli/node_modules/yargs": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.1.tgz",
|
||||
"integrity": "sha512-huO4Fr1f9PmiJJdll5kwoS2e4GqzGSsMT3PPMpOwoVkOK8ckqAewMTZyA6LXVQWflleb/Z8oPBEvNsMft0XE+g==",
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.2.tgz",
|
||||
"integrity": "sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"camelcase": "^3.0.0",
|
||||
@@ -8964,13 +8895,13 @@
|
||||
"string-width": "^1.0.2",
|
||||
"which-module": "^1.0.0",
|
||||
"y18n": "^3.2.1",
|
||||
"yargs-parser": "5.0.0-security.0"
|
||||
"yargs-parser": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/gulp-cli/node_modules/yargs-parser": {
|
||||
"version": "5.0.0-security.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0-security.0.tgz",
|
||||
"integrity": "sha512-T69y4Ps64LNesYxeYGYPvfoMTt/7y1XtfpIslUeK4um+9Hu7hlGoRtaDLvdXb7+/tfq4opVa2HRY5xGip022rQ==",
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.1.tgz",
|
||||
"integrity": "sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"camelcase": "^3.0.0",
|
||||
@@ -9066,9 +8997,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/gulp-eslint/node_modules/ansi-regex": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
|
||||
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= sha512-wFUFA5bg5dviipbQQ32yOQhl6gcJaJXiHE7dvR8VYPG97+J/GNC5FKGepKdEDUFeXRzDxPF1X/Btc8L+v7oqIQ==",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz",
|
||||
"integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
@@ -9838,7 +9769,7 @@
|
||||
"node_modules/gulp-plumber/node_modules/ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8= sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
|
||||
"integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -10389,7 +10320,7 @@
|
||||
"node_modules/has-ansi/node_modules/ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8= sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
|
||||
"integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -10685,7 +10616,7 @@
|
||||
"node_modules/husky/node_modules/ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8= sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
|
||||
"integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -10912,9 +10843,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/inquirer/node_modules/ansi-regex": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
|
||||
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
|
||||
"integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
@@ -11045,9 +10976,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/inquirer/node_modules/string-width/node_modules/ansi-regex": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
|
||||
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= sha512-wFUFA5bg5dviipbQQ32yOQhl6gcJaJXiHE7dvR8VYPG97+J/GNC5FKGepKdEDUFeXRzDxPF1X/Btc8L+v7oqIQ==",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz",
|
||||
"integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
@@ -11119,15 +11050,6 @@
|
||||
"node": ">= 12"
|
||||
}
|
||||
},
|
||||
"node_modules/is": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is/-/is-3.2.1.tgz",
|
||||
"integrity": "sha1-0Kwq1V63sL7JJqUmb2xmKqqD3KU= sha512-NgGnzF+/wucMxle6i32obg/UjUqQruwlJUtjBpDEMXNq8vPLuaf28U4q+yes1I6J89FoErr7kDtBGICoNaY7rQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/is-absolute": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz",
|
||||
@@ -12565,18 +12487,6 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/map-age-cleaner": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz",
|
||||
"integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"p-defer": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/map-cache": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
|
||||
@@ -12847,20 +12757,6 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mem": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz",
|
||||
"integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"map-age-cleaner": "^0.1.1",
|
||||
"mimic-fn": "^2.0.0",
|
||||
"p-is-promise": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/memoizee": {
|
||||
"version": "0.4.15",
|
||||
"resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz",
|
||||
@@ -12951,11 +12847,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/micromatch": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
|
||||
"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
|
||||
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"braces": "^3.0.2",
|
||||
"braces": "^3.0.3",
|
||||
"picomatch": "^2.3.1"
|
||||
},
|
||||
"engines": {
|
||||
@@ -13872,27 +13769,6 @@
|
||||
"which": "bin/which"
|
||||
}
|
||||
},
|
||||
"node_modules/npm-run-path": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
|
||||
"integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"path-key": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/npm-run-path/node_modules/path-key": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
|
||||
"integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/nth-check": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz",
|
||||
@@ -14401,33 +14277,6 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/p-defer": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
|
||||
"integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/p-finally": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
|
||||
"integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/p-is-promise": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz",
|
||||
"integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/p-limit": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
|
||||
@@ -17746,15 +17595,6 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-eof": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
|
||||
"integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-json-comments": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
|
||||
@@ -17971,9 +17811,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/table/node_modules/ansi-regex": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
|
||||
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
|
||||
"integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
@@ -19258,362 +19098,6 @@
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-nls-dev": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-nls-dev/-/vscode-nls-dev-3.3.1.tgz",
|
||||
"integrity": "sha512-fug18D7CXb8pv8JoQ0D0JmZaIYDQoKLiyZxkAy5P8Cln/FwlNsdzwQILDph62EdGY5pvsJ2Jd1T5qgHAExe/tg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-colors": "^3.2.3",
|
||||
"clone": "^2.1.1",
|
||||
"event-stream": "^3.3.4",
|
||||
"fancy-log": "^1.3.3",
|
||||
"glob": "^7.1.2",
|
||||
"iconv-lite": "^0.4.19",
|
||||
"is": "^3.2.1",
|
||||
"source-map": "^0.6.1",
|
||||
"typescript": "^2.6.2",
|
||||
"vinyl": "^2.1.0",
|
||||
"xml2js": "^0.4.19",
|
||||
"yargs": "^13.2.4"
|
||||
},
|
||||
"bin": {
|
||||
"vscl": "lib/vscl.js"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-nls-dev/node_modules/ansi-regex": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
|
||||
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-nls-dev/node_modules/ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-convert": "^1.9.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-nls-dev/node_modules/camelcase": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
|
||||
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-nls-dev/node_modules/cliui": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
|
||||
"integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"string-width": "^3.1.0",
|
||||
"strip-ansi": "^5.2.0",
|
||||
"wrap-ansi": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-nls-dev/node_modules/color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-nls-dev/node_modules/color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/vscode-nls-dev/node_modules/decamelize": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
|
||||
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-nls-dev/node_modules/emoji-regex": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
|
||||
"integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/vscode-nls-dev/node_modules/find-up": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
|
||||
"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"locate-path": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-nls-dev/node_modules/glob": {
|
||||
"version": "7.1.6",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
|
||||
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
|
||||
"deprecated": "Glob versions prior to v9 are no longer supported",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-nls-dev/node_modules/invert-kv": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz",
|
||||
"integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-nls-dev/node_modules/is-fullwidth-code-point": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
|
||||
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-nls-dev/node_modules/lcid": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz",
|
||||
"integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"invert-kv": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-nls-dev/node_modules/locate-path": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
|
||||
"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"p-locate": "^3.0.0",
|
||||
"path-exists": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-nls-dev/node_modules/os-locale": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz",
|
||||
"integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"execa": "^1.0.0",
|
||||
"lcid": "^2.0.0",
|
||||
"mem": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-nls-dev/node_modules/p-limit": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
|
||||
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"p-try": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-nls-dev/node_modules/p-locate": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
|
||||
"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"p-limit": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-nls-dev/node_modules/path-exists": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
|
||||
"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-nls-dev/node_modules/replace-ext": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz",
|
||||
"integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-nls-dev/node_modules/string-width": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
|
||||
"integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"emoji-regex": "^7.0.1",
|
||||
"is-fullwidth-code-point": "^2.0.0",
|
||||
"strip-ansi": "^5.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-nls-dev/node_modules/strip-ansi": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
|
||||
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-regex": "^4.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-nls-dev/node_modules/typescript": {
|
||||
"version": "2.9.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz",
|
||||
"integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-nls-dev/node_modules/vinyl": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz",
|
||||
"integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"clone": "^2.1.1",
|
||||
"clone-buffer": "^1.0.0",
|
||||
"clone-stats": "^1.0.0",
|
||||
"cloneable-readable": "^1.0.0",
|
||||
"remove-trailing-separator": "^1.0.1",
|
||||
"replace-ext": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-nls-dev/node_modules/wrap-ansi": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
|
||||
"integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^3.2.0",
|
||||
"string-width": "^3.0.0",
|
||||
"strip-ansi": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-nls-dev/node_modules/xml2js": {
|
||||
"version": "0.4.23",
|
||||
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz",
|
||||
"integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"sax": ">=0.6.0",
|
||||
"xmlbuilder": "~11.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-nls-dev/node_modules/xmlbuilder": {
|
||||
"version": "11.0.1",
|
||||
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
|
||||
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-nls-dev/node_modules/y18n": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz",
|
||||
"integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/vscode-nls-dev/node_modules/yargs": {
|
||||
"version": "13.2.4",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz",
|
||||
"integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"cliui": "^5.0.0",
|
||||
"find-up": "^3.0.0",
|
||||
"get-caller-file": "^2.0.1",
|
||||
"os-locale": "^3.1.0",
|
||||
"require-directory": "^2.1.1",
|
||||
"require-main-filename": "^2.0.0",
|
||||
"set-blocking": "^2.0.0",
|
||||
"string-width": "^3.0.0",
|
||||
"which-module": "^2.0.0",
|
||||
"y18n": "^4.0.0",
|
||||
"yargs-parser": "^13.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-nls-dev/node_modules/yargs-parser": {
|
||||
"version": "13.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz",
|
||||
"integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-oniguruma": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
|
||||
|
||||
+7
-7
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "code-oss-dev",
|
||||
"version": "1.94.0",
|
||||
"distro": "1f99a7e25e381bc566d839c0259770ef5735d8ed",
|
||||
"distro": "94e8178dbd2d80f72a25452eff94052eb9fbcf68",
|
||||
"author": {
|
||||
"name": "Microsoft Corporation"
|
||||
},
|
||||
@@ -28,11 +28,11 @@
|
||||
"kill-watch-webd": "deemon --kill npm run watch-web",
|
||||
"restart-watchd": "deemon --restart npm run watch",
|
||||
"restart-watch-webd": "deemon --restart npm run watch-web",
|
||||
"watch-client": "node ./node_modules/gulp/bin/gulp.js watch-client",
|
||||
"watch-client-amd": "node ./node_modules/gulp/bin/gulp.js watch-client-amd",
|
||||
"watch-client": "node --max-old-space-size=8192 ./node_modules/gulp/bin/gulp.js watch-client",
|
||||
"watch-client-amd": "node --max-old-space-size=8192 ./node_modules/gulp/bin/gulp.js watch-client-amd",
|
||||
"watch-clientd": "deemon npm run watch-client",
|
||||
"kill-watch-clientd": "deemon --kill npm run watch-client",
|
||||
"watch-extensions": "node ./node_modules/gulp/bin/gulp.js watch-extensions watch-extension-media",
|
||||
"watch-extensions": "node --max-old-space-size=8192 ./node_modules/gulp/bin/gulp.js watch-extensions watch-extension-media",
|
||||
"watch-extensionsd": "deemon npm run watch-extensions",
|
||||
"kill-watch-extensionsd": "deemon --kill npm run watch-extensions",
|
||||
"precommit": "node build/hygiene.js",
|
||||
@@ -75,6 +75,7 @@
|
||||
"@microsoft/1ds-core-js": "^3.2.13",
|
||||
"@microsoft/1ds-post-js": "^3.2.13",
|
||||
"@parcel/watcher": "2.1.0",
|
||||
"@bpasero/watcher": "https://github.com/bpasero/watcher.git#5d29cc732a03c91ecc2c861940a240b01e765c65",
|
||||
"@vscode/deviceid": "^0.1.1",
|
||||
"@vscode/iconv-lite-umd": "0.7.0",
|
||||
"@vscode/policy-watcher": "^1.1.4",
|
||||
@@ -83,7 +84,7 @@
|
||||
"@vscode/spdlog": "^0.15.0",
|
||||
"@vscode/sqlite3": "5.1.6-vscode",
|
||||
"@vscode/sudo-prompt": "9.3.1",
|
||||
"@vscode/tree-sitter-wasm": "^0.0.2",
|
||||
"@vscode/tree-sitter-wasm": "^0.0.3",
|
||||
"@vscode/vscode-languagedetection": "1.0.21",
|
||||
"@vscode/windows-mutex": "^0.5.0",
|
||||
"@vscode/windows-process-tree": "^0.6.0",
|
||||
@@ -146,6 +147,7 @@
|
||||
"@vscode/test-web": "^0.0.56",
|
||||
"@vscode/v8-heap-parser": "^0.1.0",
|
||||
"@vscode/vscode-perf": "^0.0.14",
|
||||
"@webgpu/types": "^0.1.44",
|
||||
"ansi-colors": "^3.2.3",
|
||||
"asar": "^3.0.3",
|
||||
"chromium-pickle-js": "^0.2.0",
|
||||
@@ -193,7 +195,6 @@
|
||||
"mime": "^1.4.1",
|
||||
"minimatch": "^3.0.4",
|
||||
"minimist": "^1.2.6",
|
||||
"mkdirp": "^1.0.4",
|
||||
"mocha": "^10.2.0",
|
||||
"mocha-junit-reporter": "^2.2.1",
|
||||
"mocha-multi-reporters": "^1.5.1",
|
||||
@@ -218,7 +219,6 @@
|
||||
"tslib": "^2.6.3",
|
||||
"typescript": "^5.7.0-dev.20240903",
|
||||
"util": "^0.12.4",
|
||||
"vscode-nls-dev": "^3.3.1",
|
||||
"webpack": "^5.94.0",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack-stream": "^7.0.0",
|
||||
|
||||
Generated
+43
-4
@@ -8,6 +8,7 @@
|
||||
"name": "vscode-reh",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@bpasero/watcher": "https://github.com/bpasero/watcher.git#5d29cc732a03c91ecc2c861940a240b01e765c65",
|
||||
"@microsoft/1ds-core-js": "^3.2.13",
|
||||
"@microsoft/1ds-post-js": "^3.2.13",
|
||||
"@parcel/watcher": "2.1.0",
|
||||
@@ -16,7 +17,7 @@
|
||||
"@vscode/proxy-agent": "^0.23.0",
|
||||
"@vscode/ripgrep": "^1.15.9",
|
||||
"@vscode/spdlog": "^0.15.0",
|
||||
"@vscode/tree-sitter-wasm": "^0.0.2",
|
||||
"@vscode/tree-sitter-wasm": "^0.0.3",
|
||||
"@vscode/vscode-languagedetection": "1.0.21",
|
||||
"@vscode/windows-process-tree": "^0.6.0",
|
||||
"@vscode/windows-registry": "^1.1.0",
|
||||
@@ -44,6 +45,44 @@
|
||||
"yazl": "^2.4.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@bpasero/watcher": {
|
||||
"version": "2.4.2-alpha.0",
|
||||
"resolved": "git+ssh://git@github.com/bpasero/watcher.git#5d29cc732a03c91ecc2c861940a240b01e765c65",
|
||||
"integrity": "sha512-8AWyO22MDRxp6zAJxDWXGFCHtBoioaku+x/IQrDT3VADhBRAeCVp/47qCVrHFyU0ixo0m8KGDBN6MtxqsFFU2g==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"detect-libc": "^1.0.3",
|
||||
"is-glob": "^4.0.3",
|
||||
"micromatch": "^4.0.5",
|
||||
"node-addon-api": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@bpasero/watcher/node_modules/detect-libc": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
|
||||
"integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"detect-libc": "bin/detect-libc.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@bpasero/watcher/node_modules/node-addon-api": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
|
||||
"integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@microsoft/1ds-core-js": {
|
||||
"version": "3.2.13",
|
||||
"resolved": "https://registry.npmjs.org/@microsoft/1ds-core-js/-/1ds-core-js-3.2.13.tgz",
|
||||
@@ -184,9 +223,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vscode/tree-sitter-wasm": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@vscode/tree-sitter-wasm/-/tree-sitter-wasm-0.0.2.tgz",
|
||||
"integrity": "sha512-N57MR/kt4jR0H/TXeDsVYeJmvvUiK7avow0fjy+/EeKcyNBJcM2BFhj4XOAaaMbhGsOcIeSvJFouRWctXI7sKw=="
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@vscode/tree-sitter-wasm/-/tree-sitter-wasm-0.0.3.tgz",
|
||||
"integrity": "sha512-K5YmUdohFCavPqEzG2cUPcZ6555KE1qwMDCjkvSUSz+s+8Wro2xfg+syLq90y6Tq0ZSUVvpuX6yq6ukToeGaLg=="
|
||||
},
|
||||
"node_modules/@vscode/vscode-languagedetection": {
|
||||
"version": "1.0.21",
|
||||
|
||||
+2
-1
@@ -6,12 +6,13 @@
|
||||
"@microsoft/1ds-core-js": "^3.2.13",
|
||||
"@microsoft/1ds-post-js": "^3.2.13",
|
||||
"@parcel/watcher": "2.1.0",
|
||||
"@bpasero/watcher": "https://github.com/bpasero/watcher.git#5d29cc732a03c91ecc2c861940a240b01e765c65",
|
||||
"@vscode/deviceid": "^0.1.1",
|
||||
"@vscode/iconv-lite-umd": "0.7.0",
|
||||
"@vscode/proxy-agent": "^0.23.0",
|
||||
"@vscode/ripgrep": "^1.15.9",
|
||||
"@vscode/spdlog": "^0.15.0",
|
||||
"@vscode/tree-sitter-wasm": "^0.0.2",
|
||||
"@vscode/tree-sitter-wasm": "^0.0.3",
|
||||
"@vscode/vscode-languagedetection": "1.0.21",
|
||||
"@vscode/windows-process-tree": "^0.6.0",
|
||||
"@vscode/windows-registry": "^1.1.0",
|
||||
|
||||
Generated
+4
-4
@@ -11,7 +11,7 @@
|
||||
"@microsoft/1ds-core-js": "^3.2.13",
|
||||
"@microsoft/1ds-post-js": "^3.2.13",
|
||||
"@vscode/iconv-lite-umd": "0.7.0",
|
||||
"@vscode/tree-sitter-wasm": "^0.0.2",
|
||||
"@vscode/tree-sitter-wasm": "^0.0.3",
|
||||
"@vscode/vscode-languagedetection": "1.0.21",
|
||||
"@xterm/addon-clipboard": "0.2.0-beta.39",
|
||||
"@xterm/addon-image": "0.9.0-beta.56",
|
||||
@@ -74,9 +74,9 @@
|
||||
"integrity": "sha512-bRRFxLfg5dtAyl5XyiVWz/ZBPahpOpPrNYnnHpOpUZvam4tKH35wdhP4Kj6PbM0+KdliOsPzbGWpkxcdpNB/sg=="
|
||||
},
|
||||
"node_modules/@vscode/tree-sitter-wasm": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@vscode/tree-sitter-wasm/-/tree-sitter-wasm-0.0.2.tgz",
|
||||
"integrity": "sha512-N57MR/kt4jR0H/TXeDsVYeJmvvUiK7avow0fjy+/EeKcyNBJcM2BFhj4XOAaaMbhGsOcIeSvJFouRWctXI7sKw=="
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@vscode/tree-sitter-wasm/-/tree-sitter-wasm-0.0.3.tgz",
|
||||
"integrity": "sha512-K5YmUdohFCavPqEzG2cUPcZ6555KE1qwMDCjkvSUSz+s+8Wro2xfg+syLq90y6Tq0ZSUVvpuX6yq6ukToeGaLg=="
|
||||
},
|
||||
"node_modules/@vscode/vscode-languagedetection": {
|
||||
"version": "1.0.21",
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"@microsoft/1ds-core-js": "^3.2.13",
|
||||
"@microsoft/1ds-post-js": "^3.2.13",
|
||||
"@vscode/iconv-lite-umd": "0.7.0",
|
||||
"@vscode/tree-sitter-wasm": "^0.0.2",
|
||||
"@vscode/tree-sitter-wasm": "^0.0.3",
|
||||
"@vscode/vscode-languagedetection": "1.0.21",
|
||||
"@xterm/addon-clipboard": "0.2.0-beta.39",
|
||||
"@xterm/addon-image": "0.9.0-beta.56",
|
||||
|
||||
@@ -125,6 +125,9 @@ elif [ -z "$(ldd --version 2>&1 | grep 'musl libc')" ]; then
|
||||
elif [ -f /usr/lib/libc.so.6 ]; then
|
||||
# Typical path
|
||||
libc_path='/usr/lib/libc.so.6'
|
||||
elif [ -f /lib64/libc.so.6 ]; then
|
||||
# Typical path (OpenSUSE)
|
||||
libc_path='/lib64/libc.so.6'
|
||||
elif [ -f /usr/lib64/libc.so.6 ]; then
|
||||
# Typical path
|
||||
libc_path='/usr/lib64/libc.so.6'
|
||||
|
||||
+2
-1
@@ -10,11 +10,12 @@
|
||||
"isolatedModules": false,
|
||||
"outDir": "../out/vs",
|
||||
"types": [
|
||||
"@webgpu/types",
|
||||
"mocha",
|
||||
"semver",
|
||||
"sinon",
|
||||
"winreg",
|
||||
"trusted-types",
|
||||
"winreg",
|
||||
"wicg-file-system-access"
|
||||
],
|
||||
"plugins": [
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
"compilerOptions": {
|
||||
"noEmit": true,
|
||||
"types": [
|
||||
"@webgpu/types",
|
||||
"trusted-types",
|
||||
"wicg-file-system-access"
|
||||
],
|
||||
|
||||
@@ -93,15 +93,18 @@ function getWorkerBootstrapUrl(label: string, workerScriptUrl: string, workerBas
|
||||
}
|
||||
}
|
||||
|
||||
// In below blob code, we are using JSON.stringify to ensure the passed
|
||||
// in values are not breaking our script. The values may contain string
|
||||
// terminating characters (such as ' or ").
|
||||
const blob = new Blob([coalesce([
|
||||
`/*${label}*/`,
|
||||
workerBaseUrl ? `globalThis.MonacoEnvironment = { baseUrl: '${workerBaseUrl}' };` : undefined,
|
||||
workerBaseUrl ? `globalThis.MonacoEnvironment = { baseUrl: ${JSON.stringify(workerBaseUrl)} };` : undefined,
|
||||
`globalThis._VSCODE_NLS_MESSAGES = ${JSON.stringify(getNLSMessages())};`,
|
||||
`globalThis._VSCODE_NLS_LANGUAGE = ${JSON.stringify(getNLSLanguage())};`,
|
||||
`globalThis._VSCODE_FILE_ROOT = '${globalThis._VSCODE_FILE_ROOT}';`,
|
||||
`globalThis._VSCODE_FILE_ROOT = ${JSON.stringify(globalThis._VSCODE_FILE_ROOT)};`,
|
||||
`const ttPolicy = globalThis.trustedTypes?.createPolicy('defaultWorkerFactory', { createScriptURL: value => value });`,
|
||||
`globalThis.workerttPolicy = ttPolicy;`,
|
||||
isESM ? `await import(ttPolicy?.createScriptURL('${workerScriptUrl}') ?? '${workerScriptUrl}');` : `importScripts(ttPolicy?.createScriptURL('${workerScriptUrl}') ?? '${workerScriptUrl}');`, //
|
||||
isESM ? `await import(ttPolicy?.createScriptURL(${JSON.stringify(workerScriptUrl)}) ?? ${JSON.stringify(workerScriptUrl)});` : `importScripts(ttPolicy?.createScriptURL(${JSON.stringify(workerScriptUrl)}) ?? ${JSON.stringify(workerScriptUrl)});`,
|
||||
isESM ? `globalThis.postMessage({ type: 'vscode-worker-ready' });` : undefined, // in ESM signal we are ready after the async import
|
||||
`/*${label}*/`
|
||||
]).join('')], { type: 'application/javascript' });
|
||||
|
||||
@@ -1951,10 +1951,10 @@ const defaultDomPurifyConfig = Object.freeze<dompurify.Config & { RETURN_TRUSTED
|
||||
/**
|
||||
* Sanitizes the given `value` and reset the given `node` with it.
|
||||
*/
|
||||
export function safeInnerHtml(node: HTMLElement, value: string): void {
|
||||
export function safeInnerHtml(node: HTMLElement, value: string, extraDomPurifyConfig?: dompurify.Config): void {
|
||||
const hook = hookDomPurifyHrefAndSrcSanitizer(defaultSafeProtocols);
|
||||
try {
|
||||
const html = dompurify.sanitize(value, defaultDomPurifyConfig);
|
||||
const html = dompurify.sanitize(value, { ...defaultDomPurifyConfig, ...extraDomPurifyConfig });
|
||||
node.innerHTML = html as unknown as string;
|
||||
} finally {
|
||||
hook.dispose();
|
||||
|
||||
@@ -545,9 +545,8 @@ export function renderMarkdownAsPlaintext(markdown: IMarkdownString, withCodeBlo
|
||||
value = `${value.substr(0, 100_000)}…`;
|
||||
}
|
||||
|
||||
const html = marked.parse(value, { async: false, renderer: withCodeBlocks ? plainTextWithCodeBlocksRenderer.value : plainTextRenderer.value }).replace(/&(#\d+|[a-zA-Z]+);/g, m => unescapeInfo.get(m) ?? m);
|
||||
|
||||
return sanitizeRenderedMarkdown({ isTrusted: false }, html).toString();
|
||||
const html = marked.parse(value, { async: false, renderer: withCodeBlocks ? plainTextWithCodeBlocksRenderer.value : plainTextRenderer.value });
|
||||
return sanitizeRenderedMarkdown({ isTrusted: false }, html).toString().replace(/&(#\d+|[a-zA-Z]+);/g, m => unescapeInfo.get(m) ?? m);
|
||||
}
|
||||
|
||||
const unescapeInfo = new Map<string, string>([
|
||||
|
||||
@@ -892,7 +892,7 @@ export class DefaultStyleController implements IStyleController {
|
||||
}
|
||||
|
||||
if (styles.listActiveSelectionIconForeground) {
|
||||
content.push(`.monaco-list${suffix}:focus .monaco-list-row.selected .codicon { color: ${styles.listActiveSelectionIconForeground}; }`);
|
||||
content.push(`@layer monaco-list { .monaco-list${suffix}:focus .monaco-list-row.selected .codicon { color: ${styles.listActiveSelectionIconForeground}; } }`);
|
||||
}
|
||||
|
||||
if (styles.listFocusAndSelectionBackground) {
|
||||
@@ -915,7 +915,7 @@ export class DefaultStyleController implements IStyleController {
|
||||
}
|
||||
|
||||
if (styles.listInactiveSelectionIconForeground) {
|
||||
content.push(`.monaco-list${suffix} .monaco-list-row.focused .codicon { color: ${styles.listInactiveSelectionIconForeground}; }`);
|
||||
content.push(`@layer monaco-list { .monaco-list${suffix} .monaco-list-row.focused .codicon { color: ${styles.listInactiveSelectionIconForeground}; } }`);
|
||||
}
|
||||
|
||||
if (styles.listInactiveFocusBackground) {
|
||||
|
||||
@@ -3144,6 +3144,10 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
|
||||
this.renderers.forEach(r => r.setModel(newModel));
|
||||
this.stickyScrollController?.setModel(newModel);
|
||||
|
||||
this.focus.set([]);
|
||||
this.selection.set([]);
|
||||
this.anchor.set([]);
|
||||
|
||||
this.view.splice(0, oldModel.getListRenderCount(oldModel.rootRef));
|
||||
this.model.refilter();
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ export function groupBy<K extends string | number | symbol, V>(data: V[], groupF
|
||||
return result;
|
||||
}
|
||||
|
||||
export function diffSets<T>(before: Set<T>, after: Set<T>): { removed: T[]; added: T[] } {
|
||||
export function diffSets<T>(before: ReadonlySet<T>, after: ReadonlySet<T>): { removed: T[]; added: T[] } {
|
||||
const removed: T[] = [];
|
||||
const added: T[] = [];
|
||||
for (const element of before) {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { CancellationToken } from './cancellation.js';
|
||||
import { diffSets } from './collections.js';
|
||||
import { onUnexpectedError } from './errors.js';
|
||||
import { createSingleCallFunction } from './functional.js';
|
||||
import { combinedDisposable, Disposable, DisposableMap, DisposableStore, IDisposable, toDisposable } from './lifecycle.js';
|
||||
@@ -12,7 +13,6 @@ import { IObservable, IObserver } from './observable.js';
|
||||
import { StopWatch } from './stopwatch.js';
|
||||
import { MicrotaskDelay } from './symbols.js';
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------
|
||||
// Uncomment the next line to print warnings whenever a listener is GC'ed without having been disposed. This is a LEAK.
|
||||
// -----------------------------------------------------------------------------------------------------------------------
|
||||
@@ -1791,3 +1791,30 @@ class ConstValueWithChangeEvent<T> implements IValueWithChangeEvent<T> {
|
||||
|
||||
constructor(readonly value: T) { }
|
||||
}
|
||||
|
||||
/**
|
||||
* @param handleItem Is called for each item in the set (but only the first time the item is seen in the set).
|
||||
* The returned disposable is disposed if the item is no longer in the set.
|
||||
*/
|
||||
export function trackSetChanges<T>(getData: () => ReadonlySet<T>, onDidChangeData: Event<unknown>, handleItem: (d: T) => IDisposable): IDisposable {
|
||||
const map = new DisposableMap<T, IDisposable>();
|
||||
let oldData = new Set(getData());
|
||||
for (const d of oldData) {
|
||||
map.set(d, handleItem(d));
|
||||
}
|
||||
|
||||
const store = new DisposableStore();
|
||||
store.add(onDidChangeData(() => {
|
||||
const newData = getData();
|
||||
const diff = diffSets(oldData, newData);
|
||||
for (const r of diff.removed) {
|
||||
map.deleteAndDispose(r);
|
||||
}
|
||||
for (const a of diff.added) {
|
||||
map.set(a, handleItem(a));
|
||||
}
|
||||
oldData = new Set(newData);
|
||||
}));
|
||||
store.add(map);
|
||||
return store;
|
||||
}
|
||||
|
||||
@@ -6,8 +6,12 @@
|
||||
import { IDisposable } from './lifecycle.js';
|
||||
import { env } from './process.js';
|
||||
|
||||
function hotReloadDisabled() {
|
||||
return true; // TODO@hediet fix hot reload.
|
||||
}
|
||||
|
||||
export function isHotReloadEnabled(): boolean {
|
||||
return env && !!env['VSCODE_DEV'];
|
||||
return !hotReloadDisabled() && env && !!env['VSCODE_DEV'];
|
||||
}
|
||||
export function registerHotReloadHandler(handler: HotReloadHandler): IDisposable {
|
||||
if (!isHotReloadEnabled()) {
|
||||
|
||||
@@ -875,3 +875,60 @@ export function mapsStrictEqualIgnoreOrder(a: Map<unknown, unknown>, b: Map<unkn
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* A map that is addressable with 2 separate keys. This is useful in high performance scenarios
|
||||
* where creating a composite key is too expensive.
|
||||
*/
|
||||
export class TwoKeyMap<TFirst extends string | number, TSecond extends string | number, TValue> {
|
||||
private _data: { [key: string | number]: { [key: string | number]: TValue | undefined } | undefined } = {};
|
||||
|
||||
public set(first: TFirst, second: TSecond, value: TValue): void {
|
||||
if (!this._data[first]) {
|
||||
this._data[first] = {};
|
||||
}
|
||||
this._data[first as string | number]![second] = value;
|
||||
}
|
||||
|
||||
public get(first: TFirst, second: TSecond): TValue | undefined {
|
||||
return this._data[first as string | number]?.[second];
|
||||
}
|
||||
|
||||
public clear(): void {
|
||||
this._data = {};
|
||||
}
|
||||
|
||||
public *values(): IterableIterator<TValue> {
|
||||
for (const first in this._data) {
|
||||
for (const second in this._data[first]) {
|
||||
const value = this._data[first]![second];
|
||||
if (value) {
|
||||
yield value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A map that is addressable with 4 separate keys. This is useful in high performance scenarios
|
||||
* where creating a composite key is too expensive.
|
||||
*/
|
||||
export class FourKeyMap<TFirst extends string | number, TSecond extends string | number, TThird extends string | number, TFourth extends string | number, TValue> {
|
||||
private _data: TwoKeyMap<TFirst, TSecond, TwoKeyMap<TThird, TFourth, TValue>> = new TwoKeyMap();
|
||||
|
||||
public set(first: TFirst, second: TSecond, third: TThird, fourth: TFourth, value: TValue): void {
|
||||
if (!this._data.get(first, second)) {
|
||||
this._data.set(first, second, new TwoKeyMap());
|
||||
}
|
||||
this._data.get(first, second)!.set(third, fourth, value);
|
||||
}
|
||||
|
||||
public get(first: TFirst, second: TSecond, third: TThird, fourth: TFourth): TValue | undefined {
|
||||
return this._data.get(first, second)?.get(third, fourth);
|
||||
}
|
||||
|
||||
public clear(): void {
|
||||
this._data.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,72 +5,4 @@
|
||||
|
||||
// This is a facade for the observable implementation. Only import from here!
|
||||
|
||||
export type {
|
||||
IObservable,
|
||||
IObserver,
|
||||
IReader,
|
||||
ISettable,
|
||||
ISettableObservable,
|
||||
ITransaction,
|
||||
IChangeContext,
|
||||
IChangeTracker,
|
||||
} from './observableInternal/base.js';
|
||||
|
||||
export {
|
||||
observableValue,
|
||||
disposableObservableValue,
|
||||
transaction,
|
||||
subtransaction,
|
||||
} from './observableInternal/base.js';
|
||||
export {
|
||||
derived,
|
||||
derivedOpts,
|
||||
derivedHandleChanges,
|
||||
derivedWithStore,
|
||||
} from './observableInternal/derived.js';
|
||||
export {
|
||||
autorun,
|
||||
autorunDelta,
|
||||
autorunHandleChanges,
|
||||
autorunWithStore,
|
||||
autorunOpts,
|
||||
autorunWithStoreHandleChanges,
|
||||
} from './observableInternal/autorun.js';
|
||||
export type {
|
||||
IObservableSignal,
|
||||
} from './observableInternal/utils.js';
|
||||
export {
|
||||
constObservable,
|
||||
debouncedObservable,
|
||||
derivedObservableWithCache,
|
||||
derivedObservableWithWritableCache,
|
||||
keepObserved,
|
||||
recomputeInitiallyAndOnChange,
|
||||
observableFromEvent,
|
||||
observableFromPromise,
|
||||
observableSignal,
|
||||
observableSignalFromEvent,
|
||||
wasEventTriggeredRecently,
|
||||
} from './observableInternal/utils.js';
|
||||
export {
|
||||
ObservableLazy,
|
||||
ObservableLazyPromise,
|
||||
ObservablePromise,
|
||||
PromiseResult,
|
||||
waitForState,
|
||||
derivedWithCancellationToken,
|
||||
} from './observableInternal/promise.js';
|
||||
export {
|
||||
observableValueOpts
|
||||
} from './observableInternal/api.js';
|
||||
|
||||
import { ConsoleObservableLogger, setLogger } from './observableInternal/logging.js';
|
||||
|
||||
// Remove "//" in the next line to enable logging
|
||||
const enableLogging = false
|
||||
// || Boolean("true") // done "weirdly" so that a lint warning prevents you from pushing this
|
||||
;
|
||||
|
||||
if (enableLogging) {
|
||||
setLogger(new ConsoleObservableLogger());
|
||||
}
|
||||
export * from './observableInternal/index.js';
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { EqualityComparer, strictEquals } from '../equals.js';
|
||||
import { ISettableObservable } from '../observable.js';
|
||||
import { ObservableValue } from './base.js';
|
||||
import { IDebugNameData, DebugNameData } from './debugName.js';
|
||||
import { ISettableObservable, ObservableValue } from './base.js';
|
||||
import { DebugNameData, IDebugNameData } from './debugName.js';
|
||||
import { EqualityComparer, strictEquals } from './commonFacade/deps.js';
|
||||
import { LazyObservableValue } from './lazyObservableValue.js';
|
||||
|
||||
export function observableValueOpts<T, TChange = void>(
|
||||
|
||||
@@ -3,11 +3,9 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { assertFn } from '../assert.js';
|
||||
import { onBugIndicatingError } from '../errors.js';
|
||||
import { DisposableStore, IDisposable, markAsDisposed, toDisposable, trackDisposable } from '../lifecycle.js';
|
||||
import { IChangeContext, IObservable, IObserver, IReader } from './base.js';
|
||||
import { DebugNameData, IDebugNameData } from './debugName.js';
|
||||
import { assertFn, DisposableStore, IDisposable, markAsDisposed, onBugIndicatingError, toDisposable, trackDisposable } from './commonFacade/deps.js';
|
||||
import { getLogger } from './logging.js';
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,12 +3,11 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { strictEquals, EqualityComparer } from '../equals.js';
|
||||
import { DisposableStore, IDisposable } from '../lifecycle.js';
|
||||
import { keepObserved, recomputeInitiallyAndOnChange } from '../observable.js';
|
||||
import { DebugNameData, DebugOwner, getFunctionName } from './debugName.js';
|
||||
import { DisposableStore, EqualityComparer, IDisposable, strictEquals } from './commonFacade/deps.js';
|
||||
import type { derivedOpts } from './derived.js';
|
||||
import { getLogger } from './logging.js';
|
||||
import { keepObserved, recomputeInitiallyAndOnChange } from './utils.js';
|
||||
|
||||
/**
|
||||
* Represents an observable value.
|
||||
|
||||
+2
-7
@@ -3,10 +3,5 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.chat-inline-file-link-widget .monaco-icon-label {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.chat-inline-file-link-widget .monaco-icon-label .monaco-highlighted-label {
|
||||
white-space: normal;
|
||||
}
|
||||
export { CancellationError } from '../../errors.js';
|
||||
export { CancellationToken, CancellationTokenSource } from '../../cancellation.js';
|
||||
@@ -0,0 +1,10 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
export { assertFn } from '../../assert.js';
|
||||
export { type EqualityComparer, strictEquals } from '../../equals.js';
|
||||
export { BugIndicatingError, onBugIndicatingError } from '../../errors.js';
|
||||
export { Event, type IValueWithChangeEvent } from '../../event.js';
|
||||
export { DisposableStore, type IDisposable, markAsDisposed, toDisposable, trackDisposable } from '../../lifecycle.js';
|
||||
@@ -3,12 +3,9 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { assertFn } from '../assert.js';
|
||||
import { EqualityComparer, strictEquals } from '../equals.js';
|
||||
import { onBugIndicatingError } from '../errors.js';
|
||||
import { DisposableStore, IDisposable } from '../lifecycle.js';
|
||||
import { BaseObservable, IChangeContext, IObservable, IObserver, IReader, ISettableObservable, ITransaction, _setDerivedOpts, } from './base.js';
|
||||
import { DebugNameData, IDebugNameData, DebugOwner } from './debugName.js';
|
||||
import { DebugNameData, DebugOwner, IDebugNameData } from './debugName.js';
|
||||
import { DisposableStore, EqualityComparer, IDisposable, assertFn, onBugIndicatingError, strictEquals } from './commonFacade/deps.js';
|
||||
import { getLogger } from './logging.js';
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
// This is a facade for the observable implementation. Only import from here!
|
||||
|
||||
export { observableValueOpts } from './api.js';
|
||||
export { autorun, autorunDelta, autorunHandleChanges, autorunOpts, autorunWithStore, autorunWithStoreHandleChanges } from './autorun.js';
|
||||
export { asyncTransaction, disposableObservableValue, globalTransaction, observableValue, subtransaction, transaction, TransactionImpl, type IChangeContext, type IChangeTracker, type IObservable, type IObserver, type IReader, type ISettable, type ISettableObservable, type ITransaction, } from './base.js';
|
||||
export { derived, derivedDisposable, derivedHandleChanges, derivedOpts, derivedWithSetter, derivedWithStore } from './derived.js';
|
||||
export { ObservableLazy, ObservableLazyPromise, ObservablePromise, PromiseResult, } from './promise.js';
|
||||
export { derivedWithCancellationToken, waitForState } from './utilsCancellation.js';
|
||||
export { constObservable, debouncedObservable, derivedConstOnceDefined, derivedObservableWithCache, derivedObservableWithWritableCache, keepObserved, latestChangedValue, mapObservableArrayCached, observableFromEvent, observableFromEventOpts, observableFromPromise, observableFromValueWithChangeEvent, observableSignal, observableSignalFromEvent, recomputeInitiallyAndOnChange, runOnChange, runOnChangeWithStore, signalFromObservable, ValueWithChangeEventFromObservable, wasEventTriggeredRecently, type IObservableSignal, } from './utils.js';
|
||||
export { type DebugOwner } from './debugName.js';
|
||||
|
||||
import {
|
||||
ConsoleObservableLogger,
|
||||
setLogger
|
||||
} from './logging.js';
|
||||
|
||||
// Remove "//" in the next line to enable logging
|
||||
const enableLogging = false
|
||||
// || Boolean("true") // done "weirdly" so that a lint warning prevents you from pushing this
|
||||
;
|
||||
|
||||
if (enableLogging) {
|
||||
setLogger(new ConsoleObservableLogger());
|
||||
}
|
||||
@@ -3,9 +3,8 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { EqualityComparer } from '../equals.js';
|
||||
import { ISettableObservable, ITransaction } from '../observable.js';
|
||||
import { BaseObservable, IObserver, TransactionImpl } from './base.js';
|
||||
import { EqualityComparer } from './commonFacade/deps.js';
|
||||
import { BaseObservable, IObserver, ISettableObservable, ITransaction, TransactionImpl } from './base.js';
|
||||
import { DebugNameData } from './debugName.js';
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,13 +2,8 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { autorun } from './autorun.js';
|
||||
import { IObservable, IReader, observableValue, transaction } from './base.js';
|
||||
import { Derived, derived } from './derived.js';
|
||||
import { CancellationToken, CancellationTokenSource } from '../cancellation.js';
|
||||
import { DebugNameData, DebugOwner } from './debugName.js';
|
||||
import { strictEquals } from '../equals.js';
|
||||
import { CancellationError } from '../errors.js';
|
||||
import { IObservable, observableValue, transaction } from './base.js';
|
||||
import { derived } from './derived.js';
|
||||
|
||||
export class ObservableLazy<T> {
|
||||
private readonly _value = observableValue<T | undefined>(this, undefined);
|
||||
@@ -120,90 +115,3 @@ export class ObservableLazyPromise<T> {
|
||||
return this._lazyValue.getValue().promise;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the promise when the observables state matches the predicate.
|
||||
*/
|
||||
export function waitForState<T>(observable: IObservable<T | null | undefined>): Promise<T>;
|
||||
export function waitForState<T, TState extends T>(observable: IObservable<T>, predicate: (state: T) => state is TState, isError?: (state: T) => boolean | unknown | undefined, cancellationToken?: CancellationToken): Promise<TState>;
|
||||
export function waitForState<T>(observable: IObservable<T>, predicate: (state: T) => boolean, isError?: (state: T) => boolean | unknown | undefined, cancellationToken?: CancellationToken): Promise<T>;
|
||||
export function waitForState<T>(observable: IObservable<T>, predicate?: (state: T) => boolean, isError?: (state: T) => boolean | unknown | undefined, cancellationToken?: CancellationToken): Promise<T> {
|
||||
if (!predicate) {
|
||||
predicate = state => state !== null && state !== undefined;
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
let isImmediateRun = true;
|
||||
let shouldDispose = false;
|
||||
const stateObs = observable.map(state => {
|
||||
/** @description waitForState.state */
|
||||
return {
|
||||
isFinished: predicate(state),
|
||||
error: isError ? isError(state) : false,
|
||||
state
|
||||
};
|
||||
});
|
||||
const d = autorun(reader => {
|
||||
/** @description waitForState */
|
||||
const { isFinished, error, state } = stateObs.read(reader);
|
||||
if (isFinished || error) {
|
||||
if (isImmediateRun) {
|
||||
// The variable `d` is not initialized yet
|
||||
shouldDispose = true;
|
||||
} else {
|
||||
d.dispose();
|
||||
}
|
||||
if (error) {
|
||||
reject(error === true ? state : error);
|
||||
} else {
|
||||
resolve(state);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (cancellationToken) {
|
||||
const dc = cancellationToken.onCancellationRequested(() => {
|
||||
d.dispose();
|
||||
dc.dispose();
|
||||
reject(new CancellationError());
|
||||
});
|
||||
if (cancellationToken.isCancellationRequested) {
|
||||
d.dispose();
|
||||
dc.dispose();
|
||||
reject(new CancellationError());
|
||||
return;
|
||||
}
|
||||
}
|
||||
isImmediateRun = false;
|
||||
if (shouldDispose) {
|
||||
d.dispose();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function derivedWithCancellationToken<T>(computeFn: (reader: IReader, cancellationToken: CancellationToken) => T): IObservable<T>;
|
||||
export function derivedWithCancellationToken<T>(owner: object, computeFn: (reader: IReader, cancellationToken: CancellationToken) => T): IObservable<T>;
|
||||
export function derivedWithCancellationToken<T>(computeFnOrOwner: ((reader: IReader, cancellationToken: CancellationToken) => T) | object, computeFnOrUndefined?: ((reader: IReader, cancellationToken: CancellationToken) => T)): IObservable<T> {
|
||||
let computeFn: (reader: IReader, store: CancellationToken) => T;
|
||||
let owner: DebugOwner;
|
||||
if (computeFnOrUndefined === undefined) {
|
||||
computeFn = computeFnOrOwner as any;
|
||||
owner = undefined;
|
||||
} else {
|
||||
owner = computeFnOrOwner;
|
||||
computeFn = computeFnOrUndefined as any;
|
||||
}
|
||||
|
||||
let cancellationTokenSource: CancellationTokenSource | undefined = undefined;
|
||||
return new Derived(
|
||||
new DebugNameData(owner, undefined, computeFn),
|
||||
r => {
|
||||
if (cancellationTokenSource) {
|
||||
cancellationTokenSource.dispose(true);
|
||||
}
|
||||
cancellationTokenSource = new CancellationTokenSource();
|
||||
return computeFn(r, cancellationTokenSource.token);
|
||||
}, undefined,
|
||||
undefined,
|
||||
() => cancellationTokenSource?.dispose(),
|
||||
strictEquals,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,15 +3,12 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Event, IValueWithChangeEvent } from '../event.js';
|
||||
import { DisposableStore, IDisposable, toDisposable } from '../lifecycle.js';
|
||||
import { autorun, autorunOpts, autorunWithStoreHandleChanges } from './autorun.js';
|
||||
import { BaseObservable, ConvenientObservable, IObservable, IObserver, IReader, ITransaction, _setKeepObserved, _setRecomputeInitiallyAndOnChange, observableValue, subtransaction, transaction } from './base.js';
|
||||
import { DebugNameData, IDebugNameData, DebugOwner, getDebugName, } from './debugName.js';
|
||||
import { DebugNameData, DebugOwner, IDebugNameData, getDebugName, } from './debugName.js';
|
||||
import { BugIndicatingError, DisposableStore, EqualityComparer, Event, IDisposable, IValueWithChangeEvent, strictEquals, toDisposable } from './commonFacade/deps.js';
|
||||
import { derived, derivedOpts } from './derived.js';
|
||||
import { getLogger } from './logging.js';
|
||||
import { BugIndicatingError } from '../errors.js';
|
||||
import { EqualityComparer, strictEquals } from '../equals.js';
|
||||
|
||||
/**
|
||||
* Represents an efficient observable whose value never changes.
|
||||
@@ -301,6 +298,15 @@ class ObservableSignal<TChange> extends BaseObservable<void, TChange> implements
|
||||
}
|
||||
}
|
||||
|
||||
export function signalFromObservable<T>(owner: DebugOwner | undefined, observable: IObservable<T>): IObservable<void> {
|
||||
return derivedOpts({
|
||||
owner,
|
||||
equalsFn: () => false,
|
||||
}, reader => {
|
||||
observable.read(reader);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use `debouncedObservable2` instead.
|
||||
*/
|
||||
@@ -619,7 +625,8 @@ export function derivedConstOnceDefined<T>(owner: DebugOwner, fn: (reader: IRead
|
||||
|
||||
type RemoveUndefined<T> = T extends undefined ? never : T;
|
||||
|
||||
export function runOnChange<T, TChange>(observable: IObservable<T, TChange>, cb: (value: T, deltas: RemoveUndefined<TChange>[]) => void): IDisposable {
|
||||
export function runOnChange<T, TChange>(observable: IObservable<T, TChange>, cb: (value: T, previousValue: undefined | T, deltas: RemoveUndefined<TChange>[]) => void): IDisposable {
|
||||
let _previousValue: T | undefined;
|
||||
return autorunWithStoreHandleChanges({
|
||||
createEmptyChangeSummary: () => ({ deltas: [] as RemoveUndefined<TChange>[], didChange: false }),
|
||||
handleChange: (context, changeSummary) => {
|
||||
@@ -634,17 +641,19 @@ export function runOnChange<T, TChange>(observable: IObservable<T, TChange>, cb:
|
||||
},
|
||||
}, (reader, changeSummary) => {
|
||||
const value = observable.read(reader);
|
||||
const previousValue = _previousValue;
|
||||
if (changeSummary.didChange) {
|
||||
cb(value, changeSummary.deltas);
|
||||
_previousValue = value;
|
||||
cb(value, previousValue, changeSummary.deltas);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function runOnChangeWithStore<T, TChange>(observable: IObservable<T, TChange>, cb: (value: T, deltas: RemoveUndefined<TChange>[], store: DisposableStore) => void): IDisposable {
|
||||
export function runOnChangeWithStore<T, TChange>(observable: IObservable<T, TChange>, cb: (value: T, previousValue: undefined | T, deltas: RemoveUndefined<TChange>[], store: DisposableStore) => void): IDisposable {
|
||||
const store = new DisposableStore();
|
||||
const disposable = runOnChange(observable, (value, deltas) => {
|
||||
const disposable = runOnChange(observable, (value, previousValue: undefined | T, deltas) => {
|
||||
store.clear();
|
||||
cb(value, deltas, store);
|
||||
cb(value, previousValue, deltas, store);
|
||||
});
|
||||
return {
|
||||
dispose() {
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IReader, IObservable } from './base.js';
|
||||
import { DebugOwner, DebugNameData } from './debugName.js';
|
||||
import { CancellationError, CancellationToken, CancellationTokenSource } from './commonFacade/cancellation.js';
|
||||
import { Derived } from './derived.js';
|
||||
import { strictEquals } from './commonFacade/deps.js';
|
||||
import { autorun } from './autorun.js';
|
||||
|
||||
/**
|
||||
* Resolves the promise when the observables state matches the predicate.
|
||||
*/
|
||||
export function waitForState<T>(observable: IObservable<T | null | undefined>): Promise<T>;
|
||||
export function waitForState<T, TState extends T>(observable: IObservable<T>, predicate: (state: T) => state is TState, isError?: (state: T) => boolean | unknown | undefined, cancellationToken?: CancellationToken): Promise<TState>;
|
||||
export function waitForState<T>(observable: IObservable<T>, predicate: (state: T) => boolean, isError?: (state: T) => boolean | unknown | undefined, cancellationToken?: CancellationToken): Promise<T>;
|
||||
export function waitForState<T>(observable: IObservable<T>, predicate?: (state: T) => boolean, isError?: (state: T) => boolean | unknown | undefined, cancellationToken?: CancellationToken): Promise<T> {
|
||||
if (!predicate) {
|
||||
predicate = state => state !== null && state !== undefined;
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
let isImmediateRun = true;
|
||||
let shouldDispose = false;
|
||||
const stateObs = observable.map(state => {
|
||||
/** @description waitForState.state */
|
||||
return {
|
||||
isFinished: predicate(state),
|
||||
error: isError ? isError(state) : false,
|
||||
state
|
||||
};
|
||||
});
|
||||
const d = autorun(reader => {
|
||||
/** @description waitForState */
|
||||
const { isFinished, error, state } = stateObs.read(reader);
|
||||
if (isFinished || error) {
|
||||
if (isImmediateRun) {
|
||||
// The variable `d` is not initialized yet
|
||||
shouldDispose = true;
|
||||
} else {
|
||||
d.dispose();
|
||||
}
|
||||
if (error) {
|
||||
reject(error === true ? state : error);
|
||||
} else {
|
||||
resolve(state);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (cancellationToken) {
|
||||
const dc = cancellationToken.onCancellationRequested(() => {
|
||||
d.dispose();
|
||||
dc.dispose();
|
||||
reject(new CancellationError());
|
||||
});
|
||||
if (cancellationToken.isCancellationRequested) {
|
||||
d.dispose();
|
||||
dc.dispose();
|
||||
reject(new CancellationError());
|
||||
return;
|
||||
}
|
||||
}
|
||||
isImmediateRun = false;
|
||||
if (shouldDispose) {
|
||||
d.dispose();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function derivedWithCancellationToken<T>(computeFn: (reader: IReader, cancellationToken: CancellationToken) => T): IObservable<T>;
|
||||
export function derivedWithCancellationToken<T>(owner: object, computeFn: (reader: IReader, cancellationToken: CancellationToken) => T): IObservable<T>;
|
||||
export function derivedWithCancellationToken<T>(computeFnOrOwner: ((reader: IReader, cancellationToken: CancellationToken) => T) | object, computeFnOrUndefined?: ((reader: IReader, cancellationToken: CancellationToken) => T)): IObservable<T> {
|
||||
let computeFn: (reader: IReader, store: CancellationToken) => T;
|
||||
let owner: DebugOwner;
|
||||
if (computeFnOrUndefined === undefined) {
|
||||
computeFn = computeFnOrOwner as any;
|
||||
owner = undefined;
|
||||
} else {
|
||||
owner = computeFnOrOwner;
|
||||
computeFn = computeFnOrUndefined as any;
|
||||
}
|
||||
|
||||
let cancellationTokenSource: CancellationTokenSource | undefined = undefined;
|
||||
return new Derived(
|
||||
new DebugNameData(owner, undefined, computeFn),
|
||||
r => {
|
||||
if (cancellationTokenSource) {
|
||||
cancellationTokenSource.dispose(true);
|
||||
}
|
||||
cancellationTokenSource = new CancellationTokenSource();
|
||||
return computeFn(r, cancellationTokenSource.token);
|
||||
}, undefined,
|
||||
undefined,
|
||||
() => cancellationTokenSource?.dispose(),
|
||||
strictEquals
|
||||
);
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import assert from 'assert';
|
||||
import { BidirectionalMap, LinkedMap, LRUCache, mapsStrictEqualIgnoreOrder, MRUCache, ResourceMap, SetMap, Touch } from '../../common/map.js';
|
||||
import { BidirectionalMap, FourKeyMap, LinkedMap, LRUCache, mapsStrictEqualIgnoreOrder, MRUCache, ResourceMap, SetMap, Touch, TwoKeyMap } from '../../common/map.js';
|
||||
import { extUriIgnorePathCase } from '../../common/resources.js';
|
||||
import { URI } from '../../common/uri.js';
|
||||
import { ensureNoDisposablesAreLeakedInTestSuite } from './utils.js';
|
||||
@@ -681,5 +681,65 @@ suite('SetMap', () => {
|
||||
const setMap = new SetMap<string, number>();
|
||||
assert.deepStrictEqual([...setMap.get('a')], []);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
suite('TwoKeyMap', () => {
|
||||
ensureNoDisposablesAreLeakedInTestSuite();
|
||||
|
||||
test('set and get', () => {
|
||||
const map = new TwoKeyMap<string, string, number>();
|
||||
map.set('a', 'b', 1);
|
||||
map.set('a', 'c', 2);
|
||||
map.set('b', 'c', 3);
|
||||
assert.strictEqual(map.get('a', 'b'), 1);
|
||||
assert.strictEqual(map.get('a', 'c'), 2);
|
||||
assert.strictEqual(map.get('b', 'c'), 3);
|
||||
assert.strictEqual(map.get('a', 'd'), undefined);
|
||||
});
|
||||
|
||||
test('clear', () => {
|
||||
const map = new TwoKeyMap<string, string, number>();
|
||||
map.set('a', 'b', 1);
|
||||
map.set('a', 'c', 2);
|
||||
map.set('b', 'c', 3);
|
||||
map.clear();
|
||||
assert.strictEqual(map.get('a', 'b'), undefined);
|
||||
assert.strictEqual(map.get('a', 'c'), undefined);
|
||||
assert.strictEqual(map.get('b', 'c'), undefined);
|
||||
});
|
||||
|
||||
test('values', () => {
|
||||
const map = new TwoKeyMap<string, string, number>();
|
||||
map.set('a', 'b', 1);
|
||||
map.set('a', 'c', 2);
|
||||
map.set('b', 'c', 3);
|
||||
assert.deepStrictEqual(Array.from(map.values()), [1, 2, 3]);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
suite('FourKeyMap', () => {
|
||||
ensureNoDisposablesAreLeakedInTestSuite();
|
||||
|
||||
test('set and get', () => {
|
||||
const map = new FourKeyMap<string, string, string, string, number>();
|
||||
map.set('a', 'b', 'c', 'd', 1);
|
||||
map.set('a', 'c', 'c', 'd', 2);
|
||||
map.set('b', 'e', 'f', 'g', 3);
|
||||
assert.strictEqual(map.get('a', 'b', 'c', 'd'), 1);
|
||||
assert.strictEqual(map.get('a', 'c', 'c', 'd'), 2);
|
||||
assert.strictEqual(map.get('b', 'e', 'f', 'g'), 3);
|
||||
assert.strictEqual(map.get('a', 'b', 'c', 'a'), undefined);
|
||||
});
|
||||
|
||||
test('clear', () => {
|
||||
const map = new FourKeyMap<string, string, string, string, number>();
|
||||
map.set('a', 'b', 'c', 'd', 1);
|
||||
map.set('a', 'c', 'c', 'd', 2);
|
||||
map.set('b', 'e', 'f', 'g', 3);
|
||||
map.clear();
|
||||
assert.strictEqual(map.get('a', 'b', 'c', 'd'), undefined);
|
||||
assert.strictEqual(map.get('a', 'c', 'c', 'd'), undefined);
|
||||
assert.strictEqual(map.get('b', 'e', 'f', 'g'), undefined);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,13 +4,12 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import assert from 'assert';
|
||||
import { setUnexpectedErrorHandler } from '../../common/errors.js';
|
||||
import { Emitter, Event } from '../../common/event.js';
|
||||
import { DisposableStore } from '../../common/lifecycle.js';
|
||||
import { ISettableObservable, autorun, derived, ITransaction, observableFromEvent, observableValue, transaction, keepObserved, waitForState, autorunHandleChanges, observableSignal } from '../../common/observable.js';
|
||||
import { BaseObservable, IObservable, IObserver } from '../../common/observableInternal/base.js';
|
||||
import { derivedDisposable } from '../../common/observableInternal/derived.js';
|
||||
import { autorun, autorunHandleChanges, derived, derivedDisposable, IObservable, IObserver, ISettableObservable, ITransaction, keepObserved, observableFromEvent, observableSignal, observableValue, transaction, waitForState } from '../../common/observable.js';
|
||||
import { BaseObservable } from '../../common/observableInternal/base.js';
|
||||
import { ensureNoDisposablesAreLeakedInTestSuite } from './utils.js';
|
||||
import { setUnexpectedErrorHandler } from '../../common/errors.js';
|
||||
|
||||
suite('observables', () => {
|
||||
const ds = ensureNoDisposablesAreLeakedInTestSuite();
|
||||
|
||||
@@ -211,11 +211,7 @@ class CodeMain {
|
||||
services.set(ILifecycleMainService, new SyncDescriptor(LifecycleMainService, undefined, false));
|
||||
|
||||
// Request
|
||||
const networkLogger = loggerService.createLogger('network-main', {
|
||||
name: localize('network-main', "Network (Main)"),
|
||||
hidden: true
|
||||
});
|
||||
services.set(IRequestService, new SyncDescriptor(RequestService, [networkLogger], true));
|
||||
services.set(IRequestService, new SyncDescriptor(RequestService, undefined, true));
|
||||
|
||||
// Themes
|
||||
services.set(IThemeMainService, new SyncDescriptor(ThemeMainService));
|
||||
|
||||
@@ -270,11 +270,7 @@ class SharedProcessMain extends Disposable implements IClientConnectionFilter {
|
||||
]);
|
||||
|
||||
// Request
|
||||
const networkLogger = loggerService.createLogger('network-shared', {
|
||||
name: localize('network-shared', "Network (Shared)"),
|
||||
hidden: true,
|
||||
});
|
||||
const requestService = new RequestService(networkLogger, configurationService, environmentService, logService);
|
||||
const requestService = new RequestService(configurationService, environmentService, logService);
|
||||
services.set(IRequestService, requestService);
|
||||
|
||||
// Checksum
|
||||
|
||||
@@ -117,7 +117,7 @@ export async function main(argv: string[]): Promise<any> {
|
||||
|
||||
// Extensions Management
|
||||
else if (shouldSpawnCliProcess(args)) {
|
||||
const cli = await import(['vs', 'code', 'node', 'cliProcessMain'].join('/') /* TODO@esm workaround to prevent esbuild from inlining this */);
|
||||
const cli = await import(['./cliProcessMain.js'].join('/') /* TODO@esm workaround to prevent esbuild from inlining this */);
|
||||
await cli.main(args);
|
||||
|
||||
return;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user