mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-30 06:11:38 +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
|
||||
src/Explorer/Tree/ResourceTree.tsx
|
||||
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"
|
||||
}
|
||||
},
|
||||
"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": {
|
||||
"version": "1.2.6",
|
||||
"license": "MIT",
|
||||
@@ -7893,7 +7945,7 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@nteract/data-explorer/node_modules/cross-spawn": {
|
||||
"version": "6.0.5",
|
||||
"version": "7.0.5",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"nice-try": "^1.0.4",
|
||||
@@ -8017,7 +8069,7 @@
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cross-spawn": "^6.0.0",
|
||||
"cross-spawn": "^7.0.5",
|
||||
"get-stream": "^4.0.0",
|
||||
"is-stream": "^1.1.0",
|
||||
"npm-run-path": "^2.0.0",
|
||||
@@ -16445,7 +16497,7 @@
|
||||
}
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"version": "7.0.5",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"path-key": "^3.1.0",
|
||||
@@ -18359,7 +18411,7 @@
|
||||
"@nodelib/fs.walk": "^1.2.8",
|
||||
"ajv": "^6.12.4",
|
||||
"chalk": "^4.0.0",
|
||||
"cross-spawn": "^7.0.2",
|
||||
"cross-spawn": "^7.0.5",
|
||||
"debug": "^4.3.2",
|
||||
"doctrine": "^3.0.0",
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
@@ -18946,7 +18998,7 @@
|
||||
"integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
|
||||
"devOptional": true,
|
||||
"dependencies": {
|
||||
"cross-spawn": "^7.0.3",
|
||||
"cross-spawn": "^7.0.5",
|
||||
"get-stream": "^6.0.0",
|
||||
"human-signals": "^2.1.0",
|
||||
"is-stream": "^2.0.0",
|
||||
@@ -19211,7 +19263,7 @@
|
||||
"methods": "~1.1.2",
|
||||
"on-finished": "2.4.1",
|
||||
"parseurl": "~1.3.3",
|
||||
"path-to-regexp": "0.1.7",
|
||||
"path-to-regexp": "0.1.12",
|
||||
"proxy-addr": "~2.0.7",
|
||||
"qs": "6.11.0",
|
||||
"range-parser": "~1.2.1",
|
||||
@@ -19247,7 +19299,7 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/express/node_modules/path-to-regexp": {
|
||||
"version": "0.1.7",
|
||||
"version": "0.1.12",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
@@ -30535,7 +30587,7 @@
|
||||
"@yarnpkg/lockfile": "^1.1.0",
|
||||
"chalk": "^4.1.2",
|
||||
"ci-info": "^3.7.0",
|
||||
"cross-spawn": "^7.0.3",
|
||||
"cross-spawn": "^7.0.5",
|
||||
"find-yarn-workspace-root": "^2.0.0",
|
||||
"fs-extra": "^9.0.0",
|
||||
"json-stable-stringify": "^1.0.2",
|
||||
@@ -31513,7 +31565,7 @@
|
||||
"address": "^1.1.2",
|
||||
"browserslist": "^4.18.1",
|
||||
"chalk": "^4.1.2",
|
||||
"cross-spawn": "^7.0.3",
|
||||
"cross-spawn": "^7.0.5",
|
||||
"detect-port-alt": "^1.1.6",
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
"filesize": "^8.0.6",
|
||||
@@ -32969,7 +33021,7 @@
|
||||
}
|
||||
},
|
||||
"node_modules/sane/node_modules/cross-spawn": {
|
||||
"version": "6.0.5",
|
||||
"version": "7.0.5",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"nice-try": "^1.0.4",
|
||||
@@ -32986,7 +33038,7 @@
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cross-spawn": "^6.0.0",
|
||||
"cross-spawn": "^7.0.5",
|
||||
"get-stream": "^4.0.0",
|
||||
"is-stream": "^1.1.0",
|
||||
"npm-run-path": "^2.0.0",
|
||||
@@ -35955,7 +36007,7 @@
|
||||
"@webpack-cli/serve": "^2.0.5",
|
||||
"colorette": "^2.0.14",
|
||||
"commander": "^10.0.1",
|
||||
"cross-spawn": "^7.0.3",
|
||||
"cross-spawn": "^7.0.5",
|
||||
"envinfo": "^7.7.3",
|
||||
"fastest-levenshtein": "^1.0.12",
|
||||
"import-local": "^3.0.2",
|
||||
@@ -36480,7 +36532,7 @@
|
||||
}
|
||||
},
|
||||
"node_modules/windows-release/node_modules/cross-spawn": {
|
||||
"version": "6.0.5",
|
||||
"version": "7.0.5",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"nice-try": "^1.0.4",
|
||||
@@ -36497,7 +36549,7 @@
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cross-spawn": "^6.0.0",
|
||||
"cross-spawn": "^7.0.5",
|
||||
"get-stream": "^4.0.0",
|
||||
"is-stream": "^1.1.0",
|
||||
"npm-run-path": "^2.0.0",
|
||||
|
||||
@@ -206,9 +206,11 @@
|
||||
"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: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:fast": "webpack --mode development --progress",
|
||||
"copyToConsumers": "node copyToConsumers",
|
||||
"copyToProxy": "rm -rf ./utils/local-proxy/dist && cp -r ./dist ./utils/local-proxy",
|
||||
"test": "rimraf coverage && jest",
|
||||
"test:debug": "jest --runInBand",
|
||||
"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",
|
||||
};
|
||||
|
||||
export enum MongoGuidRepresentation {
|
||||
Standard = "Standard",
|
||||
CSharpLegacy = "CSharpLegacy",
|
||||
JavaLegacy = "JavaLegacy",
|
||||
PythonLegacy = "PythonLegacy",
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ export const tokenProvider = async (requestInfo: Cosmos.RequestInfo) => {
|
||||
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.
|
||||
await Cosmos.setAuthorizationTokenHeaderUsingMasterKey(verb, resourceId, resourceType, headers, EmulatorMasterKey);
|
||||
return decodeURIComponent(headers.authorization);
|
||||
@@ -119,7 +119,7 @@ export const requestPlugin: Cosmos.Plugin<any> = async (requestContext, diagnost
|
||||
};
|
||||
|
||||
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
|
||||
const location = _global.parent ? _global.parent.location : _global.location;
|
||||
return configContext.EMULATOR_ENDPOINT || location.origin;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Constants as CosmosSDKConstants } from "@azure/cosmos";
|
||||
import { getMongoGuidRepresentation } from "Shared/StorageUtility";
|
||||
import { AuthType } from "../AuthType";
|
||||
import { configContext } from "../ConfigContext";
|
||||
import * as DataModels from "../Contracts/DataModels";
|
||||
@@ -140,9 +139,6 @@ export function readDocument(
|
||||
documentId && documentId.partitionKey && !documentId.partitionKey.systemKey
|
||||
? documentId.partitionKeyProperties?.[0]
|
||||
: "",
|
||||
clientSettings: {
|
||||
guidRepresentation: getMongoGuidRepresentation(),
|
||||
},
|
||||
};
|
||||
|
||||
const endpoint = getEndpoint(configContext.MONGO_PROXY_ENDPOINT);
|
||||
@@ -185,9 +181,6 @@ export function createDocument(
|
||||
partitionKey:
|
||||
collection && collection.partitionKey && !collection.partitionKey.systemKey ? partitionKeyProperty : "",
|
||||
documentContent: JSON.stringify(documentContent),
|
||||
clientSettings: {
|
||||
guidRepresentation: getMongoGuidRepresentation(),
|
||||
},
|
||||
};
|
||||
|
||||
const endpoint = getEndpoint(configContext.MONGO_PROXY_ENDPOINT);
|
||||
@@ -235,9 +228,6 @@ export function updateDocument(
|
||||
? documentId.partitionKeyProperties?.[0]
|
||||
: "",
|
||||
documentContent,
|
||||
clientSettings: {
|
||||
guidRepresentation: getMongoGuidRepresentation(),
|
||||
},
|
||||
};
|
||||
const endpoint = getEndpoint(configContext.MONGO_PROXY_ENDPOINT);
|
||||
|
||||
@@ -284,9 +274,6 @@ export function deleteDocuments(
|
||||
subscriptionID: userContext.subscriptionId,
|
||||
resourceGroup: userContext.resourceGroup,
|
||||
databaseAccountName: databaseAccount.name,
|
||||
clientSettings: {
|
||||
guidRepresentation: getMongoGuidRepresentation(),
|
||||
},
|
||||
};
|
||||
const endpoint = getEndpoint(configContext.MONGO_PROXY_ENDPOINT);
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ export enum Platform {
|
||||
Hosted = "Hosted",
|
||||
Emulator = "Emulator",
|
||||
Fabric = "Fabric",
|
||||
VNextEmulator = "VNextEmulator",
|
||||
}
|
||||
|
||||
export interface ConfigContext {
|
||||
@@ -215,7 +216,7 @@ export async function initializeConfiguration(): Promise<ConfigContext> {
|
||||
const AAD_ENDPOINT = params.get("aadEndpoint") || "";
|
||||
updateConfigContext({ AAD_ENDPOINT });
|
||||
}
|
||||
if (params.has("platform")) {
|
||||
if (params.has("platform") && configContext.platform !== Platform.VNextEmulator) {
|
||||
const platform = params.get("platform");
|
||||
switch (platform) {
|
||||
default:
|
||||
|
||||
@@ -10,6 +10,7 @@ import { useDatabases } from "Explorer/useDatabases";
|
||||
import { isFabric, isFabricNative } from "Platform/Fabric/FabricUtil";
|
||||
import { Action } from "Shared/Telemetry/TelemetryConstants";
|
||||
import { traceOpen } from "Shared/Telemetry/TelemetryProcessor";
|
||||
import { areAdvancedScriptsSupported } from "Utils/PlatformFeatureUtils";
|
||||
import { ReactTabKind, useTabs } from "hooks/useTabs";
|
||||
import React from "react";
|
||||
import AddCollectionIcon from "../../images/AddCollection.svg";
|
||||
@@ -130,6 +131,7 @@ export const createCollectionContextMenuButton = (
|
||||
}
|
||||
|
||||
if (
|
||||
areAdvancedScriptsSupported(configContext.platform) &&
|
||||
configContext.platform !== Platform.Fabric &&
|
||||
(userContext.apiType === "SQL" || userContext.apiType === "Gremlin")
|
||||
) {
|
||||
|
||||
@@ -15,6 +15,7 @@ import { useDatabases } from "Explorer/useDatabases";
|
||||
import { isFabricNative } from "Platform/Fabric/FabricUtil";
|
||||
import { isVectorSearchEnabled } from "Utils/CapabilityUtils";
|
||||
import { isRunningOnPublicCloud } from "Utils/CloudUtils";
|
||||
import { isFeatureSupported, PlatformFeature } from "Utils/PlatformFeatureUtils";
|
||||
import * as React from "react";
|
||||
import DiscardIcon from "../../../../images/discard.svg";
|
||||
import SaveIcon from "../../../../images/save-cosmos.svg";
|
||||
@@ -60,15 +61,15 @@ import {
|
||||
AddMongoIndexProps,
|
||||
ChangeFeedPolicyState,
|
||||
GeospatialConfigType,
|
||||
MongoIndexTypes,
|
||||
SettingsV2TabTypes,
|
||||
TtlType,
|
||||
getMongoNotification,
|
||||
getTabTitle,
|
||||
hasDatabaseSharedThroughput,
|
||||
isDirty,
|
||||
MongoIndexTypes,
|
||||
parseConflictResolutionMode,
|
||||
parseConflictResolutionProcedure,
|
||||
SettingsV2TabTypes,
|
||||
TtlType,
|
||||
} from "./SettingsUtils";
|
||||
|
||||
interface SettingsV2TabInfo {
|
||||
@@ -276,14 +277,14 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
||||
this.saveSettingsButton = {
|
||||
isEnabled: this.isSaveSettingsButtonEnabled,
|
||||
isVisible: () => {
|
||||
return true;
|
||||
return isFeatureSupported(PlatformFeature.UpdateCollection);
|
||||
},
|
||||
};
|
||||
|
||||
this.discardSettingsChangesButton = {
|
||||
isEnabled: this.isDiscardSettingsButtonEnabled,
|
||||
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({
|
||||
tab: SettingsV2TabTypes.ComputedPropertiesTab,
|
||||
content: <ComputedPropertiesComponent {...computedPropertiesComponentProps} />,
|
||||
|
||||
@@ -45,7 +45,7 @@ export class ScaleComponent extends React.Component<ScaleComponentProps> {
|
||||
|
||||
constructor(props: ScaleComponentProps) {
|
||||
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.databaseId = this.props.database?.id() || this.props.collection.databaseId;
|
||||
this.collectionId = this.props.collection?.id();
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Link } from "@fluentui/react/lib/Link";
|
||||
import { isPublicInternetAccessAllowed } from "Common/DatabaseAccountUtility";
|
||||
import { Environment, getEnvironment } from "Common/EnvironmentUtility";
|
||||
import { sendMessage } from "Common/MessageHandler";
|
||||
import { Platform, configContext } from "ConfigContext";
|
||||
import { configContext, Platform } from "ConfigContext";
|
||||
import { MessageTypes } from "Contracts/ExplorerContracts";
|
||||
import { useDataPlaneRbac } from "Explorer/Panes/SettingsPane/SettingsPane";
|
||||
import { getCopilotEnabled, isCopilotFeatureRegistered } from "Explorer/QueryCopilot/Shared/QueryCopilotClient";
|
||||
@@ -18,6 +18,7 @@ import { LocalStorageUtility, StorageKey } from "Shared/StorageUtility";
|
||||
import { acquireMsalTokenForAccount } from "Utils/AuthorizationUtils";
|
||||
import { allowedNotebookServerUrls, validateEndpoint } from "Utils/EndpointUtils";
|
||||
import { featureRegistered } from "Utils/FeatureRegistrationUtils";
|
||||
import { isFeatureSupported, PlatformFeature } from "Utils/PlatformFeatureUtils";
|
||||
import { update } from "Utils/arm/generatedClients/cosmos/databaseAccounts";
|
||||
import { useQueryCopilot } from "hooks/useQueryCopilot";
|
||||
import * as ko from "knockout";
|
||||
@@ -1187,6 +1188,7 @@ export default class Explorer {
|
||||
|
||||
// TODO: remove reference to isNotebookEnabled and isNotebooksEnabledForAccount
|
||||
const isNotebookEnabled =
|
||||
isFeatureSupported(PlatformFeature.Notebooks) &&
|
||||
configContext.platform !== Platform.Fabric &&
|
||||
(userContext.features.notebooksDownBanner ||
|
||||
useNotebook.getState().isPhoenixNotebooks ||
|
||||
@@ -1194,7 +1196,11 @@ export default class Explorer {
|
||||
useNotebook.getState().setIsNotebookEnabled(isNotebookEnabled);
|
||||
useNotebook
|
||||
.getState()
|
||||
.setIsShellEnabled(useNotebook.getState().isPhoenixFeatures && isPublicInternetAccessAllowed());
|
||||
.setIsShellEnabled(
|
||||
isFeatureSupported(PlatformFeature.CloudShell) &&
|
||||
useNotebook.getState().isPhoenixFeatures &&
|
||||
isPublicInternetAccessAllowed(),
|
||||
);
|
||||
|
||||
TelemetryProcessor.trace(Action.NotebookEnabled, ActionModifiers.Mark, {
|
||||
isNotebookEnabled,
|
||||
@@ -1215,6 +1221,7 @@ export default class Explorer {
|
||||
|
||||
public async configureCopilot(): Promise<void> {
|
||||
if (
|
||||
!isFeatureSupported(PlatformFeature.Copilot) ||
|
||||
userContext.apiType !== "SQL" ||
|
||||
!userContext.subscriptionId ||
|
||||
![Environment.Development, Environment.Mpac, Environment.Prod].includes(getEnvironment())
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { KeyboardAction } from "KeyboardShortcuts";
|
||||
import { isDataplaneRbacSupported } from "Utils/APITypeUtils";
|
||||
import { areAdvancedScriptsSupported, isFeatureSupported, PlatformFeature } from "Utils/PlatformFeatureUtils";
|
||||
import * as React from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
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 { AuthType } from "../../../AuthType";
|
||||
import * as Constants from "../../../Common/Constants";
|
||||
import { Platform, configContext } from "../../../ConfigContext";
|
||||
import { configContext, Platform } from "../../../ConfigContext";
|
||||
import * as ViewModels from "../../../Contracts/ViewModels";
|
||||
import { userContext } from "../../../UserContext";
|
||||
import { isRunningOnNationalCloud } from "../../../Utils/CloudUtils";
|
||||
@@ -52,6 +53,7 @@ export function createStaticCommandBarButtons(
|
||||
};
|
||||
|
||||
if (
|
||||
isFeatureSupported(PlatformFeature.SynapseLink) &&
|
||||
configContext.platform !== Platform.Fabric &&
|
||||
userContext.apiType !== "Tables" &&
|
||||
userContext.apiType !== "Cassandra"
|
||||
@@ -63,7 +65,9 @@ export function createStaticCommandBarButtons(
|
||||
}
|
||||
if (userContext.apiType !== "Gremlin") {
|
||||
const addVsCode = createOpenVsCodeDialogButton(container);
|
||||
buttons.push(addVsCode);
|
||||
if (addVsCode) {
|
||||
buttons.push(addVsCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,11 +246,17 @@ export function createDivider(): CommandButtonComponentProps {
|
||||
|
||||
function areScriptsSupported(): boolean {
|
||||
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 {
|
||||
if (!isFeatureSupported(PlatformFeature.SynapseLink)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (configContext.platform === Platform.Emulator) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -274,6 +284,10 @@ function createOpenSynapseLinkDialogButton(container: Explorer): CommandButtonCo
|
||||
}
|
||||
|
||||
function createOpenVsCodeDialogButton(container: Explorer): CommandButtonComponentProps {
|
||||
if (!isFeatureSupported(PlatformFeature.VSCodeIntegration)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const label = "Visual Studio Code";
|
||||
return {
|
||||
iconSrc: VSCodeIcon,
|
||||
|
||||
@@ -50,6 +50,7 @@ import * as TelemetryProcessor from "Shared/Telemetry/TelemetryProcessor";
|
||||
import { userContext } from "UserContext";
|
||||
import { getCollectionName } from "Utils/APITypeUtils";
|
||||
import { isCapabilityEnabled, isServerlessAccount, isVectorSearchEnabled } from "Utils/CapabilityUtils";
|
||||
import { isFeatureSupported, PlatformFeature } from "Utils/PlatformFeatureUtils";
|
||||
import { getUpsellMessage } from "Utils/PricingUtils";
|
||||
import { ValidCosmosDbIdDescription, ValidCosmosDbIdInputPattern } from "Utils/ValidationUtils";
|
||||
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 }}>
|
||||
{UniqueKeysHeader()}
|
||||
{this.state.uniqueKeys.map((uniqueKey: string, i: number): JSX.Element => {
|
||||
@@ -900,78 +901,86 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
</CollapsibleSectionComponent>
|
||||
</Stack>
|
||||
)}
|
||||
{!isFabricNative() && userContext.apiType !== "Tables" && (
|
||||
<CollapsibleSectionComponent
|
||||
title="Advanced"
|
||||
isExpandedByDefault={false}
|
||||
onExpand={() => {
|
||||
TelemetryProcessor.traceOpen(Action.ExpandAddCollectionPaneAdvancedSection);
|
||||
scrollToSection("collapsibleAdvancedSectionContent");
|
||||
}}
|
||||
>
|
||||
<Stack className="panelGroupSpacing" id="collapsibleAdvancedSectionContent">
|
||||
{isCapabilityEnabled("EnableMongo") && !isCapabilityEnabled("EnableMongo16MBDocumentSupport") && (
|
||||
<Stack className="panelGroupSpacing">
|
||||
<Stack horizontal>
|
||||
<span className="mandatoryStar">* </span>
|
||||
<Text className="panelTextBold" variant="small">
|
||||
Indexing
|
||||
</Text>
|
||||
<TooltipHost
|
||||
directionalHint={DirectionalHint.bottomLeftEdge}
|
||||
content="The _id field is indexed by default. Creating a wildcard index for all fields will optimize queries and is recommended for development."
|
||||
>
|
||||
<Icon
|
||||
iconName="Info"
|
||||
className="panelInfoIcon"
|
||||
tabIndex={0}
|
||||
ariaLabel="The _id field is indexed by default. Creating a wildcard index for all fields will optimize queries and is recommended for development."
|
||||
/>
|
||||
</TooltipHost>
|
||||
{isFeatureSupported(PlatformFeature.AdvancedContainerSettings) &&
|
||||
!isFabricNative() &&
|
||||
userContext.apiType !== "Tables" && (
|
||||
<CollapsibleSectionComponent
|
||||
title="Advanced"
|
||||
isExpandedByDefault={false}
|
||||
onExpand={() => {
|
||||
TelemetryProcessor.traceOpen(Action.ExpandAddCollectionPaneAdvancedSection);
|
||||
scrollToSection("collapsibleAdvancedSectionContent");
|
||||
}}
|
||||
>
|
||||
<Stack className="panelGroupSpacing" id="collapsibleAdvancedSectionContent">
|
||||
{isCapabilityEnabled("EnableMongo") && !isCapabilityEnabled("EnableMongo16MBDocumentSupport") && (
|
||||
<Stack className="panelGroupSpacing">
|
||||
<Stack horizontal>
|
||||
<span className="mandatoryStar">* </span>
|
||||
<Text className="panelTextBold" variant="small">
|
||||
Indexing
|
||||
</Text>
|
||||
<TooltipHost
|
||||
directionalHint={DirectionalHint.bottomLeftEdge}
|
||||
content="The _id field is indexed by default. Creating a wildcard index for all fields will optimize queries and is recommended for development."
|
||||
>
|
||||
<Icon
|
||||
iconName="Info"
|
||||
className="panelInfoIcon"
|
||||
tabIndex={0}
|
||||
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>
|
||||
)}
|
||||
|
||||
<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>
|
||||
)}
|
||||
|
||||
{userContext.apiType === "SQL" && (
|
||||
<Stack className="panelGroupSpacing">
|
||||
<Checkbox
|
||||
label="My application uses an older Cosmos .NET or Java SDK version (.NET V1 or Java V2)"
|
||||
checked={this.state.useHashV1}
|
||||
styles={{
|
||||
text: { fontSize: 12 },
|
||||
checkbox: { width: 12, height: 12 },
|
||||
label: { padding: 0, alignItems: "center", wordWrap: "break-word", whiteSpace: "break-spaces" },
|
||||
}}
|
||||
onChange={(ev: React.FormEvent<HTMLElement>, isChecked: boolean) =>
|
||||
this.setState({ useHashV1: isChecked, subPartitionKeys: [] })
|
||||
}
|
||||
/>
|
||||
<Text variant="small">
|
||||
<Icon iconName="InfoSolid" className="removeIcon" /> To ensure compatibility with older SDKs, the
|
||||
created container will use a legacy partitioning scheme that supports partition key values of size
|
||||
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>
|
||||
)}
|
||||
{userContext.apiType === "SQL" && (
|
||||
<Stack className="panelGroupSpacing">
|
||||
<Checkbox
|
||||
label="My application uses an older Cosmos .NET or Java SDK version (.NET V1 or Java V2)"
|
||||
checked={this.state.useHashV1}
|
||||
styles={{
|
||||
text: { fontSize: 12 },
|
||||
checkbox: { width: 12, height: 12 },
|
||||
label: {
|
||||
padding: 0,
|
||||
alignItems: "center",
|
||||
wordWrap: "break-word",
|
||||
whiteSpace: "break-spaces",
|
||||
},
|
||||
}}
|
||||
onChange={(ev: React.FormEvent<HTMLElement>, isChecked: boolean) =>
|
||||
this.setState({ useHashV1: isChecked, subPartitionKeys: [] })
|
||||
}
|
||||
/>
|
||||
<Text variant="small">
|
||||
<Icon iconName="InfoSolid" className="removeIcon" /> To ensure compatibility with older SDKs,
|
||||
the created container will use a legacy partitioning scheme that supports partition key values
|
||||
of size 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>
|
||||
|
||||
<PanelFooterComponent buttonLabel="OK" isButtonDisabled={this.state.isThroughputCapExceeded} />
|
||||
@@ -1134,6 +1143,10 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
// }
|
||||
|
||||
private shouldShowCollectionThroughputInput(): boolean {
|
||||
if (!isFeatureSupported(PlatformFeature.ContainerThroughput)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isServerlessAccount()) {
|
||||
return false;
|
||||
}
|
||||
@@ -1160,11 +1173,15 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
}
|
||||
|
||||
private shouldShowVectorSearchParameters() {
|
||||
return isVectorSearchEnabled() && (isServerlessAccount() || this.shouldShowCollectionThroughputInput());
|
||||
return (
|
||||
isFeatureSupported(PlatformFeature.VectorSearch) &&
|
||||
isVectorSearchEnabled() &&
|
||||
(isServerlessAccount() || this.shouldShowCollectionThroughputInput())
|
||||
);
|
||||
}
|
||||
|
||||
private shouldShowFullTextSearchParameters() {
|
||||
return !isFabricNative() && this.showFullTextSearch;
|
||||
return isFeatureSupported(PlatformFeature.FullTextSearch) && !isFabricNative() && this.showFullTextSearch;
|
||||
}
|
||||
|
||||
private parseUniqueKeys(): DataModels.UniqueKeyPolicy {
|
||||
|
||||
@@ -6,6 +6,7 @@ import { getFullTextLanguageOptions } from "Explorer/Controls/FullTextSeach/Full
|
||||
import { isFabricNative } from "Platform/Fabric/FabricUtil";
|
||||
import React from "react";
|
||||
import { userContext } from "UserContext";
|
||||
import { isFeatureSupported, PlatformFeature } from "Utils/PlatformFeatureUtils";
|
||||
|
||||
export function getPartitionKeyTooltipText(): string {
|
||||
if (userContext.apiType === "Mongo") {
|
||||
@@ -85,7 +86,11 @@ export function UniqueKeysHeader(): JSX.Element {
|
||||
}
|
||||
|
||||
export function shouldShowAnalyticalStoreOptions(): boolean {
|
||||
if (isFabricNative() || configContext.platform === Platform.Emulator) {
|
||||
if (
|
||||
!isFeatureSupported(PlatformFeature.AnalyticalStore) ||
|
||||
isFabricNative() ||
|
||||
configContext.platform === Platform.Emulator
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -199,16 +199,10 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({
|
||||
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 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 showRetrySettings =
|
||||
(userContext.apiType === "SQL" || userContext.apiType === "Tables" || userContext.apiType === "Gremlin") &&
|
||||
@@ -267,8 +261,6 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({
|
||||
useDatabases.getState().sampleDataResourceTokenCollection &&
|
||||
!isEmulator;
|
||||
|
||||
const shouldShowMongoGuidRepresentationOption = userContext.apiType === "Mongo";
|
||||
|
||||
const handlerOnSubmit = async () => {
|
||||
setIsExecuting(true);
|
||||
|
||||
@@ -420,10 +412,6 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({
|
||||
);
|
||||
}
|
||||
|
||||
if (shouldShowMongoGuidRepresentationOption) {
|
||||
LocalStorageUtility.setEntryString(StorageKey.MongoGuidRepresentation, mongoGuidRepresentation);
|
||||
}
|
||||
|
||||
setIsExecuting(false);
|
||||
logConsoleInfo(
|
||||
`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());
|
||||
closeSidePanel();
|
||||
};
|
||||
@@ -497,13 +477,6 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({
|
||||
{ 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 = (
|
||||
ev: React.FormEvent<HTMLInputElement>,
|
||||
option: IChoiceGroupOption,
|
||||
@@ -586,13 +559,6 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({
|
||||
setRefreshExplorer(false);
|
||||
};
|
||||
|
||||
const handleOnMongoGuidRepresentationOptionChange = (
|
||||
ev: React.FormEvent<HTMLInputElement>,
|
||||
option: IDropdownOption,
|
||||
): void => {
|
||||
setMongoGuidRepresentation(option.key as Constants.MongoGuidRepresentation);
|
||||
};
|
||||
|
||||
const choiceButtonStyles = {
|
||||
root: {
|
||||
clear: "both",
|
||||
@@ -1099,15 +1065,15 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({
|
||||
<div className={styles.settingsSectionContainer}>
|
||||
<div className={styles.settingsSectionDescription}>
|
||||
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,
|
||||
and maintained by Microsoft at no cost to you.
|
||||
NoSQL queries and Query Advisor. This will appear as another database in the Data Explorer UI, and
|
||||
is created by, and maintained by Microsoft at no cost to you.
|
||||
</div>
|
||||
<Checkbox
|
||||
styles={{
|
||||
label: { padding: 0 },
|
||||
}}
|
||||
className="padding"
|
||||
ariaLabel="Enable sample db for query exploration"
|
||||
ariaLabel="Enable sample db for Query Advisor"
|
||||
checked={copilotSampleDBEnabled}
|
||||
onChange={handleSampleDatabaseChange}
|
||||
label="Enable sample database"
|
||||
@@ -1116,27 +1082,6 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({
|
||||
</AccordionPanel>
|
||||
</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>
|
||||
)}
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
/* eslint-disable no-console */
|
||||
import { Stack } from "@fluentui/react";
|
||||
import { QueryCopilotSampleContainerId, QueryCopilotSampleDatabaseId } from "Common/Constants";
|
||||
import { CommandButtonComponentProps } from "Explorer/Controls/CommandButton/CommandButtonComponent";
|
||||
import { EditorReact } from "Explorer/Controls/Editor/EditorReact";
|
||||
import { useCommandBar } from "Explorer/Menus/CommandBar/CommandBarComponentAdapter";
|
||||
import { SaveQueryPane } from "Explorer/Panes/SaveQueryPane/SaveQueryPane";
|
||||
import { QueryCopilotPromptbar } from "Explorer/QueryCopilot/QueryCopilotPromptbar";
|
||||
import { readCopilotToggleStatus, saveCopilotToggleStatus } from "Explorer/QueryCopilot/QueryCopilotUtilities";
|
||||
import { OnExecuteQueryClick } from "Explorer/QueryCopilot/Shared/QueryCopilotClient";
|
||||
import { QueryCopilotProps } from "Explorer/QueryCopilot/Shared/QueryCopilotInterfaces";
|
||||
@@ -11,6 +13,7 @@ import { QueryCopilotResults } from "Explorer/QueryCopilot/Shared/QueryCopilotRe
|
||||
import { userContext } from "UserContext";
|
||||
import { QueryCopilotState, useQueryCopilot } from "hooks/useQueryCopilot";
|
||||
import { useSidePanel } from "hooks/useSidePanel";
|
||||
import { ReactTabKind, TabsState, useTabs } from "hooks/useTabs";
|
||||
import React, { useState } from "react";
|
||||
import SplitterLayout from "react-splitter-layout";
|
||||
import QueryCommandIcon from "../../../images/CopilotCommand.svg";
|
||||
@@ -23,8 +26,7 @@ export const QueryCopilotTab: React.FC<QueryCopilotProps> = ({ explorer }: Query
|
||||
const [copilotActive, setCopilotActive] = useState<boolean>(() =>
|
||||
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 executeQueryBtnLabel = selectedQuery ? "Execute Selection" : "Execute Query";
|
||||
@@ -68,18 +70,17 @@ export const QueryCopilotTab: React.FC<QueryCopilotProps> = ({ explorer }: Query
|
||||
useCommandBar.getState().setContextButtons(getCommandbarButtons());
|
||||
}, [query, selectedQuery, copilotActive]);
|
||||
|
||||
//TODO: Uncomment this effect when query copilot is reinstated in DE
|
||||
// React.useEffect(() => {
|
||||
// return () => {
|
||||
// useTabs.subscribe((state: TabsState) => {
|
||||
// if (state.activeReactTab === ReactTabKind.QueryCopilot) {
|
||||
// setTabActive(true);
|
||||
// } else {
|
||||
// setTabActive(false);
|
||||
// }
|
||||
// });
|
||||
// };
|
||||
// }, []);
|
||||
React.useEffect(() => {
|
||||
return () => {
|
||||
useTabs.subscribe((state: TabsState) => {
|
||||
if (state.activeReactTab === ReactTabKind.QueryCopilot) {
|
||||
setTabActive(true);
|
||||
} else {
|
||||
setTabActive(false);
|
||||
}
|
||||
});
|
||||
};
|
||||
}, []);
|
||||
|
||||
const toggleCopilot = (toggle: boolean) => {
|
||||
setCopilotActive(toggle);
|
||||
@@ -89,7 +90,6 @@ export const QueryCopilotTab: React.FC<QueryCopilotProps> = ({ explorer }: Query
|
||||
return (
|
||||
<Stack className="tab-pane" style={{ width: "100%" }}>
|
||||
<div style={isGeneratingQuery ? { height: "100%" } : { overflowY: "auto", height: "100%" }}>
|
||||
{/*TODO: Uncomment this section when query copilot is reinstated in DE
|
||||
{tabActive && copilotActive && (
|
||||
<QueryCopilotPromptbar
|
||||
explorer={explorer}
|
||||
@@ -97,7 +97,7 @@ export const QueryCopilotTab: React.FC<QueryCopilotProps> = ({ explorer }: Query
|
||||
databaseId={QueryCopilotSampleDatabaseId}
|
||||
containerId={QueryCopilotSampleContainerId}
|
||||
></QueryCopilotPromptbar>
|
||||
)} */}
|
||||
)}
|
||||
<Stack className="tabPaneContentContainer">
|
||||
<SplitterLayout percentage={true} vertical={true} primaryIndex={0} primaryMinSize={30} secondaryMinSize={70}>
|
||||
<EditorReact
|
||||
|
||||
@@ -24,7 +24,6 @@ import { ReactTabKind, useTabs } from "hooks/useTabs";
|
||||
import * as React from "react";
|
||||
import ConnectIcon from "../../../images/Connect_color.svg";
|
||||
import ContainersIcon from "../../../images/Containers.svg";
|
||||
import CosmosDBIcon from "../../../images/CosmosDB-logo.svg";
|
||||
import LinkIcon from "../../../images/Link_blue.svg";
|
||||
import PowerShellIcon from "../../../images/PowerShell.svg";
|
||||
import CopilotIcon from "../../../images/QueryCopilotNewLogo.svg";
|
||||
@@ -121,7 +120,11 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
|
||||
};
|
||||
|
||||
private getSplashScreenButtons = (): JSX.Element => {
|
||||
if (userContext.apiType === "SQL") {
|
||||
if (
|
||||
userContext.apiType === "SQL" &&
|
||||
useQueryCopilot.getState().copilotEnabled &&
|
||||
useDatabases.getState().sampleDataResourceTokenCollection
|
||||
) {
|
||||
return (
|
||||
<Stack
|
||||
className="splashStackContainer"
|
||||
@@ -149,18 +152,25 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
|
||||
/>
|
||||
</Stack>
|
||||
<Stack className="splashStackRow" horizontal>
|
||||
<SplashScreenButton
|
||||
imgSrc={CosmosDBIcon}
|
||||
imgSize={35}
|
||||
title={"Azure Cosmos DB Samples Gallery"}
|
||||
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"
|
||||
}
|
||||
onClick={() => {
|
||||
window.open("https://azurecosmosdb.github.io/gallery/?tags=example", "_blank");
|
||||
traceOpen(Action.LearningResourcesClicked, { apiType: userContext.apiType });
|
||||
}}
|
||||
/>
|
||||
{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 });
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<SplashScreenButton
|
||||
imgSrc={ConnectIcon}
|
||||
title={"Connect"}
|
||||
@@ -202,7 +212,6 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
|
||||
sample data, query.
|
||||
</TeachingBubble>
|
||||
)}
|
||||
{/*TODO: convert below to use SplashScreenButton */}
|
||||
{mainItems.map((item) => (
|
||||
<Stack
|
||||
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) {
|
||||
return {
|
||||
iconSrc: CollectionIcon,
|
||||
|
||||
@@ -7,7 +7,6 @@ interface SplashScreenButtonProps {
|
||||
title: string;
|
||||
description: string;
|
||||
onClick: () => void;
|
||||
imgSize?: number;
|
||||
}
|
||||
|
||||
export const SplashScreenButton: React.FC<SplashScreenButtonProps> = ({
|
||||
@@ -15,7 +14,6 @@ export const SplashScreenButton: React.FC<SplashScreenButtonProps> = ({
|
||||
title,
|
||||
description,
|
||||
onClick,
|
||||
imgSize,
|
||||
}: SplashScreenButtonProps): JSX.Element => {
|
||||
return (
|
||||
<Stack
|
||||
@@ -41,7 +39,7 @@ export const SplashScreenButton: React.FC<SplashScreenButtonProps> = ({
|
||||
role="button"
|
||||
>
|
||||
<div>
|
||||
<img src={imgSrc} alt={title} aria-hidden="true" {...(imgSize ? { height: imgSize, width: imgSize } : {})} />
|
||||
<img src={imgSrc} alt={title} aria-hidden="true" />
|
||||
</div>
|
||||
<Stack style={{ marginLeft: 16 }}>
|
||||
<Text style={{ fontSize: 18, fontWeight: 600 }}>{title}</Text>
|
||||
|
||||
@@ -22,7 +22,6 @@ import { formatErrorMessage, formatInfoMessage, formatWarningMessage } from "./U
|
||||
|
||||
// Constants
|
||||
const DEFAULT_CLOUDSHELL_REGION = "westus";
|
||||
const DEFAULT_FAIRFAX_CLOUDSHELL_REGION = "usgovvirginia";
|
||||
const POLLING_INTERVAL_MS = 2000;
|
||||
const MAX_RETRY_COUNT = 10;
|
||||
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
|
||||
*/
|
||||
export const determineCloudShellRegion = (): string => {
|
||||
const defaultRegion =
|
||||
userContext.portalEnv === "fairfax" ? DEFAULT_FAIRFAX_CLOUDSHELL_REGION : DEFAULT_CLOUDSHELL_REGION;
|
||||
return getNormalizedRegion(userContext.databaseAccount?.location, defaultRegion);
|
||||
return getNormalizedRegion(userContext.databaseAccount?.location, DEFAULT_CLOUDSHELL_REGION);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,7 +33,6 @@ jest.mock("../../../../UserContext", () => ({
|
||||
}));
|
||||
|
||||
jest.mock("../Utils/CommonUtils", () => ({
|
||||
...jest.requireActual("../Utils/CommonUtils"),
|
||||
getHostFromUrl: jest.fn().mockReturnValue("test-mongo.documents.azure.com"),
|
||||
}));
|
||||
|
||||
@@ -125,10 +124,7 @@ describe("MongoShellHandler", () => {
|
||||
|
||||
describe("getTerminalSuppressedData", () => {
|
||||
it("should return the correct warning message", () => {
|
||||
expect(mongoShellHandler.getTerminalSuppressedData()).toEqual([
|
||||
"Warning: Non-Genuine MongoDB Detected",
|
||||
"Telemetry is now disabled.",
|
||||
]);
|
||||
expect(mongoShellHandler.getTerminalSuppressedData()).toEqual(["Warning: Non-Genuine MongoDB Detected"]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { userContext } from "../../../../UserContext";
|
||||
import { filterAndCleanTerminalOutput, getHostFromUrl, getMongoShellRemoveInfoText } from "../Utils/CommonUtils";
|
||||
import { getHostFromUrl } from "../Utils/CommonUtils";
|
||||
import { AbstractShellHandler, DISABLE_TELEMETRY_COMMAND } from "./AbstractShellHandler";
|
||||
|
||||
export class MongoShellHandler extends AbstractShellHandler {
|
||||
private _key: string;
|
||||
private _endpoint: string | undefined;
|
||||
private _removeInfoText: string[] = getMongoShellRemoveInfoText();
|
||||
constructor(private key: string) {
|
||||
super();
|
||||
this._key = key;
|
||||
@@ -45,10 +44,6 @@ export class MongoShellHandler extends AbstractShellHandler {
|
||||
}
|
||||
|
||||
public getTerminalSuppressedData(): string[] {
|
||||
return ["Warning: Non-Genuine MongoDB Detected", "Telemetry is now disabled."];
|
||||
}
|
||||
|
||||
updateTerminalData(data: string): string {
|
||||
return filterAndCleanTerminalOutput(data, this._removeInfoText);
|
||||
return ["Warning: Non-Genuine MongoDB Detected"];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { userContext } from "../../../../UserContext";
|
||||
import { filterAndCleanTerminalOutput, getMongoShellRemoveInfoText } from "../Utils/CommonUtils";
|
||||
import { AbstractShellHandler, DISABLE_TELEMETRY_COMMAND } from "./AbstractShellHandler";
|
||||
|
||||
export class VCoreMongoShellHandler extends AbstractShellHandler {
|
||||
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() {
|
||||
super();
|
||||
@@ -35,7 +38,12 @@ export class VCoreMongoShellHandler extends AbstractShellHandler {
|
||||
return ["Warning: Non-Genuine MongoDB Detected", "Telemetry is now disabled."];
|
||||
}
|
||||
|
||||
updateTerminalData(data: string): string {
|
||||
return filterAndCleanTerminalOutput(data, this._removeInfoText);
|
||||
updateTerminalData(content: string): string {
|
||||
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) {
|
||||
const updatedData =
|
||||
typeof this._shellHandler?.updateTerminalData === "function"
|
||||
? this._shellHandler.updateTerminalData(data)
|
||||
: data;
|
||||
|
||||
const updatedData = this._shellHandler?.updateTerminalData(data) ?? data;
|
||||
const suppressedData = this._shellHandler?.getTerminalSuppressedData();
|
||||
|
||||
const shouldNotWrite = suppressedData.filter(Boolean).some((item) => updatedData.includes(item));
|
||||
|
||||
@@ -50,34 +50,3 @@ export const getShellNameForDisplay = (terminalKind: TerminalKind): string => {
|
||||
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",
|
||||
"southeastasia",
|
||||
"westcentralus",
|
||||
"usgovvirginia",
|
||||
"usgovarizona",
|
||||
]);
|
||||
|
||||
/**
|
||||
|
||||
@@ -106,6 +106,6 @@ describe("QueryTabComponent", () => {
|
||||
<QueryTabCopilotComponent {...propsMock} />
|
||||
</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 { QueryCopilotFeedbackModal } from "Explorer/QueryCopilot/Modal/QueryCopilotFeedbackModal";
|
||||
import { useCopilotStore } from "Explorer/QueryCopilot/QueryCopilotContext";
|
||||
import { QueryCopilotPromptbar } from "Explorer/QueryCopilot/QueryCopilotPromptbar";
|
||||
import { readCopilotToggleStatus, saveCopilotToggleStatus } from "Explorer/QueryCopilot/QueryCopilotUtilities";
|
||||
import { OnExecuteQueryClick, QueryDocumentsPerPage } from "Explorer/QueryCopilot/Shared/QueryCopilotClient";
|
||||
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-splitter-layout/lib/index.css";
|
||||
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 LaunchCopilot from "../../../../images/CopilotTabIcon.svg";
|
||||
import QueryCommandIcon from "../../../../images/CopilotCommand.svg";
|
||||
import LaunchCopilot from "../../../../images/CopilotTabIcon.svg";
|
||||
import DownloadQueryIcon from "../../../../images/DownloadQuery.svg";
|
||||
import CancelQueryIcon from "../../../../images/Entity_cancel.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) {
|
||||
// const mainButtonLabel = "Launch Copilot";
|
||||
// const chatPaneLabel = "Open Copilot in chat pane (ALT+C)";
|
||||
// const copilotSettingLabel = "Copilot settings";
|
||||
if (this.launchCopilotButton.visible && this.isCopilotTabActive) {
|
||||
const mainButtonLabel = "Launch Copilot";
|
||||
const chatPaneLabel = "Open Copilot in chat pane (ALT+C)";
|
||||
const copilotSettingLabel = "Copilot settings";
|
||||
|
||||
// const openCopilotChatButton: CommandButtonComponentProps = {
|
||||
// iconAlt: chatPaneLabel,
|
||||
// onCommandClick: this.launchQueryCopilotChat,
|
||||
// commandButtonLabel: chatPaneLabel,
|
||||
// ariaLabel: chatPaneLabel,
|
||||
// hasPopup: false,
|
||||
// };
|
||||
const openCopilotChatButton: CommandButtonComponentProps = {
|
||||
iconAlt: chatPaneLabel,
|
||||
onCommandClick: this.launchQueryCopilotChat,
|
||||
commandButtonLabel: chatPaneLabel,
|
||||
ariaLabel: chatPaneLabel,
|
||||
hasPopup: false,
|
||||
};
|
||||
|
||||
// const copilotSettingsButton: CommandButtonComponentProps = {
|
||||
// iconAlt: copilotSettingLabel,
|
||||
// onCommandClick: () => undefined,
|
||||
// commandButtonLabel: copilotSettingLabel,
|
||||
// ariaLabel: copilotSettingLabel,
|
||||
// hasPopup: false,
|
||||
// };
|
||||
const copilotSettingsButton: CommandButtonComponentProps = {
|
||||
iconAlt: copilotSettingLabel,
|
||||
onCommandClick: () => undefined,
|
||||
commandButtonLabel: copilotSettingLabel,
|
||||
ariaLabel: copilotSettingLabel,
|
||||
hasPopup: false,
|
||||
};
|
||||
|
||||
// const launchCopilotButton: CommandButtonComponentProps = {
|
||||
// iconSrc: LaunchCopilot,
|
||||
// iconAlt: mainButtonLabel,
|
||||
// onCommandClick: this.launchQueryCopilotChat,
|
||||
// commandButtonLabel: mainButtonLabel,
|
||||
// ariaLabel: mainButtonLabel,
|
||||
// hasPopup: false,
|
||||
// children: [openCopilotChatButton, copilotSettingsButton],
|
||||
// };
|
||||
// buttons.push(launchCopilotButton);
|
||||
// }
|
||||
const launchCopilotButton: CommandButtonComponentProps = {
|
||||
iconSrc: LaunchCopilot,
|
||||
iconAlt: mainButtonLabel,
|
||||
onCommandClick: this.launchQueryCopilotChat,
|
||||
commandButtonLabel: mainButtonLabel,
|
||||
ariaLabel: mainButtonLabel,
|
||||
hasPopup: false,
|
||||
children: [openCopilotChatButton, copilotSettingsButton],
|
||||
};
|
||||
buttons.push(launchCopilotButton);
|
||||
}
|
||||
|
||||
//TODO: Uncomment next section when query copilot is reinstated in DE
|
||||
// if (this.props.copilotEnabled) {
|
||||
// const toggleCopilotButton: CommandButtonComponentProps = {
|
||||
// iconSrc: QueryCommandIcon,
|
||||
// iconAlt: "Query Advisor",
|
||||
// keyboardAction: KeyboardAction.TOGGLE_COPILOT,
|
||||
// onCommandClick: () => {
|
||||
// this._toggleCopilot(!this.state.copilotActive);
|
||||
// },
|
||||
// commandButtonLabel: this.state.copilotActive ? "Disable Query Advisor" : "Enable Query Advisor",
|
||||
// ariaLabel: this.state.copilotActive ? "Disable Query Advisor" : "Enable Query Advisor",
|
||||
// hasPopup: false,
|
||||
// };
|
||||
// buttons.push(toggleCopilotButton);
|
||||
// }
|
||||
if (this.props.copilotEnabled) {
|
||||
const toggleCopilotButton: CommandButtonComponentProps = {
|
||||
iconSrc: QueryCommandIcon,
|
||||
iconAlt: "Query Advisor",
|
||||
keyboardAction: KeyboardAction.TOGGLE_COPILOT,
|
||||
onCommandClick: () => {
|
||||
this._toggleCopilot(!this.state.copilotActive);
|
||||
},
|
||||
commandButtonLabel: this.state.copilotActive ? "Disable Query Advisor" : "Enable Query Advisor",
|
||||
ariaLabel: this.state.copilotActive ? "Disable Query Advisor" : "Enable Query Advisor",
|
||||
hasPopup: false,
|
||||
};
|
||||
buttons.push(toggleCopilotButton);
|
||||
}
|
||||
|
||||
if (!this.props.isPreferredApiMongoDB && this.state.isExecuting) {
|
||||
const label = "Cancel query";
|
||||
@@ -727,7 +725,6 @@ class QueryTabComponentImpl extends React.Component<QueryTabComponentImplProps,
|
||||
return (
|
||||
<Fragment>
|
||||
<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 && (
|
||||
<QueryCopilotPromptbar
|
||||
explorer={this.props.collection.container}
|
||||
@@ -735,7 +732,7 @@ class QueryTabComponentImpl extends React.Component<QueryTabComponentImplProps,
|
||||
databaseId={this.props.collection.databaseId}
|
||||
containerId={this.props.collection.id()}
|
||||
></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 */}
|
||||
<Allotment
|
||||
key={vertical.toString()}
|
||||
|
||||
@@ -21,7 +21,12 @@ import { useCommandBar } from "../Menus/CommandBar/CommandBarComponentAdapter";
|
||||
import { useSelectedNode } from "../useSelectedNode";
|
||||
|
||||
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} />;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { MongoGuidRepresentation } from "Common/Constants";
|
||||
import { SplitterDirection } from "Common/Splitter";
|
||||
import * as LocalStorageUtility from "./LocalStorageUtility";
|
||||
import * as SessionStorageUtility from "./SessionStorageUtility";
|
||||
@@ -34,7 +33,6 @@ export enum StorageKey {
|
||||
DocumentsTabPrefs,
|
||||
DefaultQueryResultsView,
|
||||
AppState,
|
||||
MongoGuidRepresentation,
|
||||
}
|
||||
|
||||
export const hasRUThresholdBeenConfigured = (): boolean => {
|
||||
@@ -67,13 +65,4 @@ export const getDefaultQueryResultsView = (): SplitterDirection => {
|
||||
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;
|
||||
|
||||
@@ -79,7 +79,22 @@ export const defaultAllowedCassandraProxyEndpoints: ReadonlyArray<string> = [
|
||||
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"];
|
||||
|
||||
|
||||
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 { configContext, Platform } from "ConfigContext";
|
||||
import { getRUThreshold, ruThresholdEnabled } from "Shared/StorageUtility";
|
||||
import { userContext } from "UserContext";
|
||||
import { logConsoleWarning } from "Utils/NotificationConsoleUtils";
|
||||
@@ -66,7 +67,11 @@ export function buildDocumentsQueryPartitionProjections(
|
||||
}
|
||||
});
|
||||
const fullAccess = `${collectionAlias}${projectedProperty}`;
|
||||
if (!isSystemPartitionKey) {
|
||||
if (
|
||||
!isSystemPartitionKey &&
|
||||
configContext.platform !== Platform.Emulator &&
|
||||
configContext.platform !== Platform.VNextEmulator
|
||||
) {
|
||||
const wrappedProjection = `IIF(IS_DEFINED(${fullAccess}), ${fullAccess}, {})`;
|
||||
projections.push(wrappedProjection);
|
||||
} else {
|
||||
|
||||
@@ -86,7 +86,7 @@ export function useKnockoutExplorer(platform: Platform): Explorer {
|
||||
let explorer: Explorer;
|
||||
if (platform === Platform.Hosted) {
|
||||
explorer = await configureHosted();
|
||||
} else if (platform === Platform.Emulator) {
|
||||
} else if (platform === Platform.Emulator || platform === Platform.VNextEmulator) {
|
||||
explorer = configureEmulator();
|
||||
} else if (platform === Platform.Portal) {
|
||||
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",
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"lib": [
|
||||
"es5",
|
||||
"es6",
|
||||
"dom"
|
||||
],
|
||||
"lib": ["es5", "es6", "dom"],
|
||||
"jsx": "react",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"noEmit": true,
|
||||
"types": [
|
||||
"jest"
|
||||
],
|
||||
"types": ["jest"],
|
||||
"baseUrl": "src"
|
||||
},
|
||||
"typedocOptions": {
|
||||
@@ -43,17 +37,11 @@
|
||||
"includes": "./src/SelfServe/Documentation",
|
||||
"disableSources": true
|
||||
},
|
||||
"include": [
|
||||
"src",
|
||||
"./src/**/*",
|
||||
"./utils/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"./src/**/__mocks__/**/*"
|
||||
],
|
||||
"include": ["src", "./src/**/*", "./utils/**/*"],
|
||||
"exclude": ["./src/**/__mocks__/**/*", "./utils/local-proxy/**/*"],
|
||||
"ts-node": {
|
||||
"compilerOptions": {
|
||||
"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 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) {
|
||||
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" }),
|
||||
};
|
||||
|
||||
// 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 = [
|
||||
new HtmlWebpackPlugin({
|
||||
filename: "explorer.html",
|
||||
@@ -131,10 +150,16 @@ module.exports = function (_env = {}, argv = {}) {
|
||||
template: "src/Terminal/index.html",
|
||||
chunks: ["terminal"],
|
||||
}),
|
||||
//todo - dynamically include apis
|
||||
new HtmlWebpackPlugin({
|
||||
filename: "quickstart.html",
|
||||
template: "src/quickstart.html",
|
||||
template: "src/quickstart-sql.template.ejs",
|
||||
chunks: ["quickstart"],
|
||||
templateParameters: {
|
||||
endpointUri,
|
||||
primaryKey: primaryKeyConst,
|
||||
primaryConnString,
|
||||
},
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
filename: "index.html",
|
||||
@@ -211,11 +236,20 @@ module.exports = function (_env = {}, argv = {}) {
|
||||
{ from: "DataExplorer.proj" },
|
||||
{ from: "web.config" },
|
||||
{ from: "quickstart/*.zip" },
|
||||
{ from: "images", to: "images" },
|
||||
],
|
||||
}),
|
||||
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) {
|
||||
plugins.push(new BundleAnalyzerPlugin());
|
||||
}
|
||||
@@ -280,7 +314,7 @@ module.exports = function (_env = {}, argv = {}) {
|
||||
// disableHostCheck: true,
|
||||
liveReload: !isCI,
|
||||
server: {
|
||||
type: "https",
|
||||
type: ishttps ? "https" : "http",
|
||||
},
|
||||
host: "0.0.0.0",
|
||||
port: envVars.PORT,
|
||||
|
||||
Reference in New Issue
Block a user