mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-30 22:31:56 +00:00
Compare commits
37 Commits
pr-2210
...
cja/simple
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1faf8983f4 | ||
|
|
8cf4a94355 | ||
|
|
d7fd733564 | ||
|
|
b5725df9ed | ||
|
|
2617a7ffe5 | ||
|
|
2194bb4961 | ||
|
|
3e86a6be9d | ||
|
|
44f834b198 | ||
|
|
59190f2376 | ||
|
|
d385764027 | ||
|
|
5db83f9a85 | ||
|
|
f4276adca9 | ||
|
|
36ded95be0 | ||
|
|
41d132b041 | ||
|
|
f6c8db9f37 | ||
|
|
46e6695cba | ||
|
|
392d0edcd1 | ||
|
|
b2ea464b6c | ||
|
|
c84beeb8c3 | ||
|
|
3bf0f09d37 | ||
|
|
eb85b2959d | ||
|
|
ec472a3d4c | ||
|
|
e3055b121f | ||
|
|
e489a66ae2 | ||
|
|
601a335839 | ||
|
|
0029b04af1 | ||
|
|
f4aa74ad6f | ||
|
|
2afb2d82e4 | ||
|
|
679e4e56df | ||
|
|
df2c1b2345 | ||
|
|
7007368a1a | ||
|
|
079965d199 | ||
|
|
fc774e1089 | ||
|
|
d9d90ac6d9 | ||
|
|
c101f7de74 | ||
|
|
ca396cdfbe | ||
|
|
ff1e733679 |
@@ -143,4 +143,6 @@ src/Explorer/Tree/ResourceTreeAdapter.tsx
|
|||||||
__mocks__/monaco-editor.ts
|
__mocks__/monaco-editor.ts
|
||||||
src/Explorer/Tree/ResourceTree.tsx
|
src/Explorer/Tree/ResourceTree.tsx
|
||||||
src/Utils/EndpointUtils.ts
|
src/Utils/EndpointUtils.ts
|
||||||
src/Utils/PriorityBasedExecutionUtils.ts
|
src/Utils/PriorityBasedExecutionUtils.ts
|
||||||
|
|
||||||
|
utils/local-proxy/**
|
||||||
3
configs/emulator-http.json
Normal file
3
configs/emulator-http.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"EMULATOR_ENDPOINT": "http://localhost:8081"
|
||||||
|
}
|
||||||
80
package-lock.json
generated
80
package-lock.json
generated
@@ -205,6 +205,58 @@
|
|||||||
"webpack-dev-server": "4.15.2"
|
"webpack-dev-server": "4.15.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"canvas": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"extraneous": true,
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
|
"local_dependencies/@azure/cosmos": {
|
||||||
|
"version": "4.0.1-beta.3",
|
||||||
|
"extraneous": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@azure/abort-controller": "^1.0.0",
|
||||||
|
"@azure/core-auth": "^1.3.0",
|
||||||
|
"@azure/core-rest-pipeline": "^1.2.0",
|
||||||
|
"@azure/core-tracing": "^1.0.0",
|
||||||
|
"debug": "^4.1.1",
|
||||||
|
"fast-json-stable-stringify": "^2.1.0",
|
||||||
|
"jsbi": "^3.1.3",
|
||||||
|
"node-abort-controller": "^3.0.0",
|
||||||
|
"priorityqueuejs": "^2.0.0",
|
||||||
|
"semaphore": "^1.0.5",
|
||||||
|
"tslib": "^2.2.0",
|
||||||
|
"universal-user-agent": "^6.0.0",
|
||||||
|
"uuid": "^8.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"local_dependencies/cosmos": {
|
||||||
|
"name": "@azure/cosmos",
|
||||||
|
"version": "4.0.1-beta.3",
|
||||||
|
"extraneous": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@azure/abort-controller": "^1.0.0",
|
||||||
|
"@azure/core-auth": "^1.3.0",
|
||||||
|
"@azure/core-rest-pipeline": "^1.2.0",
|
||||||
|
"@azure/core-tracing": "^1.0.0",
|
||||||
|
"debug": "^4.1.1",
|
||||||
|
"fast-json-stable-stringify": "^2.1.0",
|
||||||
|
"jsbi": "^3.1.3",
|
||||||
|
"node-abort-controller": "^3.0.0",
|
||||||
|
"priorityqueuejs": "^2.0.0",
|
||||||
|
"semaphore": "^1.0.5",
|
||||||
|
"tslib": "^2.2.0",
|
||||||
|
"universal-user-agent": "^6.0.0",
|
||||||
|
"uuid": "^8.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@aashutoshrathi/word-wrap": {
|
"node_modules/@aashutoshrathi/word-wrap": {
|
||||||
"version": "1.2.6",
|
"version": "1.2.6",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -7893,7 +7945,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@nteract/data-explorer/node_modules/cross-spawn": {
|
"node_modules/@nteract/data-explorer/node_modules/cross-spawn": {
|
||||||
"version": "6.0.5",
|
"version": "7.0.5",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"nice-try": "^1.0.4",
|
"nice-try": "^1.0.4",
|
||||||
@@ -8017,7 +8069,7 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cross-spawn": "^6.0.0",
|
"cross-spawn": "^7.0.5",
|
||||||
"get-stream": "^4.0.0",
|
"get-stream": "^4.0.0",
|
||||||
"is-stream": "^1.1.0",
|
"is-stream": "^1.1.0",
|
||||||
"npm-run-path": "^2.0.0",
|
"npm-run-path": "^2.0.0",
|
||||||
@@ -16445,7 +16497,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/cross-spawn": {
|
"node_modules/cross-spawn": {
|
||||||
"version": "7.0.3",
|
"version": "7.0.5",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"path-key": "^3.1.0",
|
"path-key": "^3.1.0",
|
||||||
@@ -18359,7 +18411,7 @@
|
|||||||
"@nodelib/fs.walk": "^1.2.8",
|
"@nodelib/fs.walk": "^1.2.8",
|
||||||
"ajv": "^6.12.4",
|
"ajv": "^6.12.4",
|
||||||
"chalk": "^4.0.0",
|
"chalk": "^4.0.0",
|
||||||
"cross-spawn": "^7.0.2",
|
"cross-spawn": "^7.0.5",
|
||||||
"debug": "^4.3.2",
|
"debug": "^4.3.2",
|
||||||
"doctrine": "^3.0.0",
|
"doctrine": "^3.0.0",
|
||||||
"escape-string-regexp": "^4.0.0",
|
"escape-string-regexp": "^4.0.0",
|
||||||
@@ -18946,7 +18998,7 @@
|
|||||||
"integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
|
"integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cross-spawn": "^7.0.3",
|
"cross-spawn": "^7.0.5",
|
||||||
"get-stream": "^6.0.0",
|
"get-stream": "^6.0.0",
|
||||||
"human-signals": "^2.1.0",
|
"human-signals": "^2.1.0",
|
||||||
"is-stream": "^2.0.0",
|
"is-stream": "^2.0.0",
|
||||||
@@ -19211,7 +19263,7 @@
|
|||||||
"methods": "~1.1.2",
|
"methods": "~1.1.2",
|
||||||
"on-finished": "2.4.1",
|
"on-finished": "2.4.1",
|
||||||
"parseurl": "~1.3.3",
|
"parseurl": "~1.3.3",
|
||||||
"path-to-regexp": "0.1.7",
|
"path-to-regexp": "0.1.12",
|
||||||
"proxy-addr": "~2.0.7",
|
"proxy-addr": "~2.0.7",
|
||||||
"qs": "6.11.0",
|
"qs": "6.11.0",
|
||||||
"range-parser": "~1.2.1",
|
"range-parser": "~1.2.1",
|
||||||
@@ -19247,7 +19299,7 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/express/node_modules/path-to-regexp": {
|
"node_modules/express/node_modules/path-to-regexp": {
|
||||||
"version": "0.1.7",
|
"version": "0.1.12",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
@@ -30535,7 +30587,7 @@
|
|||||||
"@yarnpkg/lockfile": "^1.1.0",
|
"@yarnpkg/lockfile": "^1.1.0",
|
||||||
"chalk": "^4.1.2",
|
"chalk": "^4.1.2",
|
||||||
"ci-info": "^3.7.0",
|
"ci-info": "^3.7.0",
|
||||||
"cross-spawn": "^7.0.3",
|
"cross-spawn": "^7.0.5",
|
||||||
"find-yarn-workspace-root": "^2.0.0",
|
"find-yarn-workspace-root": "^2.0.0",
|
||||||
"fs-extra": "^9.0.0",
|
"fs-extra": "^9.0.0",
|
||||||
"json-stable-stringify": "^1.0.2",
|
"json-stable-stringify": "^1.0.2",
|
||||||
@@ -31513,7 +31565,7 @@
|
|||||||
"address": "^1.1.2",
|
"address": "^1.1.2",
|
||||||
"browserslist": "^4.18.1",
|
"browserslist": "^4.18.1",
|
||||||
"chalk": "^4.1.2",
|
"chalk": "^4.1.2",
|
||||||
"cross-spawn": "^7.0.3",
|
"cross-spawn": "^7.0.5",
|
||||||
"detect-port-alt": "^1.1.6",
|
"detect-port-alt": "^1.1.6",
|
||||||
"escape-string-regexp": "^4.0.0",
|
"escape-string-regexp": "^4.0.0",
|
||||||
"filesize": "^8.0.6",
|
"filesize": "^8.0.6",
|
||||||
@@ -32969,7 +33021,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sane/node_modules/cross-spawn": {
|
"node_modules/sane/node_modules/cross-spawn": {
|
||||||
"version": "6.0.5",
|
"version": "7.0.5",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"nice-try": "^1.0.4",
|
"nice-try": "^1.0.4",
|
||||||
@@ -32986,7 +33038,7 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cross-spawn": "^6.0.0",
|
"cross-spawn": "^7.0.5",
|
||||||
"get-stream": "^4.0.0",
|
"get-stream": "^4.0.0",
|
||||||
"is-stream": "^1.1.0",
|
"is-stream": "^1.1.0",
|
||||||
"npm-run-path": "^2.0.0",
|
"npm-run-path": "^2.0.0",
|
||||||
@@ -35955,7 +36007,7 @@
|
|||||||
"@webpack-cli/serve": "^2.0.5",
|
"@webpack-cli/serve": "^2.0.5",
|
||||||
"colorette": "^2.0.14",
|
"colorette": "^2.0.14",
|
||||||
"commander": "^10.0.1",
|
"commander": "^10.0.1",
|
||||||
"cross-spawn": "^7.0.3",
|
"cross-spawn": "^7.0.5",
|
||||||
"envinfo": "^7.7.3",
|
"envinfo": "^7.7.3",
|
||||||
"fastest-levenshtein": "^1.0.12",
|
"fastest-levenshtein": "^1.0.12",
|
||||||
"import-local": "^3.0.2",
|
"import-local": "^3.0.2",
|
||||||
@@ -36480,7 +36532,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/windows-release/node_modules/cross-spawn": {
|
"node_modules/windows-release/node_modules/cross-spawn": {
|
||||||
"version": "6.0.5",
|
"version": "7.0.5",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"nice-try": "^1.0.4",
|
"nice-try": "^1.0.4",
|
||||||
@@ -36497,7 +36549,7 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cross-spawn": "^6.0.0",
|
"cross-spawn": "^7.0.5",
|
||||||
"get-stream": "^4.0.0",
|
"get-stream": "^4.0.0",
|
||||||
"is-stream": "^1.1.0",
|
"is-stream": "^1.1.0",
|
||||||
"npm-run-path": "^2.0.0",
|
"npm-run-path": "^2.0.0",
|
||||||
|
|||||||
@@ -206,9 +206,11 @@
|
|||||||
"build:dataExplorer:ci": "npm run build:ci",
|
"build:dataExplorer:ci": "npm run build:ci",
|
||||||
"build": "npm run format:check && npm run lint && npm run compile && npm run compile:strict && npm run pack:prod && npm run copyToConsumers",
|
"build": "npm run format:check && npm run lint && npm run compile && npm run compile:strict && npm run pack:prod && npm run copyToConsumers",
|
||||||
"build:ci": "npm run format:check && npm run lint && npm run compile && npm run compile:strict && npm run pack:fast",
|
"build:ci": "npm run format:check && npm run lint && npm run compile && npm run compile:strict && npm run pack:fast",
|
||||||
|
"build:proxy": "npm run compile && npm run compile:strict && npm run pack:prod && npm run copyToProxy",
|
||||||
"pack:prod": "webpack --mode production",
|
"pack:prod": "webpack --mode production",
|
||||||
"pack:fast": "webpack --mode development --progress",
|
"pack:fast": "webpack --mode development --progress",
|
||||||
"copyToConsumers": "node copyToConsumers",
|
"copyToConsumers": "node copyToConsumers",
|
||||||
|
"copyToProxy": "rm -rf ./utils/local-proxy/dist && cp -r ./dist ./utils/local-proxy",
|
||||||
"test": "rimraf coverage && jest",
|
"test": "rimraf coverage && jest",
|
||||||
"test:debug": "jest --runInBand",
|
"test:debug": "jest --runInBand",
|
||||||
"test:e2e": "jest -c ./jest.config.playwright.js --detectOpenHandles",
|
"test:e2e": "jest -c ./jest.config.playwright.js --detectOpenHandles",
|
||||||
|
|||||||
36205
preview/package-lock.json
generated
36205
preview/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -765,10 +765,3 @@ export const ShortenedQueryCopilotSampleContainerSchema = {
|
|||||||
|
|
||||||
userPrompt: "find all products",
|
userPrompt: "find all products",
|
||||||
};
|
};
|
||||||
|
|
||||||
export enum MongoGuidRepresentation {
|
|
||||||
Standard = "Standard",
|
|
||||||
CSharpLegacy = "CSharpLegacy",
|
|
||||||
JavaLegacy = "JavaLegacy",
|
|
||||||
PythonLegacy = "PythonLegacy",
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export const tokenProvider = async (requestInfo: Cosmos.RequestInfo) => {
|
|||||||
return authorizationToken;
|
return authorizationToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (configContext.platform === Platform.Emulator) {
|
if (configContext.platform === Platform.Emulator || configContext.platform === Platform.VNextEmulator) {
|
||||||
// TODO This SDK method mutates the headers object. Find a better one or fix the SDK.
|
// TODO This SDK method mutates the headers object. Find a better one or fix the SDK.
|
||||||
await Cosmos.setAuthorizationTokenHeaderUsingMasterKey(verb, resourceId, resourceType, headers, EmulatorMasterKey);
|
await Cosmos.setAuthorizationTokenHeaderUsingMasterKey(verb, resourceId, resourceType, headers, EmulatorMasterKey);
|
||||||
return decodeURIComponent(headers.authorization);
|
return decodeURIComponent(headers.authorization);
|
||||||
@@ -119,7 +119,7 @@ export const requestPlugin: Cosmos.Plugin<any> = async (requestContext, diagnost
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const endpoint = () => {
|
export const endpoint = () => {
|
||||||
if (configContext.platform === Platform.Emulator) {
|
if (configContext.platform === Platform.Emulator || configContext.platform === Platform.VNextEmulator) {
|
||||||
// In worker scope, _global(self).parent does not exist
|
// In worker scope, _global(self).parent does not exist
|
||||||
const location = _global.parent ? _global.parent.location : _global.location;
|
const location = _global.parent ? _global.parent.location : _global.location;
|
||||||
return configContext.EMULATOR_ENDPOINT || location.origin;
|
return configContext.EMULATOR_ENDPOINT || location.origin;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { Constants as CosmosSDKConstants } from "@azure/cosmos";
|
import { Constants as CosmosSDKConstants } from "@azure/cosmos";
|
||||||
import { getMongoGuidRepresentation } from "Shared/StorageUtility";
|
|
||||||
import { AuthType } from "../AuthType";
|
import { AuthType } from "../AuthType";
|
||||||
import { configContext } from "../ConfigContext";
|
import { configContext } from "../ConfigContext";
|
||||||
import * as DataModels from "../Contracts/DataModels";
|
import * as DataModels from "../Contracts/DataModels";
|
||||||
@@ -140,9 +139,6 @@ export function readDocument(
|
|||||||
documentId && documentId.partitionKey && !documentId.partitionKey.systemKey
|
documentId && documentId.partitionKey && !documentId.partitionKey.systemKey
|
||||||
? documentId.partitionKeyProperties?.[0]
|
? documentId.partitionKeyProperties?.[0]
|
||||||
: "",
|
: "",
|
||||||
clientSettings: {
|
|
||||||
guidRepresentation: getMongoGuidRepresentation(),
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const endpoint = getEndpoint(configContext.MONGO_PROXY_ENDPOINT);
|
const endpoint = getEndpoint(configContext.MONGO_PROXY_ENDPOINT);
|
||||||
@@ -185,9 +181,6 @@ export function createDocument(
|
|||||||
partitionKey:
|
partitionKey:
|
||||||
collection && collection.partitionKey && !collection.partitionKey.systemKey ? partitionKeyProperty : "",
|
collection && collection.partitionKey && !collection.partitionKey.systemKey ? partitionKeyProperty : "",
|
||||||
documentContent: JSON.stringify(documentContent),
|
documentContent: JSON.stringify(documentContent),
|
||||||
clientSettings: {
|
|
||||||
guidRepresentation: getMongoGuidRepresentation(),
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const endpoint = getEndpoint(configContext.MONGO_PROXY_ENDPOINT);
|
const endpoint = getEndpoint(configContext.MONGO_PROXY_ENDPOINT);
|
||||||
@@ -235,9 +228,6 @@ export function updateDocument(
|
|||||||
? documentId.partitionKeyProperties?.[0]
|
? documentId.partitionKeyProperties?.[0]
|
||||||
: "",
|
: "",
|
||||||
documentContent,
|
documentContent,
|
||||||
clientSettings: {
|
|
||||||
guidRepresentation: getMongoGuidRepresentation(),
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
const endpoint = getEndpoint(configContext.MONGO_PROXY_ENDPOINT);
|
const endpoint = getEndpoint(configContext.MONGO_PROXY_ENDPOINT);
|
||||||
|
|
||||||
@@ -284,9 +274,6 @@ export function deleteDocuments(
|
|||||||
subscriptionID: userContext.subscriptionId,
|
subscriptionID: userContext.subscriptionId,
|
||||||
resourceGroup: userContext.resourceGroup,
|
resourceGroup: userContext.resourceGroup,
|
||||||
databaseAccountName: databaseAccount.name,
|
databaseAccountName: databaseAccount.name,
|
||||||
clientSettings: {
|
|
||||||
guidRepresentation: getMongoGuidRepresentation(),
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
const endpoint = getEndpoint(configContext.MONGO_PROXY_ENDPOINT);
|
const endpoint = getEndpoint(configContext.MONGO_PROXY_ENDPOINT);
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ export enum Platform {
|
|||||||
Hosted = "Hosted",
|
Hosted = "Hosted",
|
||||||
Emulator = "Emulator",
|
Emulator = "Emulator",
|
||||||
Fabric = "Fabric",
|
Fabric = "Fabric",
|
||||||
|
VNextEmulator = "VNextEmulator",
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ConfigContext {
|
export interface ConfigContext {
|
||||||
@@ -215,7 +216,7 @@ export async function initializeConfiguration(): Promise<ConfigContext> {
|
|||||||
const AAD_ENDPOINT = params.get("aadEndpoint") || "";
|
const AAD_ENDPOINT = params.get("aadEndpoint") || "";
|
||||||
updateConfigContext({ AAD_ENDPOINT });
|
updateConfigContext({ AAD_ENDPOINT });
|
||||||
}
|
}
|
||||||
if (params.has("platform")) {
|
if (params.has("platform") && configContext.platform !== Platform.VNextEmulator) {
|
||||||
const platform = params.get("platform");
|
const platform = params.get("platform");
|
||||||
switch (platform) {
|
switch (platform) {
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { useDatabases } from "Explorer/useDatabases";
|
|||||||
import { isFabric, isFabricNative } from "Platform/Fabric/FabricUtil";
|
import { isFabric, isFabricNative } from "Platform/Fabric/FabricUtil";
|
||||||
import { Action } from "Shared/Telemetry/TelemetryConstants";
|
import { Action } from "Shared/Telemetry/TelemetryConstants";
|
||||||
import { traceOpen } from "Shared/Telemetry/TelemetryProcessor";
|
import { traceOpen } from "Shared/Telemetry/TelemetryProcessor";
|
||||||
|
import { areAdvancedScriptsSupported } from "Utils/PlatformFeatureUtils";
|
||||||
import { ReactTabKind, useTabs } from "hooks/useTabs";
|
import { ReactTabKind, useTabs } from "hooks/useTabs";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import AddCollectionIcon from "../../images/AddCollection.svg";
|
import AddCollectionIcon from "../../images/AddCollection.svg";
|
||||||
@@ -130,6 +131,7 @@ export const createCollectionContextMenuButton = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
areAdvancedScriptsSupported(configContext.platform) &&
|
||||||
configContext.platform !== Platform.Fabric &&
|
configContext.platform !== Platform.Fabric &&
|
||||||
(userContext.apiType === "SQL" || userContext.apiType === "Gremlin")
|
(userContext.apiType === "SQL" || userContext.apiType === "Gremlin")
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import { useDatabases } from "Explorer/useDatabases";
|
|||||||
import { isFabricNative } from "Platform/Fabric/FabricUtil";
|
import { isFabricNative } from "Platform/Fabric/FabricUtil";
|
||||||
import { isVectorSearchEnabled } from "Utils/CapabilityUtils";
|
import { isVectorSearchEnabled } from "Utils/CapabilityUtils";
|
||||||
import { isRunningOnPublicCloud } from "Utils/CloudUtils";
|
import { isRunningOnPublicCloud } from "Utils/CloudUtils";
|
||||||
|
import { isFeatureSupported, PlatformFeature } from "Utils/PlatformFeatureUtils";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import DiscardIcon from "../../../../images/discard.svg";
|
import DiscardIcon from "../../../../images/discard.svg";
|
||||||
import SaveIcon from "../../../../images/save-cosmos.svg";
|
import SaveIcon from "../../../../images/save-cosmos.svg";
|
||||||
@@ -60,15 +61,15 @@ import {
|
|||||||
AddMongoIndexProps,
|
AddMongoIndexProps,
|
||||||
ChangeFeedPolicyState,
|
ChangeFeedPolicyState,
|
||||||
GeospatialConfigType,
|
GeospatialConfigType,
|
||||||
MongoIndexTypes,
|
|
||||||
SettingsV2TabTypes,
|
|
||||||
TtlType,
|
|
||||||
getMongoNotification,
|
getMongoNotification,
|
||||||
getTabTitle,
|
getTabTitle,
|
||||||
hasDatabaseSharedThroughput,
|
hasDatabaseSharedThroughput,
|
||||||
isDirty,
|
isDirty,
|
||||||
|
MongoIndexTypes,
|
||||||
parseConflictResolutionMode,
|
parseConflictResolutionMode,
|
||||||
parseConflictResolutionProcedure,
|
parseConflictResolutionProcedure,
|
||||||
|
SettingsV2TabTypes,
|
||||||
|
TtlType,
|
||||||
} from "./SettingsUtils";
|
} from "./SettingsUtils";
|
||||||
|
|
||||||
interface SettingsV2TabInfo {
|
interface SettingsV2TabInfo {
|
||||||
@@ -276,14 +277,14 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
|||||||
this.saveSettingsButton = {
|
this.saveSettingsButton = {
|
||||||
isEnabled: this.isSaveSettingsButtonEnabled,
|
isEnabled: this.isSaveSettingsButtonEnabled,
|
||||||
isVisible: () => {
|
isVisible: () => {
|
||||||
return true;
|
return isFeatureSupported(PlatformFeature.UpdateCollection);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
this.discardSettingsChangesButton = {
|
this.discardSettingsChangesButton = {
|
||||||
isEnabled: this.isDiscardSettingsButtonEnabled,
|
isEnabled: this.isDiscardSettingsButtonEnabled,
|
||||||
isVisible: () => {
|
isVisible: () => {
|
||||||
return true;
|
return isFeatureSupported(PlatformFeature.UpdateCollection);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1335,7 +1336,7 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.shouldShowComputedPropertiesEditor) {
|
if (isFeatureSupported(PlatformFeature.ComputedProperties) && this.shouldShowComputedPropertiesEditor) {
|
||||||
tabs.push({
|
tabs.push({
|
||||||
tab: SettingsV2TabTypes.ComputedPropertiesTab,
|
tab: SettingsV2TabTypes.ComputedPropertiesTab,
|
||||||
content: <ComputedPropertiesComponent {...computedPropertiesComponentProps} />,
|
content: <ComputedPropertiesComponent {...computedPropertiesComponentProps} />,
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ export class ScaleComponent extends React.Component<ScaleComponentProps> {
|
|||||||
|
|
||||||
constructor(props: ScaleComponentProps) {
|
constructor(props: ScaleComponentProps) {
|
||||||
super(props);
|
super(props);
|
||||||
this.isEmulator = configContext.platform === Platform.Emulator;
|
this.isEmulator = configContext.platform === Platform.Emulator || configContext.platform === Platform.VNextEmulator;
|
||||||
this.offer = this.props.database?.offer() || this.props.collection?.offer();
|
this.offer = this.props.database?.offer() || this.props.collection?.offer();
|
||||||
this.databaseId = this.props.database?.id() || this.props.collection.databaseId;
|
this.databaseId = this.props.database?.id() || this.props.collection.databaseId;
|
||||||
this.collectionId = this.props.collection?.id();
|
this.collectionId = this.props.collection?.id();
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { Link } from "@fluentui/react/lib/Link";
|
|||||||
import { isPublicInternetAccessAllowed } from "Common/DatabaseAccountUtility";
|
import { isPublicInternetAccessAllowed } from "Common/DatabaseAccountUtility";
|
||||||
import { Environment, getEnvironment } from "Common/EnvironmentUtility";
|
import { Environment, getEnvironment } from "Common/EnvironmentUtility";
|
||||||
import { sendMessage } from "Common/MessageHandler";
|
import { sendMessage } from "Common/MessageHandler";
|
||||||
import { Platform, configContext } from "ConfigContext";
|
import { configContext, Platform } from "ConfigContext";
|
||||||
import { MessageTypes } from "Contracts/ExplorerContracts";
|
import { MessageTypes } from "Contracts/ExplorerContracts";
|
||||||
import { useDataPlaneRbac } from "Explorer/Panes/SettingsPane/SettingsPane";
|
import { useDataPlaneRbac } from "Explorer/Panes/SettingsPane/SettingsPane";
|
||||||
import { getCopilotEnabled, isCopilotFeatureRegistered } from "Explorer/QueryCopilot/Shared/QueryCopilotClient";
|
import { getCopilotEnabled, isCopilotFeatureRegistered } from "Explorer/QueryCopilot/Shared/QueryCopilotClient";
|
||||||
@@ -18,6 +18,7 @@ import { LocalStorageUtility, StorageKey } from "Shared/StorageUtility";
|
|||||||
import { acquireMsalTokenForAccount } from "Utils/AuthorizationUtils";
|
import { acquireMsalTokenForAccount } from "Utils/AuthorizationUtils";
|
||||||
import { allowedNotebookServerUrls, validateEndpoint } from "Utils/EndpointUtils";
|
import { allowedNotebookServerUrls, validateEndpoint } from "Utils/EndpointUtils";
|
||||||
import { featureRegistered } from "Utils/FeatureRegistrationUtils";
|
import { featureRegistered } from "Utils/FeatureRegistrationUtils";
|
||||||
|
import { isFeatureSupported, PlatformFeature } from "Utils/PlatformFeatureUtils";
|
||||||
import { update } from "Utils/arm/generatedClients/cosmos/databaseAccounts";
|
import { update } from "Utils/arm/generatedClients/cosmos/databaseAccounts";
|
||||||
import { useQueryCopilot } from "hooks/useQueryCopilot";
|
import { useQueryCopilot } from "hooks/useQueryCopilot";
|
||||||
import * as ko from "knockout";
|
import * as ko from "knockout";
|
||||||
@@ -1187,6 +1188,7 @@ export default class Explorer {
|
|||||||
|
|
||||||
// TODO: remove reference to isNotebookEnabled and isNotebooksEnabledForAccount
|
// TODO: remove reference to isNotebookEnabled and isNotebooksEnabledForAccount
|
||||||
const isNotebookEnabled =
|
const isNotebookEnabled =
|
||||||
|
isFeatureSupported(PlatformFeature.Notebooks) &&
|
||||||
configContext.platform !== Platform.Fabric &&
|
configContext.platform !== Platform.Fabric &&
|
||||||
(userContext.features.notebooksDownBanner ||
|
(userContext.features.notebooksDownBanner ||
|
||||||
useNotebook.getState().isPhoenixNotebooks ||
|
useNotebook.getState().isPhoenixNotebooks ||
|
||||||
@@ -1194,7 +1196,11 @@ export default class Explorer {
|
|||||||
useNotebook.getState().setIsNotebookEnabled(isNotebookEnabled);
|
useNotebook.getState().setIsNotebookEnabled(isNotebookEnabled);
|
||||||
useNotebook
|
useNotebook
|
||||||
.getState()
|
.getState()
|
||||||
.setIsShellEnabled(useNotebook.getState().isPhoenixFeatures && isPublicInternetAccessAllowed());
|
.setIsShellEnabled(
|
||||||
|
isFeatureSupported(PlatformFeature.CloudShell) &&
|
||||||
|
useNotebook.getState().isPhoenixFeatures &&
|
||||||
|
isPublicInternetAccessAllowed(),
|
||||||
|
);
|
||||||
|
|
||||||
TelemetryProcessor.trace(Action.NotebookEnabled, ActionModifiers.Mark, {
|
TelemetryProcessor.trace(Action.NotebookEnabled, ActionModifiers.Mark, {
|
||||||
isNotebookEnabled,
|
isNotebookEnabled,
|
||||||
@@ -1215,6 +1221,7 @@ export default class Explorer {
|
|||||||
|
|
||||||
public async configureCopilot(): Promise<void> {
|
public async configureCopilot(): Promise<void> {
|
||||||
if (
|
if (
|
||||||
|
!isFeatureSupported(PlatformFeature.Copilot) ||
|
||||||
userContext.apiType !== "SQL" ||
|
userContext.apiType !== "SQL" ||
|
||||||
!userContext.subscriptionId ||
|
!userContext.subscriptionId ||
|
||||||
![Environment.Development, Environment.Mpac, Environment.Prod].includes(getEnvironment())
|
![Environment.Development, Environment.Mpac, Environment.Prod].includes(getEnvironment())
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { KeyboardAction } from "KeyboardShortcuts";
|
import { KeyboardAction } from "KeyboardShortcuts";
|
||||||
import { isDataplaneRbacSupported } from "Utils/APITypeUtils";
|
import { isDataplaneRbacSupported } from "Utils/APITypeUtils";
|
||||||
|
import { areAdvancedScriptsSupported, isFeatureSupported, PlatformFeature } from "Utils/PlatformFeatureUtils";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import AddSqlQueryIcon from "../../../../images/AddSqlQuery_16x16.svg";
|
import AddSqlQueryIcon from "../../../../images/AddSqlQuery_16x16.svg";
|
||||||
@@ -17,7 +18,7 @@ import SynapseIcon from "../../../../images/synapse-link.svg";
|
|||||||
import VSCodeIcon from "../../../../images/vscode.svg";
|
import VSCodeIcon from "../../../../images/vscode.svg";
|
||||||
import { AuthType } from "../../../AuthType";
|
import { AuthType } from "../../../AuthType";
|
||||||
import * as Constants from "../../../Common/Constants";
|
import * as Constants from "../../../Common/Constants";
|
||||||
import { Platform, configContext } from "../../../ConfigContext";
|
import { configContext, Platform } from "../../../ConfigContext";
|
||||||
import * as ViewModels from "../../../Contracts/ViewModels";
|
import * as ViewModels from "../../../Contracts/ViewModels";
|
||||||
import { userContext } from "../../../UserContext";
|
import { userContext } from "../../../UserContext";
|
||||||
import { isRunningOnNationalCloud } from "../../../Utils/CloudUtils";
|
import { isRunningOnNationalCloud } from "../../../Utils/CloudUtils";
|
||||||
@@ -52,6 +53,7 @@ export function createStaticCommandBarButtons(
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
isFeatureSupported(PlatformFeature.SynapseLink) &&
|
||||||
configContext.platform !== Platform.Fabric &&
|
configContext.platform !== Platform.Fabric &&
|
||||||
userContext.apiType !== "Tables" &&
|
userContext.apiType !== "Tables" &&
|
||||||
userContext.apiType !== "Cassandra"
|
userContext.apiType !== "Cassandra"
|
||||||
@@ -63,7 +65,9 @@ export function createStaticCommandBarButtons(
|
|||||||
}
|
}
|
||||||
if (userContext.apiType !== "Gremlin") {
|
if (userContext.apiType !== "Gremlin") {
|
||||||
const addVsCode = createOpenVsCodeDialogButton(container);
|
const addVsCode = createOpenVsCodeDialogButton(container);
|
||||||
buttons.push(addVsCode);
|
if (addVsCode) {
|
||||||
|
buttons.push(addVsCode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,11 +246,17 @@ export function createDivider(): CommandButtonComponentProps {
|
|||||||
|
|
||||||
function areScriptsSupported(): boolean {
|
function areScriptsSupported(): boolean {
|
||||||
return (
|
return (
|
||||||
configContext.platform !== Platform.Fabric && (userContext.apiType === "SQL" || userContext.apiType === "Gremlin")
|
areAdvancedScriptsSupported() &&
|
||||||
|
configContext.platform !== Platform.Fabric &&
|
||||||
|
(userContext.apiType === "SQL" || userContext.apiType === "Gremlin")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createOpenSynapseLinkDialogButton(container: Explorer): CommandButtonComponentProps {
|
function createOpenSynapseLinkDialogButton(container: Explorer): CommandButtonComponentProps {
|
||||||
|
if (!isFeatureSupported(PlatformFeature.SynapseLink)) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
if (configContext.platform === Platform.Emulator) {
|
if (configContext.platform === Platform.Emulator) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
@@ -274,6 +284,10 @@ function createOpenSynapseLinkDialogButton(container: Explorer): CommandButtonCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
function createOpenVsCodeDialogButton(container: Explorer): CommandButtonComponentProps {
|
function createOpenVsCodeDialogButton(container: Explorer): CommandButtonComponentProps {
|
||||||
|
if (!isFeatureSupported(PlatformFeature.VSCodeIntegration)) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
const label = "Visual Studio Code";
|
const label = "Visual Studio Code";
|
||||||
return {
|
return {
|
||||||
iconSrc: VSCodeIcon,
|
iconSrc: VSCodeIcon,
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ import * as TelemetryProcessor from "Shared/Telemetry/TelemetryProcessor";
|
|||||||
import { userContext } from "UserContext";
|
import { userContext } from "UserContext";
|
||||||
import { getCollectionName } from "Utils/APITypeUtils";
|
import { getCollectionName } from "Utils/APITypeUtils";
|
||||||
import { isCapabilityEnabled, isServerlessAccount, isVectorSearchEnabled } from "Utils/CapabilityUtils";
|
import { isCapabilityEnabled, isServerlessAccount, isVectorSearchEnabled } from "Utils/CapabilityUtils";
|
||||||
|
import { isFeatureSupported, PlatformFeature } from "Utils/PlatformFeatureUtils";
|
||||||
import { getUpsellMessage } from "Utils/PricingUtils";
|
import { getUpsellMessage } from "Utils/PricingUtils";
|
||||||
import { ValidCosmosDbIdDescription, ValidCosmosDbIdInputPattern } from "Utils/ValidationUtils";
|
import { ValidCosmosDbIdDescription, ValidCosmosDbIdInputPattern } from "Utils/ValidationUtils";
|
||||||
import * as AutoPilotUtils from "../../../Utils/AutoPilotUtils";
|
import * as AutoPilotUtils from "../../../Utils/AutoPilotUtils";
|
||||||
@@ -727,7 +728,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{!isFabricNative() && userContext.apiType === "SQL" && (
|
{isFeatureSupported(PlatformFeature.UniqueKeys) && !isFabricNative() && userContext.apiType === "SQL" && (
|
||||||
<Stack style={{ marginTop: -2, marginBottom: -4 }}>
|
<Stack style={{ marginTop: -2, marginBottom: -4 }}>
|
||||||
{UniqueKeysHeader()}
|
{UniqueKeysHeader()}
|
||||||
{this.state.uniqueKeys.map((uniqueKey: string, i: number): JSX.Element => {
|
{this.state.uniqueKeys.map((uniqueKey: string, i: number): JSX.Element => {
|
||||||
@@ -900,78 +901,86 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
</CollapsibleSectionComponent>
|
</CollapsibleSectionComponent>
|
||||||
</Stack>
|
</Stack>
|
||||||
)}
|
)}
|
||||||
{!isFabricNative() && userContext.apiType !== "Tables" && (
|
{isFeatureSupported(PlatformFeature.AdvancedContainerSettings) &&
|
||||||
<CollapsibleSectionComponent
|
!isFabricNative() &&
|
||||||
title="Advanced"
|
userContext.apiType !== "Tables" && (
|
||||||
isExpandedByDefault={false}
|
<CollapsibleSectionComponent
|
||||||
onExpand={() => {
|
title="Advanced"
|
||||||
TelemetryProcessor.traceOpen(Action.ExpandAddCollectionPaneAdvancedSection);
|
isExpandedByDefault={false}
|
||||||
scrollToSection("collapsibleAdvancedSectionContent");
|
onExpand={() => {
|
||||||
}}
|
TelemetryProcessor.traceOpen(Action.ExpandAddCollectionPaneAdvancedSection);
|
||||||
>
|
scrollToSection("collapsibleAdvancedSectionContent");
|
||||||
<Stack className="panelGroupSpacing" id="collapsibleAdvancedSectionContent">
|
}}
|
||||||
{isCapabilityEnabled("EnableMongo") && !isCapabilityEnabled("EnableMongo16MBDocumentSupport") && (
|
>
|
||||||
<Stack className="panelGroupSpacing">
|
<Stack className="panelGroupSpacing" id="collapsibleAdvancedSectionContent">
|
||||||
<Stack horizontal>
|
{isCapabilityEnabled("EnableMongo") && !isCapabilityEnabled("EnableMongo16MBDocumentSupport") && (
|
||||||
<span className="mandatoryStar">* </span>
|
<Stack className="panelGroupSpacing">
|
||||||
<Text className="panelTextBold" variant="small">
|
<Stack horizontal>
|
||||||
Indexing
|
<span className="mandatoryStar">* </span>
|
||||||
</Text>
|
<Text className="panelTextBold" variant="small">
|
||||||
<TooltipHost
|
Indexing
|
||||||
directionalHint={DirectionalHint.bottomLeftEdge}
|
</Text>
|
||||||
content="The _id field is indexed by default. Creating a wildcard index for all fields will optimize queries and is recommended for development."
|
<TooltipHost
|
||||||
>
|
directionalHint={DirectionalHint.bottomLeftEdge}
|
||||||
<Icon
|
content="The _id field is indexed by default. Creating a wildcard index for all fields will optimize queries and is recommended for development."
|
||||||
iconName="Info"
|
>
|
||||||
className="panelInfoIcon"
|
<Icon
|
||||||
tabIndex={0}
|
iconName="Info"
|
||||||
ariaLabel="The _id field is indexed by default. Creating a wildcard index for all fields will optimize queries and is recommended for development."
|
className="panelInfoIcon"
|
||||||
/>
|
tabIndex={0}
|
||||||
</TooltipHost>
|
ariaLabel="The _id field is indexed by default. Creating a wildcard index for all fields will optimize queries and is recommended for development."
|
||||||
|
/>
|
||||||
|
</TooltipHost>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
<Checkbox
|
||||||
|
label="Create a Wildcard Index on all fields"
|
||||||
|
checked={this.state.createMongoWildCardIndex}
|
||||||
|
styles={{
|
||||||
|
text: { fontSize: 12 },
|
||||||
|
checkbox: { width: 12, height: 12 },
|
||||||
|
label: { padding: 0, alignItems: "center" },
|
||||||
|
}}
|
||||||
|
onChange={(ev: React.FormEvent<HTMLElement>, isChecked: boolean) =>
|
||||||
|
this.setState({ createMongoWildCardIndex: isChecked })
|
||||||
|
}
|
||||||
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
)}
|
||||||
|
|
||||||
<Checkbox
|
{userContext.apiType === "SQL" && (
|
||||||
label="Create a Wildcard Index on all fields"
|
<Stack className="panelGroupSpacing">
|
||||||
checked={this.state.createMongoWildCardIndex}
|
<Checkbox
|
||||||
styles={{
|
label="My application uses an older Cosmos .NET or Java SDK version (.NET V1 or Java V2)"
|
||||||
text: { fontSize: 12 },
|
checked={this.state.useHashV1}
|
||||||
checkbox: { width: 12, height: 12 },
|
styles={{
|
||||||
label: { padding: 0, alignItems: "center" },
|
text: { fontSize: 12 },
|
||||||
}}
|
checkbox: { width: 12, height: 12 },
|
||||||
onChange={(ev: React.FormEvent<HTMLElement>, isChecked: boolean) =>
|
label: {
|
||||||
this.setState({ createMongoWildCardIndex: isChecked })
|
padding: 0,
|
||||||
}
|
alignItems: "center",
|
||||||
/>
|
wordWrap: "break-word",
|
||||||
</Stack>
|
whiteSpace: "break-spaces",
|
||||||
)}
|
},
|
||||||
|
}}
|
||||||
{userContext.apiType === "SQL" && (
|
onChange={(ev: React.FormEvent<HTMLElement>, isChecked: boolean) =>
|
||||||
<Stack className="panelGroupSpacing">
|
this.setState({ useHashV1: isChecked, subPartitionKeys: [] })
|
||||||
<Checkbox
|
}
|
||||||
label="My application uses an older Cosmos .NET or Java SDK version (.NET V1 or Java V2)"
|
/>
|
||||||
checked={this.state.useHashV1}
|
<Text variant="small">
|
||||||
styles={{
|
<Icon iconName="InfoSolid" className="removeIcon" /> To ensure compatibility with older SDKs,
|
||||||
text: { fontSize: 12 },
|
the created container will use a legacy partitioning scheme that supports partition key values
|
||||||
checkbox: { width: 12, height: 12 },
|
of size only up to 101 bytes. If this is enabled, you will not be able to use hierarchical
|
||||||
label: { padding: 0, alignItems: "center", wordWrap: "break-word", whiteSpace: "break-spaces" },
|
partition keys.{" "}
|
||||||
}}
|
<Link href="https://aka.ms/cosmos-large-pk" target="_blank">
|
||||||
onChange={(ev: React.FormEvent<HTMLElement>, isChecked: boolean) =>
|
Learn more
|
||||||
this.setState({ useHashV1: isChecked, subPartitionKeys: [] })
|
</Link>
|
||||||
}
|
</Text>
|
||||||
/>
|
</Stack>
|
||||||
<Text variant="small">
|
)}
|
||||||
<Icon iconName="InfoSolid" className="removeIcon" /> To ensure compatibility with older SDKs, the
|
</Stack>
|
||||||
created container will use a legacy partitioning scheme that supports partition key values of size
|
</CollapsibleSectionComponent>
|
||||||
only up to 101 bytes. If this is enabled, you will not be able to use hierarchical partition keys.{" "}
|
)}
|
||||||
<Link href="https://aka.ms/cosmos-large-pk" target="_blank">
|
|
||||||
Learn more
|
|
||||||
</Link>
|
|
||||||
</Text>
|
|
||||||
</Stack>
|
|
||||||
)}
|
|
||||||
</Stack>
|
|
||||||
</CollapsibleSectionComponent>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<PanelFooterComponent buttonLabel="OK" isButtonDisabled={this.state.isThroughputCapExceeded} />
|
<PanelFooterComponent buttonLabel="OK" isButtonDisabled={this.state.isThroughputCapExceeded} />
|
||||||
@@ -1134,6 +1143,10 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
private shouldShowCollectionThroughputInput(): boolean {
|
private shouldShowCollectionThroughputInput(): boolean {
|
||||||
|
if (!isFeatureSupported(PlatformFeature.ContainerThroughput)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (isServerlessAccount()) {
|
if (isServerlessAccount()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1160,11 +1173,15 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private shouldShowVectorSearchParameters() {
|
private shouldShowVectorSearchParameters() {
|
||||||
return isVectorSearchEnabled() && (isServerlessAccount() || this.shouldShowCollectionThroughputInput());
|
return (
|
||||||
|
isFeatureSupported(PlatformFeature.VectorSearch) &&
|
||||||
|
isVectorSearchEnabled() &&
|
||||||
|
(isServerlessAccount() || this.shouldShowCollectionThroughputInput())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private shouldShowFullTextSearchParameters() {
|
private shouldShowFullTextSearchParameters() {
|
||||||
return !isFabricNative() && this.showFullTextSearch;
|
return isFeatureSupported(PlatformFeature.FullTextSearch) && !isFabricNative() && this.showFullTextSearch;
|
||||||
}
|
}
|
||||||
|
|
||||||
private parseUniqueKeys(): DataModels.UniqueKeyPolicy {
|
private parseUniqueKeys(): DataModels.UniqueKeyPolicy {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { getFullTextLanguageOptions } from "Explorer/Controls/FullTextSeach/Full
|
|||||||
import { isFabricNative } from "Platform/Fabric/FabricUtil";
|
import { isFabricNative } from "Platform/Fabric/FabricUtil";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { userContext } from "UserContext";
|
import { userContext } from "UserContext";
|
||||||
|
import { isFeatureSupported, PlatformFeature } from "Utils/PlatformFeatureUtils";
|
||||||
|
|
||||||
export function getPartitionKeyTooltipText(): string {
|
export function getPartitionKeyTooltipText(): string {
|
||||||
if (userContext.apiType === "Mongo") {
|
if (userContext.apiType === "Mongo") {
|
||||||
@@ -85,7 +86,11 @@ export function UniqueKeysHeader(): JSX.Element {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function shouldShowAnalyticalStoreOptions(): boolean {
|
export function shouldShowAnalyticalStoreOptions(): boolean {
|
||||||
if (isFabricNative() || configContext.platform === Platform.Emulator) {
|
if (
|
||||||
|
!isFeatureSupported(PlatformFeature.AnalyticalStore) ||
|
||||||
|
isFabricNative() ||
|
||||||
|
configContext.platform === Platform.Emulator
|
||||||
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -199,16 +199,10 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({
|
|||||||
LocalStorageUtility.getEntryString(StorageKey.CopilotSampleDBEnabled) === "true",
|
LocalStorageUtility.getEntryString(StorageKey.CopilotSampleDBEnabled) === "true",
|
||||||
);
|
);
|
||||||
|
|
||||||
const [mongoGuidRepresentation, setMongoGuidRepresentation] = useState<Constants.MongoGuidRepresentation>(
|
|
||||||
LocalStorageUtility.hasItem(StorageKey.MongoGuidRepresentation)
|
|
||||||
? (LocalStorageUtility.getEntryString(StorageKey.MongoGuidRepresentation) as Constants.MongoGuidRepresentation)
|
|
||||||
: Constants.MongoGuidRepresentation.CSharpLegacy,
|
|
||||||
);
|
|
||||||
|
|
||||||
const styles = useStyles();
|
const styles = useStyles();
|
||||||
|
|
||||||
const explorerVersion = configContext.gitSha;
|
const explorerVersion = configContext.gitSha;
|
||||||
const isEmulator = configContext.platform === Platform.Emulator;
|
const isEmulator = configContext.platform === Platform.Emulator || configContext.platform === Platform.VNextEmulator;
|
||||||
const shouldShowQueryPageOptions = userContext.apiType === "SQL";
|
const shouldShowQueryPageOptions = userContext.apiType === "SQL";
|
||||||
const showRetrySettings =
|
const showRetrySettings =
|
||||||
(userContext.apiType === "SQL" || userContext.apiType === "Tables" || userContext.apiType === "Gremlin") &&
|
(userContext.apiType === "SQL" || userContext.apiType === "Tables" || userContext.apiType === "Gremlin") &&
|
||||||
@@ -267,8 +261,6 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({
|
|||||||
useDatabases.getState().sampleDataResourceTokenCollection &&
|
useDatabases.getState().sampleDataResourceTokenCollection &&
|
||||||
!isEmulator;
|
!isEmulator;
|
||||||
|
|
||||||
const shouldShowMongoGuidRepresentationOption = userContext.apiType === "Mongo";
|
|
||||||
|
|
||||||
const handlerOnSubmit = async () => {
|
const handlerOnSubmit = async () => {
|
||||||
setIsExecuting(true);
|
setIsExecuting(true);
|
||||||
|
|
||||||
@@ -420,10 +412,6 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldShowMongoGuidRepresentationOption) {
|
|
||||||
LocalStorageUtility.setEntryString(StorageKey.MongoGuidRepresentation, mongoGuidRepresentation);
|
|
||||||
}
|
|
||||||
|
|
||||||
setIsExecuting(false);
|
setIsExecuting(false);
|
||||||
logConsoleInfo(
|
logConsoleInfo(
|
||||||
`Updated items per page setting to ${LocalStorageUtility.getEntryNumber(StorageKey.ActualItemPerPage)}`,
|
`Updated items per page setting to ${LocalStorageUtility.getEntryNumber(StorageKey.ActualItemPerPage)}`,
|
||||||
@@ -445,14 +433,6 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldShowMongoGuidRepresentationOption) {
|
|
||||||
logConsoleInfo(
|
|
||||||
`Updated Mongo Guid Representation to ${LocalStorageUtility.getEntryString(
|
|
||||||
StorageKey.MongoGuidRepresentation,
|
|
||||||
)}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
refreshExplorer && (await explorer.refreshExplorer());
|
refreshExplorer && (await explorer.refreshExplorer());
|
||||||
closeSidePanel();
|
closeSidePanel();
|
||||||
};
|
};
|
||||||
@@ -497,13 +477,6 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({
|
|||||||
{ key: SplitterDirection.Horizontal, text: "Horizontal" },
|
{ key: SplitterDirection.Horizontal, text: "Horizontal" },
|
||||||
];
|
];
|
||||||
|
|
||||||
const mongoGuidRepresentationDropdownOptions: IDropdownOption[] = [
|
|
||||||
{ key: Constants.MongoGuidRepresentation.CSharpLegacy, text: Constants.MongoGuidRepresentation.CSharpLegacy },
|
|
||||||
{ key: Constants.MongoGuidRepresentation.JavaLegacy, text: Constants.MongoGuidRepresentation.JavaLegacy },
|
|
||||||
{ key: Constants.MongoGuidRepresentation.PythonLegacy, text: Constants.MongoGuidRepresentation.PythonLegacy },
|
|
||||||
{ key: Constants.MongoGuidRepresentation.Standard, text: Constants.MongoGuidRepresentation.Standard },
|
|
||||||
];
|
|
||||||
|
|
||||||
const handleOnPriorityLevelOptionChange = (
|
const handleOnPriorityLevelOptionChange = (
|
||||||
ev: React.FormEvent<HTMLInputElement>,
|
ev: React.FormEvent<HTMLInputElement>,
|
||||||
option: IChoiceGroupOption,
|
option: IChoiceGroupOption,
|
||||||
@@ -586,13 +559,6 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({
|
|||||||
setRefreshExplorer(false);
|
setRefreshExplorer(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOnMongoGuidRepresentationOptionChange = (
|
|
||||||
ev: React.FormEvent<HTMLInputElement>,
|
|
||||||
option: IDropdownOption,
|
|
||||||
): void => {
|
|
||||||
setMongoGuidRepresentation(option.key as Constants.MongoGuidRepresentation);
|
|
||||||
};
|
|
||||||
|
|
||||||
const choiceButtonStyles = {
|
const choiceButtonStyles = {
|
||||||
root: {
|
root: {
|
||||||
clear: "both",
|
clear: "both",
|
||||||
@@ -1099,15 +1065,15 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({
|
|||||||
<div className={styles.settingsSectionContainer}>
|
<div className={styles.settingsSectionContainer}>
|
||||||
<div className={styles.settingsSectionDescription}>
|
<div className={styles.settingsSectionDescription}>
|
||||||
This is a sample database and collection with synthetic product data you can use to explore using
|
This is a sample database and collection with synthetic product data you can use to explore using
|
||||||
NoSQL queries. This will appear as another database in the Data Explorer UI, and is created by,
|
NoSQL queries and Query Advisor. This will appear as another database in the Data Explorer UI, and
|
||||||
and maintained by Microsoft at no cost to you.
|
is created by, and maintained by Microsoft at no cost to you.
|
||||||
</div>
|
</div>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
styles={{
|
styles={{
|
||||||
label: { padding: 0 },
|
label: { padding: 0 },
|
||||||
}}
|
}}
|
||||||
className="padding"
|
className="padding"
|
||||||
ariaLabel="Enable sample db for query exploration"
|
ariaLabel="Enable sample db for Query Advisor"
|
||||||
checked={copilotSampleDBEnabled}
|
checked={copilotSampleDBEnabled}
|
||||||
onChange={handleSampleDatabaseChange}
|
onChange={handleSampleDatabaseChange}
|
||||||
label="Enable sample database"
|
label="Enable sample database"
|
||||||
@@ -1116,27 +1082,6 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({
|
|||||||
</AccordionPanel>
|
</AccordionPanel>
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
)}
|
)}
|
||||||
{shouldShowMongoGuidRepresentationOption && (
|
|
||||||
<AccordionItem value="14">
|
|
||||||
<AccordionHeader>
|
|
||||||
<div className={styles.header}>Guid Representation</div>
|
|
||||||
</AccordionHeader>
|
|
||||||
<AccordionPanel>
|
|
||||||
<div className={styles.settingsSectionContainer}>
|
|
||||||
<div className={styles.settingsSectionDescription}>
|
|
||||||
GuidRepresentation in MongoDB refers to how Globally Unique Identifiers (GUIDs) are serialized and
|
|
||||||
deserialized when stored in BSON documents. This will apply to all document operations.
|
|
||||||
</div>
|
|
||||||
<Dropdown
|
|
||||||
aria-labelledby="mongoGuidRepresentation"
|
|
||||||
selectedKey={mongoGuidRepresentation}
|
|
||||||
options={mongoGuidRepresentationDropdownOptions}
|
|
||||||
onChange={handleOnMongoGuidRepresentationOptionChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</AccordionPanel>
|
|
||||||
</AccordionItem>
|
|
||||||
)}
|
|
||||||
</Accordion>
|
</Accordion>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
import { Stack } from "@fluentui/react";
|
import { Stack } from "@fluentui/react";
|
||||||
|
import { QueryCopilotSampleContainerId, QueryCopilotSampleDatabaseId } from "Common/Constants";
|
||||||
import { CommandButtonComponentProps } from "Explorer/Controls/CommandButton/CommandButtonComponent";
|
import { CommandButtonComponentProps } from "Explorer/Controls/CommandButton/CommandButtonComponent";
|
||||||
import { EditorReact } from "Explorer/Controls/Editor/EditorReact";
|
import { EditorReact } from "Explorer/Controls/Editor/EditorReact";
|
||||||
import { useCommandBar } from "Explorer/Menus/CommandBar/CommandBarComponentAdapter";
|
import { useCommandBar } from "Explorer/Menus/CommandBar/CommandBarComponentAdapter";
|
||||||
import { SaveQueryPane } from "Explorer/Panes/SaveQueryPane/SaveQueryPane";
|
import { SaveQueryPane } from "Explorer/Panes/SaveQueryPane/SaveQueryPane";
|
||||||
|
import { QueryCopilotPromptbar } from "Explorer/QueryCopilot/QueryCopilotPromptbar";
|
||||||
import { readCopilotToggleStatus, saveCopilotToggleStatus } from "Explorer/QueryCopilot/QueryCopilotUtilities";
|
import { readCopilotToggleStatus, saveCopilotToggleStatus } from "Explorer/QueryCopilot/QueryCopilotUtilities";
|
||||||
import { OnExecuteQueryClick } from "Explorer/QueryCopilot/Shared/QueryCopilotClient";
|
import { OnExecuteQueryClick } from "Explorer/QueryCopilot/Shared/QueryCopilotClient";
|
||||||
import { QueryCopilotProps } from "Explorer/QueryCopilot/Shared/QueryCopilotInterfaces";
|
import { QueryCopilotProps } from "Explorer/QueryCopilot/Shared/QueryCopilotInterfaces";
|
||||||
@@ -11,6 +13,7 @@ import { QueryCopilotResults } from "Explorer/QueryCopilot/Shared/QueryCopilotRe
|
|||||||
import { userContext } from "UserContext";
|
import { userContext } from "UserContext";
|
||||||
import { QueryCopilotState, useQueryCopilot } from "hooks/useQueryCopilot";
|
import { QueryCopilotState, useQueryCopilot } from "hooks/useQueryCopilot";
|
||||||
import { useSidePanel } from "hooks/useSidePanel";
|
import { useSidePanel } from "hooks/useSidePanel";
|
||||||
|
import { ReactTabKind, TabsState, useTabs } from "hooks/useTabs";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import SplitterLayout from "react-splitter-layout";
|
import SplitterLayout from "react-splitter-layout";
|
||||||
import QueryCommandIcon from "../../../images/CopilotCommand.svg";
|
import QueryCommandIcon from "../../../images/CopilotCommand.svg";
|
||||||
@@ -23,8 +26,7 @@ export const QueryCopilotTab: React.FC<QueryCopilotProps> = ({ explorer }: Query
|
|||||||
const [copilotActive, setCopilotActive] = useState<boolean>(() =>
|
const [copilotActive, setCopilotActive] = useState<boolean>(() =>
|
||||||
readCopilotToggleStatus(userContext.databaseAccount),
|
readCopilotToggleStatus(userContext.databaseAccount),
|
||||||
);
|
);
|
||||||
//TODO: Uncomment this useState when query copilot is reinstated in DE
|
const [tabActive, setTabActive] = useState<boolean>(true);
|
||||||
// const [tabActive, setTabActive] = useState<boolean>(true);
|
|
||||||
|
|
||||||
const getCommandbarButtons = (): CommandButtonComponentProps[] => {
|
const getCommandbarButtons = (): CommandButtonComponentProps[] => {
|
||||||
const executeQueryBtnLabel = selectedQuery ? "Execute Selection" : "Execute Query";
|
const executeQueryBtnLabel = selectedQuery ? "Execute Selection" : "Execute Query";
|
||||||
@@ -68,18 +70,17 @@ export const QueryCopilotTab: React.FC<QueryCopilotProps> = ({ explorer }: Query
|
|||||||
useCommandBar.getState().setContextButtons(getCommandbarButtons());
|
useCommandBar.getState().setContextButtons(getCommandbarButtons());
|
||||||
}, [query, selectedQuery, copilotActive]);
|
}, [query, selectedQuery, copilotActive]);
|
||||||
|
|
||||||
//TODO: Uncomment this effect when query copilot is reinstated in DE
|
React.useEffect(() => {
|
||||||
// React.useEffect(() => {
|
return () => {
|
||||||
// return () => {
|
useTabs.subscribe((state: TabsState) => {
|
||||||
// useTabs.subscribe((state: TabsState) => {
|
if (state.activeReactTab === ReactTabKind.QueryCopilot) {
|
||||||
// if (state.activeReactTab === ReactTabKind.QueryCopilot) {
|
setTabActive(true);
|
||||||
// setTabActive(true);
|
} else {
|
||||||
// } else {
|
setTabActive(false);
|
||||||
// setTabActive(false);
|
}
|
||||||
// }
|
});
|
||||||
// });
|
};
|
||||||
// };
|
}, []);
|
||||||
// }, []);
|
|
||||||
|
|
||||||
const toggleCopilot = (toggle: boolean) => {
|
const toggleCopilot = (toggle: boolean) => {
|
||||||
setCopilotActive(toggle);
|
setCopilotActive(toggle);
|
||||||
@@ -89,7 +90,6 @@ export const QueryCopilotTab: React.FC<QueryCopilotProps> = ({ explorer }: Query
|
|||||||
return (
|
return (
|
||||||
<Stack className="tab-pane" style={{ width: "100%" }}>
|
<Stack className="tab-pane" style={{ width: "100%" }}>
|
||||||
<div style={isGeneratingQuery ? { height: "100%" } : { overflowY: "auto", height: "100%" }}>
|
<div style={isGeneratingQuery ? { height: "100%" } : { overflowY: "auto", height: "100%" }}>
|
||||||
{/*TODO: Uncomment this section when query copilot is reinstated in DE
|
|
||||||
{tabActive && copilotActive && (
|
{tabActive && copilotActive && (
|
||||||
<QueryCopilotPromptbar
|
<QueryCopilotPromptbar
|
||||||
explorer={explorer}
|
explorer={explorer}
|
||||||
@@ -97,7 +97,7 @@ export const QueryCopilotTab: React.FC<QueryCopilotProps> = ({ explorer }: Query
|
|||||||
databaseId={QueryCopilotSampleDatabaseId}
|
databaseId={QueryCopilotSampleDatabaseId}
|
||||||
containerId={QueryCopilotSampleContainerId}
|
containerId={QueryCopilotSampleContainerId}
|
||||||
></QueryCopilotPromptbar>
|
></QueryCopilotPromptbar>
|
||||||
)} */}
|
)}
|
||||||
<Stack className="tabPaneContentContainer">
|
<Stack className="tabPaneContentContainer">
|
||||||
<SplitterLayout percentage={true} vertical={true} primaryIndex={0} primaryMinSize={30} secondaryMinSize={70}>
|
<SplitterLayout percentage={true} vertical={true} primaryIndex={0} primaryMinSize={30} secondaryMinSize={70}>
|
||||||
<EditorReact
|
<EditorReact
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import { ReactTabKind, useTabs } from "hooks/useTabs";
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import ConnectIcon from "../../../images/Connect_color.svg";
|
import ConnectIcon from "../../../images/Connect_color.svg";
|
||||||
import ContainersIcon from "../../../images/Containers.svg";
|
import ContainersIcon from "../../../images/Containers.svg";
|
||||||
import CosmosDBIcon from "../../../images/CosmosDB-logo.svg";
|
|
||||||
import LinkIcon from "../../../images/Link_blue.svg";
|
import LinkIcon from "../../../images/Link_blue.svg";
|
||||||
import PowerShellIcon from "../../../images/PowerShell.svg";
|
import PowerShellIcon from "../../../images/PowerShell.svg";
|
||||||
import CopilotIcon from "../../../images/QueryCopilotNewLogo.svg";
|
import CopilotIcon from "../../../images/QueryCopilotNewLogo.svg";
|
||||||
@@ -121,7 +120,11 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private getSplashScreenButtons = (): JSX.Element => {
|
private getSplashScreenButtons = (): JSX.Element => {
|
||||||
if (userContext.apiType === "SQL") {
|
if (
|
||||||
|
userContext.apiType === "SQL" &&
|
||||||
|
useQueryCopilot.getState().copilotEnabled &&
|
||||||
|
useDatabases.getState().sampleDataResourceTokenCollection
|
||||||
|
) {
|
||||||
return (
|
return (
|
||||||
<Stack
|
<Stack
|
||||||
className="splashStackContainer"
|
className="splashStackContainer"
|
||||||
@@ -149,18 +152,25 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
|
|||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack className="splashStackRow" horizontal>
|
<Stack className="splashStackRow" horizontal>
|
||||||
<SplashScreenButton
|
{useQueryCopilot.getState().copilotEnabled && (
|
||||||
imgSrc={CosmosDBIcon}
|
<SplashScreenButton
|
||||||
imgSize={35}
|
imgSrc={CopilotIcon}
|
||||||
title={"Azure Cosmos DB Samples Gallery"}
|
title={"Query faster with Query Advisor"}
|
||||||
description={
|
description={
|
||||||
"Discover samples that showcase scalable, intelligent app patterns. Try one now to see how fast you can go from concept to code with Cosmos DB"
|
"Query Advisor is your AI buddy that helps you write Azure Cosmos DB queries like a pro. Try it using our sample data set now!"
|
||||||
}
|
}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
window.open("https://azurecosmosdb.github.io/gallery/?tags=example", "_blank");
|
const copilotVersion = userContext.features.copilotVersion;
|
||||||
traceOpen(Action.LearningResourcesClicked, { apiType: userContext.apiType });
|
if (copilotVersion === "v1.0") {
|
||||||
}}
|
useTabs.getState().openAndActivateReactTab(ReactTabKind.QueryCopilot);
|
||||||
/>
|
} else if (copilotVersion === "v2.0") {
|
||||||
|
const sampleCollection = useDatabases.getState().sampleDataResourceTokenCollection;
|
||||||
|
sampleCollection.onNewQueryClick(sampleCollection, undefined);
|
||||||
|
}
|
||||||
|
traceOpen(Action.OpenQueryCopilotFromSplashScreen, { apiType: userContext.apiType });
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<SplashScreenButton
|
<SplashScreenButton
|
||||||
imgSrc={ConnectIcon}
|
imgSrc={ConnectIcon}
|
||||||
title={"Connect"}
|
title={"Connect"}
|
||||||
@@ -202,7 +212,6 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
|
|||||||
sample data, query.
|
sample data, query.
|
||||||
</TeachingBubble>
|
</TeachingBubble>
|
||||||
)}
|
)}
|
||||||
{/*TODO: convert below to use SplashScreenButton */}
|
|
||||||
{mainItems.map((item) => (
|
{mainItems.map((item) => (
|
||||||
<Stack
|
<Stack
|
||||||
id={`mainButton-${item.id}`}
|
id={`mainButton-${item.id}`}
|
||||||
@@ -468,34 +477,6 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Re-enable lint rule when query copilot is reinstated in DE
|
|
||||||
/* eslint-disable-next-line no-unused-vars */
|
|
||||||
private getQueryCopilotCard = (): JSX.Element => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{useQueryCopilot.getState().copilotEnabled && (
|
|
||||||
<SplashScreenButton
|
|
||||||
imgSrc={CopilotIcon}
|
|
||||||
title={"Query faster with Query Advisor"}
|
|
||||||
description={
|
|
||||||
"Query Advisor is your AI buddy that helps you write Azure Cosmos DB queries like a pro. Try it using our sample data set now!"
|
|
||||||
}
|
|
||||||
onClick={() => {
|
|
||||||
const copilotVersion = userContext.features.copilotVersion;
|
|
||||||
if (copilotVersion === "v1.0") {
|
|
||||||
useTabs.getState().openAndActivateReactTab(ReactTabKind.QueryCopilot);
|
|
||||||
} else if (copilotVersion === "v2.0") {
|
|
||||||
const sampleCollection = useDatabases.getState().sampleDataResourceTokenCollection;
|
|
||||||
sampleCollection.onNewQueryClick(sampleCollection, undefined);
|
|
||||||
}
|
|
||||||
traceOpen(Action.OpenQueryCopilotFromSplashScreen, { apiType: userContext.apiType });
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
private decorateOpenCollectionActivity({ databaseId, collectionId }: MostRecentActivity.OpenCollectionItem) {
|
private decorateOpenCollectionActivity({ databaseId, collectionId }: MostRecentActivity.OpenCollectionItem) {
|
||||||
return {
|
return {
|
||||||
iconSrc: CollectionIcon,
|
iconSrc: CollectionIcon,
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ interface SplashScreenButtonProps {
|
|||||||
title: string;
|
title: string;
|
||||||
description: string;
|
description: string;
|
||||||
onClick: () => void;
|
onClick: () => void;
|
||||||
imgSize?: number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SplashScreenButton: React.FC<SplashScreenButtonProps> = ({
|
export const SplashScreenButton: React.FC<SplashScreenButtonProps> = ({
|
||||||
@@ -15,7 +14,6 @@ export const SplashScreenButton: React.FC<SplashScreenButtonProps> = ({
|
|||||||
title,
|
title,
|
||||||
description,
|
description,
|
||||||
onClick,
|
onClick,
|
||||||
imgSize,
|
|
||||||
}: SplashScreenButtonProps): JSX.Element => {
|
}: SplashScreenButtonProps): JSX.Element => {
|
||||||
return (
|
return (
|
||||||
<Stack
|
<Stack
|
||||||
@@ -41,7 +39,7 @@ export const SplashScreenButton: React.FC<SplashScreenButtonProps> = ({
|
|||||||
role="button"
|
role="button"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<img src={imgSrc} alt={title} aria-hidden="true" {...(imgSize ? { height: imgSize, width: imgSize } : {})} />
|
<img src={imgSrc} alt={title} aria-hidden="true" />
|
||||||
</div>
|
</div>
|
||||||
<Stack style={{ marginLeft: 16 }}>
|
<Stack style={{ marginLeft: 16 }}>
|
||||||
<Text style={{ fontSize: 18, fontWeight: 600 }}>{title}</Text>
|
<Text style={{ fontSize: 18, fontWeight: 600 }}>{title}</Text>
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import { formatErrorMessage, formatInfoMessage, formatWarningMessage } from "./U
|
|||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
const DEFAULT_CLOUDSHELL_REGION = "westus";
|
const DEFAULT_CLOUDSHELL_REGION = "westus";
|
||||||
const DEFAULT_FAIRFAX_CLOUDSHELL_REGION = "usgovvirginia";
|
|
||||||
const POLLING_INTERVAL_MS = 2000;
|
const POLLING_INTERVAL_MS = 2000;
|
||||||
const MAX_RETRY_COUNT = 10;
|
const MAX_RETRY_COUNT = 10;
|
||||||
const MAX_PING_COUNT = 120 * 60; // 120 minutes (60 seconds/minute)
|
const MAX_PING_COUNT = 120 * 60; // 120 minutes (60 seconds/minute)
|
||||||
@@ -154,9 +153,7 @@ export const ensureCloudShellProviderRegistered = async (): Promise<void> => {
|
|||||||
* Determines the appropriate CloudShell region
|
* Determines the appropriate CloudShell region
|
||||||
*/
|
*/
|
||||||
export const determineCloudShellRegion = (): string => {
|
export const determineCloudShellRegion = (): string => {
|
||||||
const defaultRegion =
|
return getNormalizedRegion(userContext.databaseAccount?.location, DEFAULT_CLOUDSHELL_REGION);
|
||||||
userContext.portalEnv === "fairfax" ? DEFAULT_FAIRFAX_CLOUDSHELL_REGION : DEFAULT_CLOUDSHELL_REGION;
|
|
||||||
return getNormalizedRegion(userContext.databaseAccount?.location, defaultRegion);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ jest.mock("../../../../UserContext", () => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock("../Utils/CommonUtils", () => ({
|
jest.mock("../Utils/CommonUtils", () => ({
|
||||||
...jest.requireActual("../Utils/CommonUtils"),
|
|
||||||
getHostFromUrl: jest.fn().mockReturnValue("test-mongo.documents.azure.com"),
|
getHostFromUrl: jest.fn().mockReturnValue("test-mongo.documents.azure.com"),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -125,10 +124,7 @@ describe("MongoShellHandler", () => {
|
|||||||
|
|
||||||
describe("getTerminalSuppressedData", () => {
|
describe("getTerminalSuppressedData", () => {
|
||||||
it("should return the correct warning message", () => {
|
it("should return the correct warning message", () => {
|
||||||
expect(mongoShellHandler.getTerminalSuppressedData()).toEqual([
|
expect(mongoShellHandler.getTerminalSuppressedData()).toEqual(["Warning: Non-Genuine MongoDB Detected"]);
|
||||||
"Warning: Non-Genuine MongoDB Detected",
|
|
||||||
"Telemetry is now disabled.",
|
|
||||||
]);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import { userContext } from "../../../../UserContext";
|
import { userContext } from "../../../../UserContext";
|
||||||
import { filterAndCleanTerminalOutput, getHostFromUrl, getMongoShellRemoveInfoText } from "../Utils/CommonUtils";
|
import { getHostFromUrl } from "../Utils/CommonUtils";
|
||||||
import { AbstractShellHandler, DISABLE_TELEMETRY_COMMAND } from "./AbstractShellHandler";
|
import { AbstractShellHandler, DISABLE_TELEMETRY_COMMAND } from "./AbstractShellHandler";
|
||||||
|
|
||||||
export class MongoShellHandler extends AbstractShellHandler {
|
export class MongoShellHandler extends AbstractShellHandler {
|
||||||
private _key: string;
|
private _key: string;
|
||||||
private _endpoint: string | undefined;
|
private _endpoint: string | undefined;
|
||||||
private _removeInfoText: string[] = getMongoShellRemoveInfoText();
|
|
||||||
constructor(private key: string) {
|
constructor(private key: string) {
|
||||||
super();
|
super();
|
||||||
this._key = key;
|
this._key = key;
|
||||||
@@ -45,10 +44,6 @@ export class MongoShellHandler extends AbstractShellHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public getTerminalSuppressedData(): string[] {
|
public getTerminalSuppressedData(): string[] {
|
||||||
return ["Warning: Non-Genuine MongoDB Detected", "Telemetry is now disabled."];
|
return ["Warning: Non-Genuine MongoDB Detected"];
|
||||||
}
|
|
||||||
|
|
||||||
updateTerminalData(data: string): string {
|
|
||||||
return filterAndCleanTerminalOutput(data, this._removeInfoText);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
import { userContext } from "../../../../UserContext";
|
import { userContext } from "../../../../UserContext";
|
||||||
import { filterAndCleanTerminalOutput, getMongoShellRemoveInfoText } from "../Utils/CommonUtils";
|
|
||||||
import { AbstractShellHandler, DISABLE_TELEMETRY_COMMAND } from "./AbstractShellHandler";
|
import { AbstractShellHandler, DISABLE_TELEMETRY_COMMAND } from "./AbstractShellHandler";
|
||||||
|
|
||||||
export class VCoreMongoShellHandler extends AbstractShellHandler {
|
export class VCoreMongoShellHandler extends AbstractShellHandler {
|
||||||
private _endpoint: string | undefined;
|
private _endpoint: string | undefined;
|
||||||
private _removeInfoText: string[] = getMongoShellRemoveInfoText();
|
private _textFilterRules: string[] = [
|
||||||
|
"For mongosh info see: https://www.mongodb.com/docs/mongodb-shell/",
|
||||||
|
"disableTelemetry() command",
|
||||||
|
"https://www.mongodb.com/legal/privacy-policy",
|
||||||
|
];
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
@@ -35,7 +38,12 @@ export class VCoreMongoShellHandler extends AbstractShellHandler {
|
|||||||
return ["Warning: Non-Genuine MongoDB Detected", "Telemetry is now disabled."];
|
return ["Warning: Non-Genuine MongoDB Detected", "Telemetry is now disabled."];
|
||||||
}
|
}
|
||||||
|
|
||||||
updateTerminalData(data: string): string {
|
updateTerminalData(content: string): string {
|
||||||
return filterAndCleanTerminalOutput(data, this._removeInfoText);
|
const updatedContent = content
|
||||||
|
.split("\n")
|
||||||
|
.filter((line) => !this._textFilterRules.some((part) => line.includes(part)))
|
||||||
|
.filter((line, idx, arr) => (arr.length > 3 && idx <= arr.length - 3 ? !["", "\r"].includes(line) : true)) // Filter out empty lines and carriage returns, but keep the last 3 lines if they exist
|
||||||
|
.join("\n");
|
||||||
|
return updatedContent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,11 +135,7 @@ export class AttachAddon implements ITerminalAddon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this._allowTerminalWrite) {
|
if (this._allowTerminalWrite) {
|
||||||
const updatedData =
|
const updatedData = this._shellHandler?.updateTerminalData(data) ?? data;
|
||||||
typeof this._shellHandler?.updateTerminalData === "function"
|
|
||||||
? this._shellHandler.updateTerminalData(data)
|
|
||||||
: data;
|
|
||||||
|
|
||||||
const suppressedData = this._shellHandler?.getTerminalSuppressedData();
|
const suppressedData = this._shellHandler?.getTerminalSuppressedData();
|
||||||
|
|
||||||
const shouldNotWrite = suppressedData.filter(Boolean).some((item) => updatedData.includes(item));
|
const shouldNotWrite = suppressedData.filter(Boolean).some((item) => updatedData.includes(item));
|
||||||
|
|||||||
@@ -50,34 +50,3 @@ export const getShellNameForDisplay = (terminalKind: TerminalKind): string => {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Get MongoDB shell information text that should be removed from terminal output
|
|
||||||
*/
|
|
||||||
export const getMongoShellRemoveInfoText = (): string[] => {
|
|
||||||
return [
|
|
||||||
"For mongosh info see: https://www.mongodb.com/docs/mongodb-shell/",
|
|
||||||
"disableTelemetry() command",
|
|
||||||
"https://www.mongodb.com/legal/privacy-policy",
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
export const filterAndCleanTerminalOutput = (data: string, removeInfoText: string[]): string => {
|
|
||||||
if (!data || removeInfoText.length === 0) {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
const lines = data.split("\n");
|
|
||||||
const filteredLines: string[] = [];
|
|
||||||
|
|
||||||
for (let i = 0; i < lines.length; i++) {
|
|
||||||
const line = lines[i];
|
|
||||||
const shouldRemove = removeInfoText.some((text) => line.includes(text));
|
|
||||||
|
|
||||||
if (!shouldRemove) {
|
|
||||||
filteredLines.push(line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return filteredLines.join("\n").replace(/((\r\n)|\n|\r){2,}/g, "\r\n");
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ const validCloudShellRegions = new Set([
|
|||||||
"centralindia",
|
"centralindia",
|
||||||
"southeastasia",
|
"southeastasia",
|
||||||
"westcentralus",
|
"westcentralus",
|
||||||
"usgovvirginia",
|
|
||||||
"usgovarizona",
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -106,6 +106,6 @@ describe("QueryTabComponent", () => {
|
|||||||
<QueryTabCopilotComponent {...propsMock} />
|
<QueryTabCopilotComponent {...propsMock} />
|
||||||
</CopilotProvider>,
|
</CopilotProvider>,
|
||||||
);
|
);
|
||||||
expect(container.find(QueryCopilotPromptbar).exists()).toBe(false);
|
expect(container.find(QueryCopilotPromptbar).exists()).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { useDialog } from "Explorer/Controls/Dialog";
|
|||||||
import { monaco } from "Explorer/LazyMonaco";
|
import { monaco } from "Explorer/LazyMonaco";
|
||||||
import { QueryCopilotFeedbackModal } from "Explorer/QueryCopilot/Modal/QueryCopilotFeedbackModal";
|
import { QueryCopilotFeedbackModal } from "Explorer/QueryCopilot/Modal/QueryCopilotFeedbackModal";
|
||||||
import { useCopilotStore } from "Explorer/QueryCopilot/QueryCopilotContext";
|
import { useCopilotStore } from "Explorer/QueryCopilot/QueryCopilotContext";
|
||||||
|
import { QueryCopilotPromptbar } from "Explorer/QueryCopilot/QueryCopilotPromptbar";
|
||||||
import { readCopilotToggleStatus, saveCopilotToggleStatus } from "Explorer/QueryCopilot/QueryCopilotUtilities";
|
import { readCopilotToggleStatus, saveCopilotToggleStatus } from "Explorer/QueryCopilot/QueryCopilotUtilities";
|
||||||
import { OnExecuteQueryClick, QueryDocumentsPerPage } from "Explorer/QueryCopilot/Shared/QueryCopilotClient";
|
import { OnExecuteQueryClick, QueryDocumentsPerPage } from "Explorer/QueryCopilot/Shared/QueryCopilotClient";
|
||||||
import { QueryCopilotSidebar } from "Explorer/QueryCopilot/V2/Sidebar/QueryCopilotSidebar";
|
import { QueryCopilotSidebar } from "Explorer/QueryCopilot/V2/Sidebar/QueryCopilotSidebar";
|
||||||
@@ -27,9 +28,8 @@ import { TabsState, useTabs } from "hooks/useTabs";
|
|||||||
import React, { Fragment, createRef } from "react";
|
import React, { Fragment, createRef } from "react";
|
||||||
import "react-splitter-layout/lib/index.css";
|
import "react-splitter-layout/lib/index.css";
|
||||||
import { format } from "react-string-format";
|
import { format } from "react-string-format";
|
||||||
//TODO: Uncomment next two lines when query copilot is reinstated in DE
|
import QueryCommandIcon from "../../../../images/CopilotCommand.svg";
|
||||||
// import QueryCommandIcon from "../../../../images/CopilotCommand.svg";
|
import LaunchCopilot from "../../../../images/CopilotTabIcon.svg";
|
||||||
// import LaunchCopilot from "../../../../images/CopilotTabIcon.svg";
|
|
||||||
import DownloadQueryIcon from "../../../../images/DownloadQuery.svg";
|
import DownloadQueryIcon from "../../../../images/DownloadQuery.svg";
|
||||||
import CancelQueryIcon from "../../../../images/Entity_cancel.svg";
|
import CancelQueryIcon from "../../../../images/Entity_cancel.svg";
|
||||||
import ExecuteQueryIcon from "../../../../images/ExecuteQuery.svg";
|
import ExecuteQueryIcon from "../../../../images/ExecuteQuery.svg";
|
||||||
@@ -494,55 +494,53 @@ class QueryTabComponentImpl extends React.Component<QueryTabComponentImplProps,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Uncomment next section when query copilot is reinstated in DE
|
if (this.launchCopilotButton.visible && this.isCopilotTabActive) {
|
||||||
// if (this.launchCopilotButton.visible && this.isCopilotTabActive) {
|
const mainButtonLabel = "Launch Copilot";
|
||||||
// const mainButtonLabel = "Launch Copilot";
|
const chatPaneLabel = "Open Copilot in chat pane (ALT+C)";
|
||||||
// const chatPaneLabel = "Open Copilot in chat pane (ALT+C)";
|
const copilotSettingLabel = "Copilot settings";
|
||||||
// const copilotSettingLabel = "Copilot settings";
|
|
||||||
|
|
||||||
// const openCopilotChatButton: CommandButtonComponentProps = {
|
const openCopilotChatButton: CommandButtonComponentProps = {
|
||||||
// iconAlt: chatPaneLabel,
|
iconAlt: chatPaneLabel,
|
||||||
// onCommandClick: this.launchQueryCopilotChat,
|
onCommandClick: this.launchQueryCopilotChat,
|
||||||
// commandButtonLabel: chatPaneLabel,
|
commandButtonLabel: chatPaneLabel,
|
||||||
// ariaLabel: chatPaneLabel,
|
ariaLabel: chatPaneLabel,
|
||||||
// hasPopup: false,
|
hasPopup: false,
|
||||||
// };
|
};
|
||||||
|
|
||||||
// const copilotSettingsButton: CommandButtonComponentProps = {
|
const copilotSettingsButton: CommandButtonComponentProps = {
|
||||||
// iconAlt: copilotSettingLabel,
|
iconAlt: copilotSettingLabel,
|
||||||
// onCommandClick: () => undefined,
|
onCommandClick: () => undefined,
|
||||||
// commandButtonLabel: copilotSettingLabel,
|
commandButtonLabel: copilotSettingLabel,
|
||||||
// ariaLabel: copilotSettingLabel,
|
ariaLabel: copilotSettingLabel,
|
||||||
// hasPopup: false,
|
hasPopup: false,
|
||||||
// };
|
};
|
||||||
|
|
||||||
// const launchCopilotButton: CommandButtonComponentProps = {
|
const launchCopilotButton: CommandButtonComponentProps = {
|
||||||
// iconSrc: LaunchCopilot,
|
iconSrc: LaunchCopilot,
|
||||||
// iconAlt: mainButtonLabel,
|
iconAlt: mainButtonLabel,
|
||||||
// onCommandClick: this.launchQueryCopilotChat,
|
onCommandClick: this.launchQueryCopilotChat,
|
||||||
// commandButtonLabel: mainButtonLabel,
|
commandButtonLabel: mainButtonLabel,
|
||||||
// ariaLabel: mainButtonLabel,
|
ariaLabel: mainButtonLabel,
|
||||||
// hasPopup: false,
|
hasPopup: false,
|
||||||
// children: [openCopilotChatButton, copilotSettingsButton],
|
children: [openCopilotChatButton, copilotSettingsButton],
|
||||||
// };
|
};
|
||||||
// buttons.push(launchCopilotButton);
|
buttons.push(launchCopilotButton);
|
||||||
// }
|
}
|
||||||
|
|
||||||
//TODO: Uncomment next section when query copilot is reinstated in DE
|
if (this.props.copilotEnabled) {
|
||||||
// if (this.props.copilotEnabled) {
|
const toggleCopilotButton: CommandButtonComponentProps = {
|
||||||
// const toggleCopilotButton: CommandButtonComponentProps = {
|
iconSrc: QueryCommandIcon,
|
||||||
// iconSrc: QueryCommandIcon,
|
iconAlt: "Query Advisor",
|
||||||
// iconAlt: "Query Advisor",
|
keyboardAction: KeyboardAction.TOGGLE_COPILOT,
|
||||||
// keyboardAction: KeyboardAction.TOGGLE_COPILOT,
|
onCommandClick: () => {
|
||||||
// onCommandClick: () => {
|
this._toggleCopilot(!this.state.copilotActive);
|
||||||
// this._toggleCopilot(!this.state.copilotActive);
|
},
|
||||||
// },
|
commandButtonLabel: this.state.copilotActive ? "Disable Query Advisor" : "Enable Query Advisor",
|
||||||
// commandButtonLabel: this.state.copilotActive ? "Disable Query Advisor" : "Enable Query Advisor",
|
ariaLabel: this.state.copilotActive ? "Disable Query Advisor" : "Enable Query Advisor",
|
||||||
// ariaLabel: this.state.copilotActive ? "Disable Query Advisor" : "Enable Query Advisor",
|
hasPopup: false,
|
||||||
// hasPopup: false,
|
};
|
||||||
// };
|
buttons.push(toggleCopilotButton);
|
||||||
// buttons.push(toggleCopilotButton);
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
if (!this.props.isPreferredApiMongoDB && this.state.isExecuting) {
|
if (!this.props.isPreferredApiMongoDB && this.state.isExecuting) {
|
||||||
const label = "Cancel query";
|
const label = "Cancel query";
|
||||||
@@ -727,7 +725,6 @@ class QueryTabComponentImpl extends React.Component<QueryTabComponentImplProps,
|
|||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<CosmosFluentProvider id={this.props.tabId} className={this.props.styles.queryTab} role="tabpanel">
|
<CosmosFluentProvider id={this.props.tabId} className={this.props.styles.queryTab} role="tabpanel">
|
||||||
{/*TODO: Uncomment this section when query copilot is reinstated in DE
|
|
||||||
{this.props.copilotEnabled && this.state.currentTabActive && this.state.copilotActive && (
|
{this.props.copilotEnabled && this.state.currentTabActive && this.state.copilotActive && (
|
||||||
<QueryCopilotPromptbar
|
<QueryCopilotPromptbar
|
||||||
explorer={this.props.collection.container}
|
explorer={this.props.collection.container}
|
||||||
@@ -735,7 +732,7 @@ class QueryTabComponentImpl extends React.Component<QueryTabComponentImplProps,
|
|||||||
databaseId={this.props.collection.databaseId}
|
databaseId={this.props.collection.databaseId}
|
||||||
containerId={this.props.collection.id()}
|
containerId={this.props.collection.id()}
|
||||||
></QueryCopilotPromptbar>
|
></QueryCopilotPromptbar>
|
||||||
)} */}
|
)}
|
||||||
{/* Set 'key' to the value of vertical to force re-rendering when vertical changes, to work around https://github.com/johnwalley/allotment/issues/457 */}
|
{/* Set 'key' to the value of vertical to force re-rendering when vertical changes, to work around https://github.com/johnwalley/allotment/issues/457 */}
|
||||||
<Allotment
|
<Allotment
|
||||||
key={vertical.toString()}
|
key={vertical.toString()}
|
||||||
|
|||||||
@@ -21,7 +21,12 @@ import { useCommandBar } from "../Menus/CommandBar/CommandBarComponentAdapter";
|
|||||||
import { useSelectedNode } from "../useSelectedNode";
|
import { useSelectedNode } from "../useSelectedNode";
|
||||||
|
|
||||||
export const shouldShowScriptNodes = (): boolean => {
|
export const shouldShowScriptNodes = (): boolean => {
|
||||||
return !isFabric() && (userContext.apiType === "SQL" || userContext.apiType === "Gremlin");
|
return (
|
||||||
|
!isFabric() &&
|
||||||
|
configContext.platform !== Platform.Emulator &&
|
||||||
|
configContext.platform !== Platform.VNextEmulator &&
|
||||||
|
(userContext.apiType === "SQL" || userContext.apiType === "Gremlin")
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const TreeDatabaseIcon = <DatabaseRegular fontSize={16} />;
|
const TreeDatabaseIcon = <DatabaseRegular fontSize={16} />;
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { MongoGuidRepresentation } from "Common/Constants";
|
|
||||||
import { SplitterDirection } from "Common/Splitter";
|
import { SplitterDirection } from "Common/Splitter";
|
||||||
import * as LocalStorageUtility from "./LocalStorageUtility";
|
import * as LocalStorageUtility from "./LocalStorageUtility";
|
||||||
import * as SessionStorageUtility from "./SessionStorageUtility";
|
import * as SessionStorageUtility from "./SessionStorageUtility";
|
||||||
@@ -34,7 +33,6 @@ export enum StorageKey {
|
|||||||
DocumentsTabPrefs,
|
DocumentsTabPrefs,
|
||||||
DefaultQueryResultsView,
|
DefaultQueryResultsView,
|
||||||
AppState,
|
AppState,
|
||||||
MongoGuidRepresentation,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const hasRUThresholdBeenConfigured = (): boolean => {
|
export const hasRUThresholdBeenConfigured = (): boolean => {
|
||||||
@@ -67,13 +65,4 @@ export const getDefaultQueryResultsView = (): SplitterDirection => {
|
|||||||
return SplitterDirection.Horizontal;
|
return SplitterDirection.Horizontal;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getMongoGuidRepresentation = (): MongoGuidRepresentation => {
|
|
||||||
const mongoGuidRepresentation: string | null = LocalStorageUtility.getEntryString(StorageKey.MongoGuidRepresentation);
|
|
||||||
if (mongoGuidRepresentation) {
|
|
||||||
return mongoGuidRepresentation as MongoGuidRepresentation;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MongoGuidRepresentation.CSharpLegacy;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const DefaultRUThreshold = 5000;
|
export const DefaultRUThreshold = 5000;
|
||||||
|
|||||||
@@ -79,7 +79,22 @@ export const defaultAllowedCassandraProxyEndpoints: ReadonlyArray<string> = [
|
|||||||
CassandraProxyEndpoints.Mooncake,
|
CassandraProxyEndpoints.Mooncake,
|
||||||
];
|
];
|
||||||
|
|
||||||
export const allowedEmulatorEndpoints: ReadonlyArray<string> = ["https://localhost:8081"];
|
export const allowedCassandraProxyEndpoints_ToBeDeprecated: ReadonlyArray<string> = [
|
||||||
|
"https://main.documentdb.ext.azure.com",
|
||||||
|
"https://main.documentdb.ext.azure.cn",
|
||||||
|
"https://main.documentdb.ext.azure.us",
|
||||||
|
"https://main.cosmos.ext.azure",
|
||||||
|
"https://localhost:12901",
|
||||||
|
];
|
||||||
|
|
||||||
|
export const CassandraProxyOutboundIPs: { [key: string]: string[] } = {
|
||||||
|
[CassandraProxyEndpoints.Mpac]: ["40.113.96.14", "104.42.11.145"],
|
||||||
|
[CassandraProxyEndpoints.Prod]: ["137.117.230.240", "168.61.72.237"],
|
||||||
|
[CassandraProxyEndpoints.Fairfax]: ["52.244.50.101", "52.227.165.24"],
|
||||||
|
[CassandraProxyEndpoints.Mooncake]: ["40.73.99.146", "143.64.62.47"],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const allowedEmulatorEndpoints: ReadonlyArray<string> = ["https://localhost:8081", "http://localhost:8081"];
|
||||||
|
|
||||||
export const allowedArcadiaEndpoints: ReadonlyArray<string> = ["https://workspaceartifacts.projectarcadia.net"];
|
export const allowedArcadiaEndpoints: ReadonlyArray<string> = ["https://workspaceartifacts.projectarcadia.net"];
|
||||||
|
|
||||||
|
|||||||
116
src/Utils/PlatformFeatureUtils.ts
Normal file
116
src/Utils/PlatformFeatureUtils.ts
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
import { Platform, configContext } from "../ConfigContext";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Feature flags enumeration - centralized feature definitions
|
||||||
|
*/
|
||||||
|
export enum PlatformFeature {
|
||||||
|
// UI/Core Features
|
||||||
|
Queries = "Queries",
|
||||||
|
Notebooks = "Notebooks",
|
||||||
|
SynapseLink = "SynapseLink",
|
||||||
|
VSCodeIntegration = "VSCodeIntegration",
|
||||||
|
GlobalSecondaryIndex = "GlobalSecondaryIndex",
|
||||||
|
DataPlaneRbac = "DataPlaneRbac",
|
||||||
|
EntraIDLogin = "EntraIDLogin",
|
||||||
|
EntreIDRbac = "EntreIDRbac",
|
||||||
|
RetrySettings = "RetrySettings",
|
||||||
|
GraphAutoVizOption = "GraphAutoVizOption",
|
||||||
|
CrossPartitionOption = "CrossPartitionOption",
|
||||||
|
EnhancedQueryControl = "EnhancedQueryControl",
|
||||||
|
ParallelismOption = "ParallelismOption",
|
||||||
|
EnableEntraIdRbac = "EnableEntraIdRbac",
|
||||||
|
PriorityBasedExecution = "PriorityBasedExecution",
|
||||||
|
RegionSelection = "RegionSelection",
|
||||||
|
Copilot = "Copilot",
|
||||||
|
CloudShell = "CloudShell",
|
||||||
|
ContainerPagination = "ContainerPagination",
|
||||||
|
FullTextSearch = "FullTextSearch",
|
||||||
|
VectorSearch = "VectorSearch",
|
||||||
|
ThroughputBucketing = "ThroughputBucketing",
|
||||||
|
ComputedProperties = "ComputedProperties",
|
||||||
|
AnalyticalStore = "AnalyticalStore",
|
||||||
|
UniqueKeys = "UniqueKeys",
|
||||||
|
ContainerThroughput = "ContainerThroughput",
|
||||||
|
AdvancedContainerSettings = "AdvancedContainerSettings",
|
||||||
|
|
||||||
|
// CRUD Operations - Database
|
||||||
|
CreateDatabase = "CreateDatabase",
|
||||||
|
ReadDatabase = "ReadDatabase",
|
||||||
|
DeleteDatabase = "DeleteDatabase",
|
||||||
|
|
||||||
|
// CRUD Operations - Collection
|
||||||
|
CreateCollection = "CreateCollection",
|
||||||
|
ReadCollection = "ReadCollection",
|
||||||
|
UpdateCollection = "UpdateCollection",
|
||||||
|
DeleteCollection = "DeleteCollection",
|
||||||
|
|
||||||
|
// CRUD Operations - Document
|
||||||
|
CreateDocument = "CreateDocument",
|
||||||
|
ReadDocument = "ReadDocument",
|
||||||
|
UpdateDocument = "UpdateDocument",
|
||||||
|
DeleteDocument = "DeleteDocument",
|
||||||
|
|
||||||
|
// Advanced Database Features
|
||||||
|
StoredProcedures = "StoredProcedures",
|
||||||
|
UDF = "UDF",
|
||||||
|
Trigger = "Trigger",
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Feature matrix per platform.
|
||||||
|
* - Only list platforms that have restrictions. If a platform is not present, all features are considered supported.
|
||||||
|
* - Start with VNextEmulator today; add more platforms/flags here later without touching calling code.
|
||||||
|
*/
|
||||||
|
const FEATURE_MATRIX: ReadonlyMap<Platform, ReadonlySet<PlatformFeature>> = new Map([
|
||||||
|
[
|
||||||
|
Platform.VNextEmulator,
|
||||||
|
new Set<PlatformFeature>([
|
||||||
|
PlatformFeature.Queries,
|
||||||
|
PlatformFeature.UniqueKeys,
|
||||||
|
|
||||||
|
PlatformFeature.CreateDatabase,
|
||||||
|
PlatformFeature.ReadDatabase,
|
||||||
|
PlatformFeature.DeleteDatabase,
|
||||||
|
|
||||||
|
PlatformFeature.CreateCollection,
|
||||||
|
PlatformFeature.ReadCollection,
|
||||||
|
PlatformFeature.UpdateCollection,
|
||||||
|
PlatformFeature.DeleteCollection,
|
||||||
|
|
||||||
|
PlatformFeature.CreateDocument,
|
||||||
|
PlatformFeature.ReadDocument,
|
||||||
|
PlatformFeature.UpdateDocument,
|
||||||
|
PlatformFeature.DeleteDocument,
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Central feature flag function - checks if a feature is enabled for current platform
|
||||||
|
* @param feature The feature to check
|
||||||
|
* @param platform Optional platform override, defaults to current platform
|
||||||
|
* @returns True if the feature is enabled for the platform, false otherwise
|
||||||
|
*/
|
||||||
|
export const isFeatureSupported = (feature: PlatformFeature, platform?: Platform): boolean => {
|
||||||
|
const currentPlatform = platform ?? configContext.platform;
|
||||||
|
if (currentPlatform !== Platform.VNextEmulator) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// VNextEmulator: check from the feature matrix
|
||||||
|
const vnextFeatures = FEATURE_MATRIX.get(Platform.VNextEmulator);
|
||||||
|
return vnextFeatures?.has(feature) ?? false;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const areAdvancedScriptsSupported = (platform?: Platform): boolean => {
|
||||||
|
const currentPlatform = platform ?? configContext.platform;
|
||||||
|
if (currentPlatform !== Platform.VNextEmulator) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, require all script features to be enabled
|
||||||
|
return (
|
||||||
|
isFeatureSupported(PlatformFeature.StoredProcedures, currentPlatform) &&
|
||||||
|
isFeatureSupported(PlatformFeature.UDF, currentPlatform) &&
|
||||||
|
isFeatureSupported(PlatformFeature.Trigger, currentPlatform)
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import { PartitionKey, PartitionKeyDefinition } from "@azure/cosmos";
|
import { PartitionKey, PartitionKeyDefinition } from "@azure/cosmos";
|
||||||
|
import { configContext, Platform } from "ConfigContext";
|
||||||
import { getRUThreshold, ruThresholdEnabled } from "Shared/StorageUtility";
|
import { getRUThreshold, ruThresholdEnabled } from "Shared/StorageUtility";
|
||||||
import { userContext } from "UserContext";
|
import { userContext } from "UserContext";
|
||||||
import { logConsoleWarning } from "Utils/NotificationConsoleUtils";
|
import { logConsoleWarning } from "Utils/NotificationConsoleUtils";
|
||||||
@@ -66,7 +67,11 @@ export function buildDocumentsQueryPartitionProjections(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
const fullAccess = `${collectionAlias}${projectedProperty}`;
|
const fullAccess = `${collectionAlias}${projectedProperty}`;
|
||||||
if (!isSystemPartitionKey) {
|
if (
|
||||||
|
!isSystemPartitionKey &&
|
||||||
|
configContext.platform !== Platform.Emulator &&
|
||||||
|
configContext.platform !== Platform.VNextEmulator
|
||||||
|
) {
|
||||||
const wrappedProjection = `IIF(IS_DEFINED(${fullAccess}), ${fullAccess}, {})`;
|
const wrappedProjection = `IIF(IS_DEFINED(${fullAccess}), ${fullAccess}, {})`;
|
||||||
projections.push(wrappedProjection);
|
projections.push(wrappedProjection);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ export function useKnockoutExplorer(platform: Platform): Explorer {
|
|||||||
let explorer: Explorer;
|
let explorer: Explorer;
|
||||||
if (platform === Platform.Hosted) {
|
if (platform === Platform.Hosted) {
|
||||||
explorer = await configureHosted();
|
explorer = await configureHosted();
|
||||||
} else if (platform === Platform.Emulator) {
|
} else if (platform === Platform.Emulator || platform === Platform.VNextEmulator) {
|
||||||
explorer = configureEmulator();
|
explorer = configureEmulator();
|
||||||
} else if (platform === Platform.Portal) {
|
} else if (platform === Platform.Portal) {
|
||||||
explorer = await configurePortal();
|
explorer = await configurePortal();
|
||||||
|
|||||||
200
src/quickstart-sql-only-http.html
Normal file
200
src/quickstart-sql-only-http.html
Normal file
@@ -0,0 +1,200 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="height=device-height, width=device-width, initial-scale=1.0" />
|
||||||
|
|
||||||
|
<title>Azure Cosmos DB Emulator</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="divQuickStart">
|
||||||
|
<div class="Introlines">
|
||||||
|
<p class="Introline1">Congratulations! Your Azure Cosmos DB emulator is running.</p>
|
||||||
|
<p class="Introline2">Now, let's connect a sample app to it.</p>
|
||||||
|
<div id="divQuickStartConnections">
|
||||||
|
<p class="Introline2">URI</p>
|
||||||
|
<input type="text" class="codeblock" readonly="readonly" value="http://localhost:8081" />
|
||||||
|
<p class="Introline2">Primary Key</p>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
class="codeblock"
|
||||||
|
readonly="readonly"
|
||||||
|
value="C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
|
||||||
|
/>
|
||||||
|
<p class="Introline2">Primary Connection String</p>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
class="codeblock"
|
||||||
|
readonly="readonly"
|
||||||
|
value="AccountEndpoint=http://localhost:8081/;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<p class="Introline3"><b>Choose a platform</b></p>
|
||||||
|
</div>
|
||||||
|
<div class="container-fluid">
|
||||||
|
<ul class="nav nav-tabs qslevel">
|
||||||
|
<li class="active">
|
||||||
|
<a data-toggle="tab" href="#net">
|
||||||
|
<img class="qsmenuicons" src="../images/dotnet.png" alt=".NET" /> .NET
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a data-toggle="tab" href="#java"> <img class="qsmenuicons" src="../images/java.png" alt="Java" /> Java </a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a data-toggle="tab" href="#nodejs">
|
||||||
|
<img class="qsmenuicons" src="../images/nodejs.png" alt="Node.js" /> Node.js
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a data-toggle="tab" href="#python">
|
||||||
|
<img class="qsmenuicons" src="../images/python.png" alt="Python" /> Python
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a data-toggle="tab" href="#go"> <img class="qsmenuicons" src="../images/golang.svg" alt="Go" /> Go </a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a data-toggle="tab" href="#springboot">
|
||||||
|
<img class="qsmenuicons" src="../images/springboot.svg" alt="Spring Boot" /> Spring Boot
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="tab-content">
|
||||||
|
<div id="net" class="tab-pane fade in active">
|
||||||
|
<div class="sampleApp">
|
||||||
|
<div class="numbersize numbersizePadding">1</div>
|
||||||
|
<div class="numberheading">
|
||||||
|
Create a new .NET app
|
||||||
|
<p>
|
||||||
|
Follow this
|
||||||
|
<a href="https://learn.microsoft.com/azure/cosmos-db/nosql/quickstart-dotnet" target="_blank"
|
||||||
|
>tutorial
|
||||||
|
</a>
|
||||||
|
to create a new .NET app connected to Azure Cosmos DB.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="learn-more"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="java" class="tab-pane fade">
|
||||||
|
<div class="sampleApp">
|
||||||
|
<div class="numbersize numbersizePadding">1</div>
|
||||||
|
<div class="numberheading">
|
||||||
|
Create a new Java app
|
||||||
|
<p>
|
||||||
|
Follow this
|
||||||
|
<a href="https://learn.microsoft.com/azure/cosmos-db/nosql/quickstart-java" target="_blank"
|
||||||
|
>tutorial
|
||||||
|
</a>
|
||||||
|
to create a new Java app connected to Azure Cosmos DB.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="learn-more"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="nodejs" class="tab-pane fade">
|
||||||
|
<div class="sampleApp">
|
||||||
|
<div class="numbersize numbersizePadding">1</div>
|
||||||
|
<div class="numberheading">
|
||||||
|
Create a new Node.js app
|
||||||
|
<p>
|
||||||
|
Follow this
|
||||||
|
<a
|
||||||
|
href="https://learn.microsoft.com/azure/cosmos-db/nosql/quickstart-nodejs?pivots=programming-language-ts"
|
||||||
|
target="_blank"
|
||||||
|
>tutorial
|
||||||
|
</a>
|
||||||
|
to create a new Node.js app connected to Azure Cosmos DB.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="learn-more"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="python" class="tab-pane fade">
|
||||||
|
<div class="sampleApp">
|
||||||
|
<div class="numbersize numbersizePadding">1</div>
|
||||||
|
<div class="numberheading">
|
||||||
|
Create a new Python app
|
||||||
|
<p>
|
||||||
|
Follow this
|
||||||
|
<a href="https://aka.ms/cosmos-db-emulator/tutorial/python" target="_blank">tutorial</a>
|
||||||
|
to create a new Python app connected to Azure Cosmos DB.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="learn-more"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="go" class="tab-pane fade">
|
||||||
|
<div class="sampleApp">
|
||||||
|
<div class="numbersize numbersizePadding">1</div>
|
||||||
|
<div class="numberheading">
|
||||||
|
Create a new Go app
|
||||||
|
<p>
|
||||||
|
Follow this
|
||||||
|
<a href="https://learn.microsoft.com/azure/cosmos-db/nosql/quickstart-go" target="_blank">tutorial</a>
|
||||||
|
to create a new Go app connected to Azure Cosmos DB.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="learn-more"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="springboot" class="tab-pane fade">
|
||||||
|
<div class="sampleApp">
|
||||||
|
<div class="numbersize numbersizePadding">1</div>
|
||||||
|
<div class="numberheading">
|
||||||
|
Create a new Spring Boot app
|
||||||
|
<p>
|
||||||
|
Follow this
|
||||||
|
<a
|
||||||
|
href="https://learn.microsoft.com/azure/cosmos-db/nosql/tutorial-springboot-azure-kubernetes-service"
|
||||||
|
target="_blank"
|
||||||
|
>tutorial</a
|
||||||
|
>
|
||||||
|
to create a new Spring Boot app connected to Azure Cosmos DB.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="learn-more"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template id="learnMoreTpl">
|
||||||
|
<div class="app-block">
|
||||||
|
<div class="numbersize">2</div>
|
||||||
|
<div class="numberheading">
|
||||||
|
Learn more about Azure Cosmos DB
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="https://azurecosmosdb.github.io/gallery/?tags=example" target="_blank" class="atags"
|
||||||
|
>Code Samples</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li><a href="https://aka.ms/cosmos-db-emulator/docs" target="_blank" class="atags">Documentation</a></li>
|
||||||
|
<li><a href="https://aka.ms/cosmos-db-emulator/pricing" target="_blank" class="atags">Pricing</a></li>
|
||||||
|
<li>
|
||||||
|
<a href="https://cosmos.azure.com/capacitycalculator/" target="_blank" class="atags">Capacity planner</a>
|
||||||
|
</li>
|
||||||
|
<li><a href="https://aka.ms/cosmos-db-emulator/stackoverflow" target="_blank" class="atags">Forum</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.querySelectorAll(".learn-more").forEach((slot) => {
|
||||||
|
const node = document.getElementById("learnMoreTpl").content.cloneNode(true);
|
||||||
|
slot.appendChild(node);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
200
src/quickstart-sql-only.html
Normal file
200
src/quickstart-sql-only.html
Normal file
@@ -0,0 +1,200 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="height=device-height, width=device-width, initial-scale=1.0" />
|
||||||
|
|
||||||
|
<title>Azure Cosmos DB Emulator</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="divQuickStart">
|
||||||
|
<div class="Introlines">
|
||||||
|
<p class="Introline1">Congratulations! Your Azure Cosmos DB emulator is running.</p>
|
||||||
|
<p class="Introline2">Now, let's connect a sample app to it.</p>
|
||||||
|
<div id="divQuickStartConnections">
|
||||||
|
<p class="Introline2">URI</p>
|
||||||
|
<input type="text" class="codeblock" readonly="readonly" value="https://localhost:8081" />
|
||||||
|
<p class="Introline2">Primary Key</p>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
class="codeblock"
|
||||||
|
readonly="readonly"
|
||||||
|
value="C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
|
||||||
|
/>
|
||||||
|
<p class="Introline2">Primary Connection String</p>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
class="codeblock"
|
||||||
|
readonly="readonly"
|
||||||
|
value="AccountEndpoint=https://localhost:8081/;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<p class="Introline3"><b>Choose a platform</b></p>
|
||||||
|
</div>
|
||||||
|
<div class="container-fluid">
|
||||||
|
<ul class="nav nav-tabs qslevel">
|
||||||
|
<li class="active">
|
||||||
|
<a data-toggle="tab" href="#net">
|
||||||
|
<img class="qsmenuicons" src="../images/dotnet.png" alt=".NET" /> .NET
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a data-toggle="tab" href="#java"> <img class="qsmenuicons" src="../images/java.png" alt="Java" /> Java </a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a data-toggle="tab" href="#nodejs">
|
||||||
|
<img class="qsmenuicons" src="../images/nodejs.png" alt="Node.js" /> Node.js
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a data-toggle="tab" href="#python">
|
||||||
|
<img class="qsmenuicons" src="../images/python.png" alt="Python" /> Python
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a data-toggle="tab" href="#go"> <img class="qsmenuicons" src="../images/golang.svg" alt="Go" /> Go </a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a data-toggle="tab" href="#springboot">
|
||||||
|
<img class="qsmenuicons" src="../images/springboot.svg" alt="Spring Boot" /> Spring Boot
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="tab-content">
|
||||||
|
<div id="net" class="tab-pane fade in active">
|
||||||
|
<div class="sampleApp">
|
||||||
|
<div class="numbersize numbersizePadding">1</div>
|
||||||
|
<div class="numberheading">
|
||||||
|
Create a new .NET app
|
||||||
|
<p>
|
||||||
|
Follow this
|
||||||
|
<a href="https://learn.microsoft.com/azure/cosmos-db/nosql/quickstart-dotnet" target="_blank"
|
||||||
|
>tutorial
|
||||||
|
</a>
|
||||||
|
to create a new .NET app connected to Azure Cosmos DB.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="learn-more"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="java" class="tab-pane fade">
|
||||||
|
<div class="sampleApp">
|
||||||
|
<div class="numbersize numbersizePadding">1</div>
|
||||||
|
<div class="numberheading">
|
||||||
|
Create a new Java app
|
||||||
|
<p>
|
||||||
|
Follow this
|
||||||
|
<a href="https://learn.microsoft.com/azure/cosmos-db/nosql/quickstart-java" target="_blank"
|
||||||
|
>tutorial
|
||||||
|
</a>
|
||||||
|
to create a new Java app connected to Azure Cosmos DB.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="learn-more"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="nodejs" class="tab-pane fade">
|
||||||
|
<div class="sampleApp">
|
||||||
|
<div class="numbersize numbersizePadding">1</div>
|
||||||
|
<div class="numberheading">
|
||||||
|
Create a new Node.js app
|
||||||
|
<p>
|
||||||
|
Follow this
|
||||||
|
<a
|
||||||
|
href="https://learn.microsoft.com/azure/cosmos-db/nosql/quickstart-nodejs?pivots=programming-language-ts"
|
||||||
|
target="_blank"
|
||||||
|
>tutorial
|
||||||
|
</a>
|
||||||
|
to create a new Node.js app connected to Azure Cosmos DB.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="learn-more"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="python" class="tab-pane fade">
|
||||||
|
<div class="sampleApp">
|
||||||
|
<div class="numbersize numbersizePadding">1</div>
|
||||||
|
<div class="numberheading">
|
||||||
|
Create a new Python app
|
||||||
|
<p>
|
||||||
|
Follow this
|
||||||
|
<a href="https://aka.ms/cosmos-db-emulator/tutorial/python" target="_blank">tutorial</a>
|
||||||
|
to create a new Python app connected to Azure Cosmos DB.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="learn-more"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="go" class="tab-pane fade">
|
||||||
|
<div class="sampleApp">
|
||||||
|
<div class="numbersize numbersizePadding">1</div>
|
||||||
|
<div class="numberheading">
|
||||||
|
Create a new Go app
|
||||||
|
<p>
|
||||||
|
Follow this
|
||||||
|
<a href="https://learn.microsoft.com/azure/cosmos-db/nosql/quickstart-go" target="_blank">tutorial</a>
|
||||||
|
to create a new Go app connected to Azure Cosmos DB.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="learn-more"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="springboot" class="tab-pane fade">
|
||||||
|
<div class="sampleApp">
|
||||||
|
<div class="numbersize numbersizePadding">1</div>
|
||||||
|
<div class="numberheading">
|
||||||
|
Create a new Spring Boot app
|
||||||
|
<p>
|
||||||
|
Follow this
|
||||||
|
<a
|
||||||
|
href="https://learn.microsoft.com/azure/cosmos-db/nosql/tutorial-springboot-azure-kubernetes-service"
|
||||||
|
target="_blank"
|
||||||
|
>tutorial</a
|
||||||
|
>
|
||||||
|
to create a new Spring Boot app connected to Azure Cosmos DB.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="learn-more"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template id="learnMoreTpl">
|
||||||
|
<div class="app-block">
|
||||||
|
<div class="numbersize">2</div>
|
||||||
|
<div class="numberheading">
|
||||||
|
Learn more about Azure Cosmos DB
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="https://azurecosmosdb.github.io/gallery/?tags=example" target="_blank" class="atags"
|
||||||
|
>Code Samples</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li><a href="https://aka.ms/cosmos-db-emulator/docs" target="_blank" class="atags">Documentation</a></li>
|
||||||
|
<li><a href="https://aka.ms/cosmos-db-emulator/pricing" target="_blank" class="atags">Pricing</a></li>
|
||||||
|
<li>
|
||||||
|
<a href="https://cosmos.azure.com/capacitycalculator/" target="_blank" class="atags">Capacity planner</a>
|
||||||
|
</li>
|
||||||
|
<li><a href="https://aka.ms/cosmos-db-emulator/stackoverflow" target="_blank" class="atags">Forum</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.querySelectorAll(".learn-more").forEach((slot) => {
|
||||||
|
const node = document.getElementById("learnMoreTpl").content.cloneNode(true);
|
||||||
|
slot.appendChild(node);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
179
src/quickstart-sql.template.ejs
Normal file
179
src/quickstart-sql.template.ejs
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="height=device-height, width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Azure Cosmos DB Emulator (SQL)</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="divQuickStart">
|
||||||
|
<div class="Introlines">
|
||||||
|
<p class="Introline1">Congratulations! Your Azure Cosmos DB emulator is running.</p>
|
||||||
|
<p class="Introline2">Now, let's connect a sample app to it.</p>
|
||||||
|
<div id="divQuickStartConnections">
|
||||||
|
<p class="Introline2">URI</p>
|
||||||
|
<input type="text" class="codeblock" readonly value="<%= endpointUri %>" />
|
||||||
|
<p class="Introline2">Primary Key</p>
|
||||||
|
<input type="text" class="codeblock" readonly value="<%= primaryKey %>" />
|
||||||
|
<p class="Introline2">Primary Connection String</p>
|
||||||
|
<input type="text" class="codeblock" readonly value="<%= primaryConnString %>" />
|
||||||
|
</div>
|
||||||
|
<p class="Introline3"><b>Choose a platform</b></p>
|
||||||
|
</div>
|
||||||
|
<div class="container-fluid">
|
||||||
|
<ul class="nav nav-tabs qslevel">
|
||||||
|
<li class="active">
|
||||||
|
<a data-toggle="tab" href="#net"> <img class="qsmenuicons" src="images/dotnet.png" alt=".NET" /> .NET </a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a data-toggle="tab" href="#java"><img class="qsmenuicons" src="images/java.png" alt="Java" /> Java</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a data-toggle="tab" href="#nodejs"
|
||||||
|
><img class="qsmenuicons" src="images/nodejs.png" alt="Node.js" /> Node.js</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a data-toggle="tab" href="#python"
|
||||||
|
><img class="qsmenuicons" src="images/python.png" alt="Python" /> Python</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a data-toggle="tab" href="#go"><img class="qsmenuicons" src="images/golang.svg" alt="Go" /> Go</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a data-toggle="tab" href="#springboot"
|
||||||
|
><img class="qsmenuicons" src="images/springboot.svg" alt="Spring Boot" /> Spring Boot</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="tab-content">
|
||||||
|
<div id="net" class="tab-pane fade in active">
|
||||||
|
<div class="sampleApp">
|
||||||
|
<div class="numbersize numbersizePadding">1</div>
|
||||||
|
<div class="numberheading">
|
||||||
|
Create a new .NET app
|
||||||
|
<p>
|
||||||
|
Follow this
|
||||||
|
<a href="https://learn.microsoft.com/azure/cosmos-db/nosql/quickstart-dotnet" target="_blank"
|
||||||
|
>tutorial</a
|
||||||
|
>
|
||||||
|
to create a new .NET app connected to Azure Cosmos DB.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="learn-more"></div>
|
||||||
|
</div>
|
||||||
|
<div id="java" class="tab-pane fade">
|
||||||
|
<div class="sampleApp">
|
||||||
|
<div class="numbersize numbersizePadding">1</div>
|
||||||
|
<div class="numberheading">
|
||||||
|
Create a new Java app
|
||||||
|
<p>
|
||||||
|
Follow this
|
||||||
|
<a href="https://learn.microsoft.com/azure/cosmos-db/nosql/quickstart-java" target="_blank"
|
||||||
|
>tutorial</a
|
||||||
|
>
|
||||||
|
to create a new Java app connected to Azure Cosmos DB.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="learn-more"></div>
|
||||||
|
</div>
|
||||||
|
<div id="nodejs" class="tab-pane fade">
|
||||||
|
<div class="sampleApp">
|
||||||
|
<div class="numbersize numbersizePadding">1</div>
|
||||||
|
<div class="numberheading">
|
||||||
|
Create a new Node.js app
|
||||||
|
<p>
|
||||||
|
Follow this
|
||||||
|
<a
|
||||||
|
href="https://learn.microsoft.com/azure/cosmos-db/nosql/quickstart-nodejs?pivots=programming-language-ts"
|
||||||
|
target="_blank"
|
||||||
|
>tutorial</a
|
||||||
|
>
|
||||||
|
to create a new Node.js app connected to Azure Cosmos DB.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="learn-more"></div>
|
||||||
|
</div>
|
||||||
|
<div id="python" class="tab-pane fade">
|
||||||
|
<div class="sampleApp">
|
||||||
|
<div class="numbersize numbersizePadding">1</div>
|
||||||
|
<div class="numberheading">
|
||||||
|
Create a new Python app
|
||||||
|
<p>
|
||||||
|
Follow this <a href="https://aka.ms/cosmos-db-emulator/tutorial/python" target="_blank">tutorial</a>
|
||||||
|
to create a new Python app connected to Azure Cosmos DB.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="learn-more"></div>
|
||||||
|
</div>
|
||||||
|
<div id="go" class="tab-pane fade">
|
||||||
|
<div class="sampleApp">
|
||||||
|
<div class="numbersize numbersizePadding">1</div>
|
||||||
|
<div class="numberheading">
|
||||||
|
Create a new Go app
|
||||||
|
<p>
|
||||||
|
Follow this
|
||||||
|
<a href="https://learn.microsoft.com/azure/cosmos-db/nosql/quickstart-go" target="_blank">tutorial</a>
|
||||||
|
to create a new Go app connected to Azure Cosmos DB.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="learn-more"></div>
|
||||||
|
</div>
|
||||||
|
<div id="springboot" class="tab-pane fade">
|
||||||
|
<div class="sampleApp">
|
||||||
|
<div class="numbersize numbersizePadding">1</div>
|
||||||
|
<div class="numberheading">
|
||||||
|
Create a new Spring Boot app
|
||||||
|
<p>
|
||||||
|
Follow this
|
||||||
|
<a
|
||||||
|
href="https://learn.microsoft.com/azure/cosmos-db/nosql/tutorial-springboot-azure-kubernetes-service"
|
||||||
|
target="_blank"
|
||||||
|
>tutorial</a
|
||||||
|
>
|
||||||
|
to create a new Spring Boot app connected to Azure Cosmos DB.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="learn-more"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template id="learnMoreTpl">
|
||||||
|
<div class="app-block">
|
||||||
|
<div class="numbersize">2</div>
|
||||||
|
<div class="numberheading">
|
||||||
|
Learn more about Azure Cosmos DB
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="https://azurecosmosdb.github.io/gallery/?tags=example" target="_blank" class="atags"
|
||||||
|
>Code Samples</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li><a href="https://aka.ms/cosmos-db-emulator/docs" target="_blank" class="atags">Documentation</a></li>
|
||||||
|
<li><a href="https://aka.ms/cosmos-db-emulator/pricing" target="_blank" class="atags">Pricing</a></li>
|
||||||
|
<li>
|
||||||
|
<a href="https://cosmos.azure.com/capacitycalculator/" target="_blank" class="atags">Capacity planner</a>
|
||||||
|
</li>
|
||||||
|
<li><a href="https://aka.ms/cosmos-db-emulator/stackoverflow" target="_blank" class="atags">Forum</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.querySelectorAll(".learn-more").forEach((slot) => {
|
||||||
|
const node = document.getElementById("learnMoreTpl").content.cloneNode(true);
|
||||||
|
slot.appendChild(node);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -15,18 +15,12 @@
|
|||||||
"target": "es2017",
|
"target": "es2017",
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"emitDecoratorMetadata": true,
|
"emitDecoratorMetadata": true,
|
||||||
"lib": [
|
"lib": ["es5", "es6", "dom"],
|
||||||
"es5",
|
|
||||||
"es6",
|
|
||||||
"dom"
|
|
||||||
],
|
|
||||||
"jsx": "react",
|
"jsx": "react",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"types": [
|
"types": ["jest"],
|
||||||
"jest"
|
|
||||||
],
|
|
||||||
"baseUrl": "src"
|
"baseUrl": "src"
|
||||||
},
|
},
|
||||||
"typedocOptions": {
|
"typedocOptions": {
|
||||||
@@ -43,17 +37,11 @@
|
|||||||
"includes": "./src/SelfServe/Documentation",
|
"includes": "./src/SelfServe/Documentation",
|
||||||
"disableSources": true
|
"disableSources": true
|
||||||
},
|
},
|
||||||
"include": [
|
"include": ["src", "./src/**/*", "./utils/**/*"],
|
||||||
"src",
|
"exclude": ["./src/**/__mocks__/**/*", "./utils/local-proxy/**/*"],
|
||||||
"./src/**/*",
|
|
||||||
"./utils/**/*"
|
|
||||||
],
|
|
||||||
"exclude": [
|
|
||||||
"./src/**/__mocks__/**/*"
|
|
||||||
],
|
|
||||||
"ts-node": {
|
"ts-node": {
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"module": "CommonJS"
|
"module": "CommonJS"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
6
utils/local-proxy/.gitignore
vendored
Normal file
6
utils/local-proxy/.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
dist*
|
||||||
|
node_modules
|
||||||
|
*.cert
|
||||||
|
*.key
|
||||||
|
*.pfx
|
||||||
|
*.log
|
||||||
177
utils/local-proxy/index.js
Normal file
177
utils/local-proxy/index.js
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
const express = require("express");
|
||||||
|
const { createProxyMiddleware } = require("http-proxy-middleware");
|
||||||
|
const { inspect } = require("util");
|
||||||
|
const fs = require("fs");
|
||||||
|
const https = require("https");
|
||||||
|
|
||||||
|
const conf = {};
|
||||||
|
conf.PORT = process.env.EXPLORER_PORT || 1234;
|
||||||
|
conf.LOG_LEVEL = process.env.LOG_LEVEL || "info";
|
||||||
|
conf.EMULATOR_ENDPOINT = process.env.EMULATOR_ENDPOINT || "http://localhost:8081";
|
||||||
|
conf.ENDPOINT_DISCOVERY_ENABLED = (process.env.ENDPOINT_DISCOVERY_ENABLED || "false").toLowerCase() === "true";
|
||||||
|
conf.GATEWAY_TLS_ENABLED = (process.env.GATEWAY_TLS_ENABLED || "false").toLowerCase() === "true";
|
||||||
|
conf.CERT_PATH = process.env.CERT_PATH;
|
||||||
|
conf.CERT_SECRET = process.env.CERT_SECRET;
|
||||||
|
|
||||||
|
const LOG_NUM = levelToNumber(conf.LOG_LEVEL);
|
||||||
|
function _log(level, msg, color) {
|
||||||
|
if (levelToNumber(level) >= LOG_NUM) {
|
||||||
|
console.log(`${colorToCode(color)}[${level || "debug"}]${msg}\x1b[0m`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _debug(msg, color) {
|
||||||
|
_log("debug", msg, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _info(msg, color) {
|
||||||
|
_log("info", msg, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _warn(msg, color) {
|
||||||
|
_log("warn", msg, color || "yellow");
|
||||||
|
}
|
||||||
|
|
||||||
|
function _err(msg, color) {
|
||||||
|
_log("error", msg, color || "red");
|
||||||
|
}
|
||||||
|
|
||||||
|
function levelToNumber(level) {
|
||||||
|
switch (level) {
|
||||||
|
case "debug":
|
||||||
|
return 0;
|
||||||
|
case "info":
|
||||||
|
return 1;
|
||||||
|
case "warn":
|
||||||
|
return 2;
|
||||||
|
case "error":
|
||||||
|
return 3;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function colorToCode(color) {
|
||||||
|
switch (color) {
|
||||||
|
case "red":
|
||||||
|
return "\x1b[31m";
|
||||||
|
case "green":
|
||||||
|
return "\x1b[32m";
|
||||||
|
case "blue":
|
||||||
|
return "\x1b[34m";
|
||||||
|
case "yellow":
|
||||||
|
return "\x1b[33m";
|
||||||
|
default:
|
||||||
|
return "\x1b[0m";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function statusToColor(status) {
|
||||||
|
if (status < 300) {
|
||||||
|
return "green";
|
||||||
|
} else if (status < 400) {
|
||||||
|
return "blue";
|
||||||
|
} else {
|
||||||
|
return "red";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const testEndpoint = () => {
|
||||||
|
fetch(conf.EMULATOR_ENDPOINT)
|
||||||
|
.then(async (res) => {
|
||||||
|
const body = await res.json();
|
||||||
|
_info("[EMU] Emulator is accessible");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
_warn("[EMU] Emulator is not accessible");
|
||||||
|
_warn(`[EMU] ${inspect(e)}`);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
testEndpoint();
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
|
||||||
|
app.use((e, req, res, next) => {
|
||||||
|
_err(`[APP] ${inspect(e)}`);
|
||||||
|
res.status(500).json({ error: _err.message });
|
||||||
|
});
|
||||||
|
|
||||||
|
app.use((req, res, next) => {
|
||||||
|
req.startTime = new Date();
|
||||||
|
res.append("Access-Control-Allow-Origin", "*");
|
||||||
|
res.append("Access-Control-Allow-Credentials", "true");
|
||||||
|
res.append("Access-Control-Max-Age", "3600");
|
||||||
|
res.append("Access-Control-Allow-Headers", "*");
|
||||||
|
res.append("Access-Control-Allow-Methods", "*");
|
||||||
|
res.once("finish", () => {
|
||||||
|
const ms = new Date() - req.startTime;
|
||||||
|
(res.statusCode < 400 ? _debug : _err)(
|
||||||
|
`[APP] ${req.method} ${req.url} ${res.statusCode} - ${ms}ms`,
|
||||||
|
statusToColor(res.statusCode),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/_ready", (_, res) => {
|
||||||
|
res.status(200).send("Compilation complete.");
|
||||||
|
});
|
||||||
|
|
||||||
|
const appConf = {
|
||||||
|
PROXY_PATH: "/proxy",
|
||||||
|
EMULATOR_ENDPOINT: conf.EMULATOR_ENDPOINT,
|
||||||
|
platform: "VNextEmulator",
|
||||||
|
};
|
||||||
|
app.get("/config.json", (_, res) => {
|
||||||
|
res.status(200).json(appConf).end();
|
||||||
|
});
|
||||||
|
|
||||||
|
const proxyProxy = createProxyMiddleware({
|
||||||
|
target: "https://cdb-ms-mpac-pbe.cosmos.azure.com",
|
||||||
|
changeOrigin: true,
|
||||||
|
secure: false,
|
||||||
|
logLevel: conf.LOG_LEVEL,
|
||||||
|
pathRewrite: { "^/proxy": "" },
|
||||||
|
router: (req) => {
|
||||||
|
if (conf.ENDPOINT_DISCOVERY_ENABLED) {
|
||||||
|
let newTarget = req.headers["x-ms-proxy-target"];
|
||||||
|
return newTarget;
|
||||||
|
} else {
|
||||||
|
return conf.EMULATOR_ENDPOINT;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
app.use("/proxy", proxyProxy);
|
||||||
|
|
||||||
|
const unsupported = (req, res) => {
|
||||||
|
res.status(404).send("Unexpected operation. Please create issue.");
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: andersonc - I don't believe these are needed for emulator, should confirm and remove.
|
||||||
|
app.use("/api", unsupported);
|
||||||
|
app.use("/_explorer", unsupported);
|
||||||
|
app.use("/explorerProxy", unsupported);
|
||||||
|
app.use(`/${conf.AZURE_TENANT_ID}`, unsupported);
|
||||||
|
|
||||||
|
app.use(express.static("dist"));
|
||||||
|
|
||||||
|
_info(`[EMU] Expecting emulator on [${conf.EMULATOR_ENDPOINT}]`);
|
||||||
|
_info(`[APP] Listening on [${conf.PORT}]`);
|
||||||
|
if (conf.GATEWAY_TLS_ENABLED) {
|
||||||
|
if (!conf.CERT_PATH || !conf.CERT_SECRET) {
|
||||||
|
_err("[APP] Certificate path or secret not provided");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
pfx: fs.readFileSync(conf.CERT_PATH),
|
||||||
|
passphrase: conf.CERT_SECRET,
|
||||||
|
};
|
||||||
|
|
||||||
|
const server = https.createServer(options, app);
|
||||||
|
server.listen(conf.PORT);
|
||||||
|
} else {
|
||||||
|
app.listen(conf.PORT);
|
||||||
|
}
|
||||||
1
utils/local-proxy/main.js
Normal file
1
utils/local-proxy/main.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
require('./index.js');
|
||||||
984
utils/local-proxy/package-lock.json
generated
Normal file
984
utils/local-proxy/package-lock.json
generated
Normal file
@@ -0,0 +1,984 @@
|
|||||||
|
{
|
||||||
|
"name": "local-proxy",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "local-proxy",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"express": "^4.21.1",
|
||||||
|
"http-proxy-middleware": "^3.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/http-proxy": {
|
||||||
|
"version": "1.17.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz",
|
||||||
|
"integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/node": {
|
||||||
|
"version": "22.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz",
|
||||||
|
"integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"undici-types": "~6.20.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/accepts": {
|
||||||
|
"version": "1.3.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
||||||
|
"integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"mime-types": "~2.1.34",
|
||||||
|
"negotiator": "0.6.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/array-flatten": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/body-parser": {
|
||||||
|
"version": "1.20.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
|
||||||
|
"integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"bytes": "3.1.2",
|
||||||
|
"content-type": "~1.0.5",
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"depd": "2.0.0",
|
||||||
|
"destroy": "1.2.0",
|
||||||
|
"http-errors": "2.0.0",
|
||||||
|
"iconv-lite": "0.4.24",
|
||||||
|
"on-finished": "2.4.1",
|
||||||
|
"qs": "6.13.0",
|
||||||
|
"raw-body": "2.5.2",
|
||||||
|
"type-is": "~1.6.18",
|
||||||
|
"unpipe": "1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8",
|
||||||
|
"npm": "1.2.8000 || >= 1.4.16"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/braces": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"fill-range": "^7.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/bytes": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/call-bind": {
|
||||||
|
"version": "1.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
|
||||||
|
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"es-define-property": "^1.0.0",
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"function-bind": "^1.1.2",
|
||||||
|
"get-intrinsic": "^1.2.4",
|
||||||
|
"set-function-length": "^1.2.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/content-disposition": {
|
||||||
|
"version": "0.5.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
|
||||||
|
"integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": "5.2.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/content-type": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
|
||||||
|
"integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cookie": {
|
||||||
|
"version": "0.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
|
||||||
|
"integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cookie-signature": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||||
|
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/debug": {
|
||||||
|
"version": "2.6.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||||
|
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/define-data-property": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"es-define-property": "^1.0.0",
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"gopd": "^1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/depd": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/destroy": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8",
|
||||||
|
"npm": "1.2.8000 || >= 1.4.16"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ee-first": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/encodeurl": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/es-define-property": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"get-intrinsic": "^1.2.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/es-errors": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/escape-html": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/etag": {
|
||||||
|
"version": "1.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
||||||
|
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eventemitter3": {
|
||||||
|
"version": "4.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
|
||||||
|
"integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/express": {
|
||||||
|
"version": "4.21.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz",
|
||||||
|
"integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"accepts": "~1.3.8",
|
||||||
|
"array-flatten": "1.1.1",
|
||||||
|
"body-parser": "1.20.3",
|
||||||
|
"content-disposition": "0.5.4",
|
||||||
|
"content-type": "~1.0.4",
|
||||||
|
"cookie": "0.7.1",
|
||||||
|
"cookie-signature": "1.0.6",
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"depd": "2.0.0",
|
||||||
|
"encodeurl": "~2.0.0",
|
||||||
|
"escape-html": "~1.0.3",
|
||||||
|
"etag": "~1.8.1",
|
||||||
|
"finalhandler": "1.3.1",
|
||||||
|
"fresh": "0.5.2",
|
||||||
|
"http-errors": "2.0.0",
|
||||||
|
"merge-descriptors": "1.0.3",
|
||||||
|
"methods": "~1.1.2",
|
||||||
|
"on-finished": "2.4.1",
|
||||||
|
"parseurl": "~1.3.3",
|
||||||
|
"path-to-regexp": "0.1.12",
|
||||||
|
"proxy-addr": "~2.0.7",
|
||||||
|
"qs": "6.13.0",
|
||||||
|
"range-parser": "~1.2.1",
|
||||||
|
"safe-buffer": "5.2.1",
|
||||||
|
"send": "0.19.0",
|
||||||
|
"serve-static": "1.16.2",
|
||||||
|
"setprototypeof": "1.2.0",
|
||||||
|
"statuses": "2.0.1",
|
||||||
|
"type-is": "~1.6.18",
|
||||||
|
"utils-merge": "1.0.1",
|
||||||
|
"vary": "~1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fill-range": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||||
|
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"to-regex-range": "^5.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/finalhandler": {
|
||||||
|
"version": "1.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
|
||||||
|
"integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"encodeurl": "~2.0.0",
|
||||||
|
"escape-html": "~1.0.3",
|
||||||
|
"on-finished": "2.4.1",
|
||||||
|
"parseurl": "~1.3.3",
|
||||||
|
"statuses": "2.0.1",
|
||||||
|
"unpipe": "~1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/follow-redirects": {
|
||||||
|
"version": "1.15.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
|
||||||
|
"integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "individual",
|
||||||
|
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"debug": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/forwarded": {
|
||||||
|
"version": "0.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
|
||||||
|
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fresh": {
|
||||||
|
"version": "0.5.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
||||||
|
"integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/function-bind": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/get-intrinsic": {
|
||||||
|
"version": "1.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
|
||||||
|
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"function-bind": "^1.1.2",
|
||||||
|
"has-proto": "^1.0.1",
|
||||||
|
"has-symbols": "^1.0.3",
|
||||||
|
"hasown": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/gopd": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"get-intrinsic": "^1.1.3"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/has-property-descriptors": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"es-define-property": "^1.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/has-proto": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/has-symbols": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/hasown": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"function-bind": "^1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/http-errors": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"depd": "2.0.0",
|
||||||
|
"inherits": "2.0.4",
|
||||||
|
"setprototypeof": "1.2.0",
|
||||||
|
"statuses": "2.0.1",
|
||||||
|
"toidentifier": "1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/http-proxy": {
|
||||||
|
"version": "1.18.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
|
||||||
|
"integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"eventemitter3": "^4.0.0",
|
||||||
|
"follow-redirects": "^1.0.0",
|
||||||
|
"requires-port": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/http-proxy-middleware": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-usY0HG5nyDUwtqpiZdETNbmKtw3QQ1jwYFZ9wi5iHzX2BcILwQKtYDJPo7XHTsu5Z0B2Hj3W9NNnbd+AjFWjqg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/http-proxy": "^1.17.15",
|
||||||
|
"debug": "^4.3.6",
|
||||||
|
"http-proxy": "^1.18.1",
|
||||||
|
"is-glob": "^4.0.3",
|
||||||
|
"is-plain-object": "^5.0.0",
|
||||||
|
"micromatch": "^4.0.8"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/http-proxy-middleware/node_modules/debug": {
|
||||||
|
"version": "4.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
||||||
|
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "^2.1.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"supports-color": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/http-proxy-middleware/node_modules/ms": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/iconv-lite": {
|
||||||
|
"version": "0.4.24",
|
||||||
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||||
|
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"safer-buffer": ">= 2.1.2 < 3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/inherits": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
|
"node_modules/ipaddr.js": {
|
||||||
|
"version": "1.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
||||||
|
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-extglob": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-glob": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"is-extglob": "^2.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-number": {
|
||||||
|
"version": "7.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||||
|
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.12.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-plain-object": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/media-typer": {
|
||||||
|
"version": "0.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||||
|
"integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/merge-descriptors": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/methods": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/micromatch": {
|
||||||
|
"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.3",
|
||||||
|
"picomatch": "^2.3.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mime": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
|
||||||
|
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"mime": "cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mime-db": {
|
||||||
|
"version": "1.52.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||||
|
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mime-types": {
|
||||||
|
"version": "2.1.35",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||||
|
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"mime-db": "1.52.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ms": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/negotiator": {
|
||||||
|
"version": "0.6.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
|
||||||
|
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/object-inspect": {
|
||||||
|
"version": "1.13.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz",
|
||||||
|
"integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/on-finished": {
|
||||||
|
"version": "2.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
|
||||||
|
"integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ee-first": "1.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/parseurl": {
|
||||||
|
"version": "1.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||||
|
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/path-to-regexp": {
|
||||||
|
"version": "0.1.12",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
|
||||||
|
"integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/picomatch": {
|
||||||
|
"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"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/proxy-addr": {
|
||||||
|
"version": "2.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||||
|
"integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"forwarded": "0.2.0",
|
||||||
|
"ipaddr.js": "1.9.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/qs": {
|
||||||
|
"version": "6.13.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
|
||||||
|
"integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"dependencies": {
|
||||||
|
"side-channel": "^1.0.6"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/range-parser": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/raw-body": {
|
||||||
|
"version": "2.5.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
|
||||||
|
"integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"bytes": "3.1.2",
|
||||||
|
"http-errors": "2.0.0",
|
||||||
|
"iconv-lite": "0.4.24",
|
||||||
|
"unpipe": "1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/requires-port": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/safe-buffer": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "consulting",
|
||||||
|
"url": "https://feross.org/support"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/safer-buffer": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/send": {
|
||||||
|
"version": "0.19.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
|
||||||
|
"integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"depd": "2.0.0",
|
||||||
|
"destroy": "1.2.0",
|
||||||
|
"encodeurl": "~1.0.2",
|
||||||
|
"escape-html": "~1.0.3",
|
||||||
|
"etag": "~1.8.1",
|
||||||
|
"fresh": "0.5.2",
|
||||||
|
"http-errors": "2.0.0",
|
||||||
|
"mime": "1.6.0",
|
||||||
|
"ms": "2.1.3",
|
||||||
|
"on-finished": "2.4.1",
|
||||||
|
"range-parser": "~1.2.1",
|
||||||
|
"statuses": "2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/send/node_modules/encodeurl": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/send/node_modules/ms": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/serve-static": {
|
||||||
|
"version": "1.16.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
|
||||||
|
"integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"encodeurl": "~2.0.0",
|
||||||
|
"escape-html": "~1.0.3",
|
||||||
|
"parseurl": "~1.3.3",
|
||||||
|
"send": "0.19.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/set-function-length": {
|
||||||
|
"version": "1.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
|
||||||
|
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"define-data-property": "^1.1.4",
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"function-bind": "^1.1.2",
|
||||||
|
"get-intrinsic": "^1.2.4",
|
||||||
|
"gopd": "^1.0.1",
|
||||||
|
"has-property-descriptors": "^1.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/setprototypeof": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
|
"node_modules/side-channel": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
|
||||||
|
"integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"call-bind": "^1.0.7",
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"get-intrinsic": "^1.2.4",
|
||||||
|
"object-inspect": "^1.13.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/statuses": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/to-regex-range": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"is-number": "^7.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/toidentifier": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/type-is": {
|
||||||
|
"version": "1.6.18",
|
||||||
|
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
|
||||||
|
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"media-typer": "0.3.0",
|
||||||
|
"mime-types": "~2.1.24"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/undici-types": {
|
||||||
|
"version": "6.20.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
|
||||||
|
"integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/unpipe": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/utils-merge": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/vary": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
17
utils/local-proxy/package.json
Normal file
17
utils/local-proxy/package.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"name": "local-proxy",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"start": "node main.js",
|
||||||
|
"pack": "cd ../.. && npm run build:proxy && cd utils/local-proxy"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"description": "",
|
||||||
|
"dependencies": {
|
||||||
|
"express": "^4.21.1",
|
||||||
|
"http-proxy-middleware": "^3.0.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
39
utils/local-proxy/readme.md
Normal file
39
utils/local-proxy/readme.md
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# local-proxy
|
||||||
|
|
||||||
|
Lightweight host for Cosmos Explorer
|
||||||
|
|
||||||
|
## Quickstart
|
||||||
|
|
||||||
|
1. Pre-req - install packages for root project (`cd ../.. && npm ci && cd utils/local-proxy`)
|
||||||
|
2. Install - install packages for local-proxy (`npm ci`)
|
||||||
|
3. Pack - `npm run pack` - builds and packs Cosmos Explorer and copies files into project
|
||||||
|
4. Start - `npm start` - starts the proxy
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ../..
|
||||||
|
npm ci
|
||||||
|
cd utils/local-proxy
|
||||||
|
npm ci
|
||||||
|
npm run pack
|
||||||
|
npm start
|
||||||
|
```
|
||||||
|
|
||||||
|
## Config
|
||||||
|
|
||||||
|
All config is current set via environment variables
|
||||||
|
|
||||||
|
| Name | Options (Default) | Description |
|
||||||
|
| ---------------------------- | ----------------------------------------- | ------------------------------------------------------------ |
|
||||||
|
| `PORT` | number (`1234`) | The port on which the proxy runs. |
|
||||||
|
| `LOG_LEVEL` | `debug`, `info`, `warn`, `error` (`info`) | The logging level for the proxy. |
|
||||||
|
| `EMULATOR_ENDPOINT` | string (`http://localhost:8081`) | The endpoint for the emulator which will be proxied. |
|
||||||
|
| `ENDPOINT_DISCOVERY_ENABLED` | boolean (`false`) | Determine whether the proxy will rewrite the endpoint or not |
|
||||||
|
|
||||||
|
## Dependenies
|
||||||
|
|
||||||
|
Node.js v20+
|
||||||
|
npm (optional)
|
||||||
|
|
||||||
|
## Deployment
|
||||||
|
|
||||||
|
Copy the entire local-proxy directory to wherever you'd like. If you have npm, you can use `npm start`, else `node main.js`
|
||||||
41
utils/local-proxy/test/e2e/https/test_https.sh
Normal file
41
utils/local-proxy/test/e2e/https/test_https.sh
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
pushd $(dirname $0) > /dev/null
|
||||||
|
|
||||||
|
echo Creating self-signed certificate
|
||||||
|
|
||||||
|
# Create a self-signed certificate
|
||||||
|
|
||||||
|
export CERT_SECRET=$(openssl rand -base64 20)
|
||||||
|
openssl genrsa 2048 > host.key
|
||||||
|
chmod 400 host.key
|
||||||
|
#openssl req -new -x509 -nodes -sha256 -days 365 -key host.key -out host.cert --passin env:CERT_SECRET -subj "/C=US/ST=WA/L=BELLEVUE/O=Microsoft/OU=Azure Cosmos DB/CN=CHRIS ANDERSON/emailAddress=andersonc@microsoft.com"
|
||||||
|
openssl pkcs12 -export -out host.pfx -inkey host.key -in host.cert --passout env:CERT_SECRET --name "CHRIS ANDERSON"
|
||||||
|
|
||||||
|
export CERT_PATH=$(realpath host.pfx)
|
||||||
|
|
||||||
|
echo CERT_PATH=$CERT_PATH
|
||||||
|
|
||||||
|
popd > /dev/null
|
||||||
|
|
||||||
|
export GATEWAY_TLS_ENABLED=true
|
||||||
|
export EXPLORER_PORT=12345
|
||||||
|
|
||||||
|
# Use node to start so we can kill it later
|
||||||
|
node main.js > ./https-test.log &
|
||||||
|
node_pid=$!
|
||||||
|
echo node pid=$node_pid
|
||||||
|
|
||||||
|
sleep .5
|
||||||
|
|
||||||
|
output=$(curl --insecure -s "https://localhost:12345/_ready")
|
||||||
|
|
||||||
|
kill -KILL $node_pid
|
||||||
|
|
||||||
|
if [ "$output" != "Compilation complete." ]; then
|
||||||
|
echo "Failed to start HTTPS server"
|
||||||
|
cat ./https-test.log
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo https test completed
|
||||||
@@ -24,6 +24,8 @@ const AZURE_TENANT_ID = "72f988bf-86f1-41af-91ab-2d7cd011db47";
|
|||||||
const RESOURCE_GROUP = "de-e2e-tests";
|
const RESOURCE_GROUP = "de-e2e-tests";
|
||||||
const AZURE_CLIENT_SECRET = process.env.AZURE_CLIENT_SECRET || process.env.NOTEBOOKS_TEST_RUNNER_CLIENT_SECRET; // TODO Remove. Exists for backwards compat with old .env files. Prefer AZURE_CLIENT_SECRET
|
const AZURE_CLIENT_SECRET = process.env.AZURE_CLIENT_SECRET || process.env.NOTEBOOKS_TEST_RUNNER_CLIENT_SECRET; // TODO Remove. Exists for backwards compat with old .env files. Prefer AZURE_CLIENT_SECRET
|
||||||
|
|
||||||
|
const ishttps = process.env.GATEWAY_TLS_ENABLED !== "false"; // false -> false, true -> true, default -> true
|
||||||
|
|
||||||
if (!AZURE_CLIENT_SECRET) {
|
if (!AZURE_CLIENT_SECRET) {
|
||||||
console.warn("AZURE_CLIENT_SECRET is not set. testExplorer.html will not work.");
|
console.warn("AZURE_CLIENT_SECRET is not set. testExplorer.html will not work.");
|
||||||
}
|
}
|
||||||
@@ -120,6 +122,23 @@ module.exports = function (_env = {}, argv = {}) {
|
|||||||
...(mode !== "production" && { testExplorer: "./test/testExplorer/TestExplorer.ts" }),
|
...(mode !== "production" && { testExplorer: "./test/testExplorer/TestExplorer.ts" }),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Derive emulator endpoint components from EMULATOR_ENDPOINT (fallback to localhost defaults)
|
||||||
|
const rawEndpoint = process.env.EMULATOR_ENDPOINT || (ishttps ? "https://localhost:8081/" : "http://localhost:8081/");
|
||||||
|
let endpointProtocol = ishttps ? "https" : "http";
|
||||||
|
let endpointHost = "localhost";
|
||||||
|
let endpointPort = "8081";
|
||||||
|
try {
|
||||||
|
const u = new URL(rawEndpoint);
|
||||||
|
endpointProtocol = u.protocol.replace(":", "");
|
||||||
|
endpointHost = u.hostname;
|
||||||
|
endpointPort = u.port || (endpointProtocol === "https" ? "443" : "80");
|
||||||
|
} catch (e) {
|
||||||
|
// Ignore parse errors and keep defaults
|
||||||
|
}
|
||||||
|
const endpointUri = `${endpointProtocol}://${endpointHost}:${endpointPort}`;
|
||||||
|
const primaryKeyConst = "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==";
|
||||||
|
const primaryConnString = `AccountEndpoint=${endpointUri}/;AccountKey=${primaryKeyConst}`;
|
||||||
|
|
||||||
const htmlWebpackPlugins = [
|
const htmlWebpackPlugins = [
|
||||||
new HtmlWebpackPlugin({
|
new HtmlWebpackPlugin({
|
||||||
filename: "explorer.html",
|
filename: "explorer.html",
|
||||||
@@ -131,10 +150,16 @@ module.exports = function (_env = {}, argv = {}) {
|
|||||||
template: "src/Terminal/index.html",
|
template: "src/Terminal/index.html",
|
||||||
chunks: ["terminal"],
|
chunks: ["terminal"],
|
||||||
}),
|
}),
|
||||||
|
//todo - dynamically include apis
|
||||||
new HtmlWebpackPlugin({
|
new HtmlWebpackPlugin({
|
||||||
filename: "quickstart.html",
|
filename: "quickstart.html",
|
||||||
template: "src/quickstart.html",
|
template: "src/quickstart-sql.template.ejs",
|
||||||
chunks: ["quickstart"],
|
chunks: ["quickstart"],
|
||||||
|
templateParameters: {
|
||||||
|
endpointUri,
|
||||||
|
primaryKey: primaryKeyConst,
|
||||||
|
primaryConnString,
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
new HtmlWebpackPlugin({
|
new HtmlWebpackPlugin({
|
||||||
filename: "index.html",
|
filename: "index.html",
|
||||||
@@ -211,11 +236,20 @@ module.exports = function (_env = {}, argv = {}) {
|
|||||||
{ from: "DataExplorer.proj" },
|
{ from: "DataExplorer.proj" },
|
||||||
{ from: "web.config" },
|
{ from: "web.config" },
|
||||||
{ from: "quickstart/*.zip" },
|
{ from: "quickstart/*.zip" },
|
||||||
|
{ from: "images", to: "images" },
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
new EnvironmentPlugin(envVars),
|
new EnvironmentPlugin(envVars),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if (process.env.EXPLORER_CONFIG_PATH) {
|
||||||
|
plugins.push(
|
||||||
|
new CopyWebpackPlugin({
|
||||||
|
patterns: [{ from: process.env.EXPLORER_CONFIG_PATH, to: "config.json" }],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (argv.analyze) {
|
if (argv.analyze) {
|
||||||
plugins.push(new BundleAnalyzerPlugin());
|
plugins.push(new BundleAnalyzerPlugin());
|
||||||
}
|
}
|
||||||
@@ -280,7 +314,7 @@ module.exports = function (_env = {}, argv = {}) {
|
|||||||
// disableHostCheck: true,
|
// disableHostCheck: true,
|
||||||
liveReload: !isCI,
|
liveReload: !isCI,
|
||||||
server: {
|
server: {
|
||||||
type: "https",
|
type: ishttps ? "https" : "http",
|
||||||
},
|
},
|
||||||
host: "0.0.0.0",
|
host: "0.0.0.0",
|
||||||
port: envVars.PORT,
|
port: envVars.PORT,
|
||||||
|
|||||||
Reference in New Issue
Block a user