mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-10-16 14:50:15 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
055597c1ff | ||
|
|
f75a4695be | ||
|
|
0cbaaed9e1 | ||
|
|
295fcf8701 | ||
|
|
ba4f1c9db7 | ||
|
|
bde5c93740 | ||
|
|
2421e4806a | ||
|
|
27a9cf3d58 | ||
|
|
cddbb1c876 | ||
|
|
2ab9d2f450 | ||
|
|
750d66c4ae | ||
|
|
844c01dc75 | ||
|
|
154082e6bd | ||
|
|
5d90858fa3 | ||
|
|
0ae505fd32 | ||
|
|
7b0c6ebe66 | ||
|
|
591083435d | ||
|
|
d23959a9b5 | ||
|
|
1799768389 | ||
|
|
250547f329 | ||
|
|
4f52c445fc | ||
|
|
0c70890258 | ||
|
|
bc656de886 | ||
|
|
fb6e6f6f13 | ||
|
|
a0d79ff9b1 | ||
|
|
f5dfd8726a | ||
|
|
0095cc8d37 | ||
|
|
16fcc21346 | ||
|
|
f5e4f14159 | ||
|
|
0c1d47ef10 | ||
|
|
2d82e85491 | ||
|
|
87e9c79e43 | ||
|
|
c3042d5aa4 |
@@ -7,7 +7,7 @@ CloudBeaver is a web server that provides a rich web interface. The server itsel
|
||||
It is free to use and open-source (licensed under [Apache 2](https://github.com/dbeaver/cloudbeaver/blob/devel/LICENSE) license).
|
||||
See our [WIKI](https://github.com/dbeaver/cloudbeaver/wiki) for more details.
|
||||
|
||||
<img src="https://github.com/dbeaver/cloudbeaver/wiki/images/connection-creation-demo.png" width="400"/>
|
||||
<a><img src="https://github.com/dbeaver/cloudbeaver/wiki/images/connection-creation-demo.png" width="400"/></a>
|
||||
<img src="https://github.com/dbeaver/cloudbeaver/wiki/images/gis-demo.png" width="400"/>
|
||||
<img src="https://github.com/dbeaver/cloudbeaver/wiki/images/data-transfer-demo.png" width="400"/>
|
||||
<img src="https://github.com/dbeaver/cloudbeaver/wiki/images/sql-editor-demo.png" width="400"/>
|
||||
@@ -25,13 +25,19 @@ You can see a live demo of CloudBeaver here: https://demo.cloudbeaver.io
|
||||
|
||||
## Changelog
|
||||
|
||||
### 25.0.4 2025-05-05
|
||||
- Important:
|
||||
- Connection templates were removed from the application. You can use the Connection Editor to create new connections.
|
||||
- Databases and drivers:
|
||||
- LibSQL: added the ability to use token authentication for connecting;
|
||||
- Clickhouse: driver has been updated to version 0.8.5.
|
||||
|
||||
### 25.0.3 2025-04-21
|
||||
- Administration: log records now capture create, update, and delete actions for users, teams, and connections for improved tracking and transparency;
|
||||
- SQL Editor: auto-completion has been improved for aliases and camelCase entities;
|
||||
- Users DDL in Oracle is displayed in metadata editor on corresponding tab for users with Oracle administration permissions;
|
||||
- Different bug fixes and enhancements have been made.
|
||||
|
||||
|
||||
### 25.0.2 2025-04-07
|
||||
- Data Editor: improved table rendering to scale column width depending on the content.
|
||||
- Improved Navigation tree performance: lost connection does not lead to the application freezing anymore.
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
# artifacts
|
||||
lib
|
||||
out
|
||||
dist
|
||||
node_modules
|
||||
|
||||
# Yarn
|
||||
.yarn/*
|
||||
!.yarn/patches
|
||||
!.yarn/plugins
|
||||
!.yarn/releases
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
!.yarn/sdks/**
|
||||
|
||||
# Swap the comments on the following lines if you wish to use zero-installs
|
||||
# In that case, don't forget to run `yarn config set enableGlobalCache false`!
|
||||
@@ -11,9 +19,3 @@
|
||||
|
||||
#!.yarn/cache
|
||||
.pnp.*
|
||||
|
||||
# artifacts
|
||||
lib
|
||||
out
|
||||
dist
|
||||
node_modules
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "prettier",
|
||||
"version": "3.5.1-sdk",
|
||||
"version": "3.5.3-sdk",
|
||||
"main": "./index.cjs",
|
||||
"type": "commonjs",
|
||||
"bin": "./bin/prettier.cjs"
|
||||
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const {existsSync} = require(`fs`);
|
||||
const {createRequire, register} = require(`module`);
|
||||
const {resolve} = require(`path`);
|
||||
const {pathToFileURL} = require(`url`);
|
||||
|
||||
const relPnpApiPath = "../../../../.pnp.cjs";
|
||||
|
||||
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
|
||||
const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
|
||||
const absRequire = createRequire(absPnpApiPath);
|
||||
|
||||
const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
|
||||
const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
|
||||
|
||||
if (existsSync(absPnpApiPath)) {
|
||||
if (!process.versions.pnp) {
|
||||
// Setup the environment to be able to require typescript/bin/tsserver
|
||||
require(absPnpApiPath).setup();
|
||||
if (isPnpLoaderEnabled && register) {
|
||||
register(pathToFileURL(absPnpLoaderPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const wrapWithUserWrapper = existsSync(absUserWrapperPath)
|
||||
? exports => absRequire(absUserWrapperPath)(exports)
|
||||
: exports => exports;
|
||||
|
||||
// Defer to the real typescript/bin/tsserver your application uses
|
||||
module.exports = wrapWithUserWrapper(absRequire(`typescript/bin/tsserver`));
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"name": "typescript",
|
||||
"version": "5.7.3-sdk",
|
||||
"main": "./lib/typescript.js",
|
||||
"type": "commonjs",
|
||||
"bin": {
|
||||
"tsc": "./bin/tsc",
|
||||
"tsserver": "./bin/tsserver"
|
||||
}
|
||||
}
|
||||
@@ -100,7 +100,6 @@
|
||||
--dbv-kit-btn-background-active: var(--dbv-kit-btn-primary-background-active);
|
||||
|
||||
--dbv-kit-btn-loader-color: var(--dbv-kit-btn-background-hover);
|
||||
--dbv-kit-btn-loader-background: var(--dbv-kit-btn-loader-base-color);
|
||||
}
|
||||
|
||||
.dbv-kit-button--secondary {
|
||||
@@ -111,7 +110,6 @@
|
||||
--dbv-kit-btn-border-color: var(--dbv-kit-btn-secondary-border-color);
|
||||
|
||||
--dbv-kit-btn-loader-color: var(--dbv-kit-btn-secondary-foreground);
|
||||
--dbv-kit-btn-loader-background: var(--dbv-kit-btn-secondary-background-active);
|
||||
}
|
||||
|
||||
.dbv-kit-button--danger {
|
||||
@@ -121,7 +119,6 @@
|
||||
--dbv-kit-btn-background-active: var(--dbv-kit-btn-danger-background-active);
|
||||
|
||||
--dbv-kit-btn-loader-color: var(--dbv-kit-btn-danger-background);
|
||||
--dbv-kit-btn-loader-background: var(--dbv-kit-btn-loader-base-color);
|
||||
--dbv-kit-btn-outline-color: var(--dbv-kit-btn-danger-color-outline);
|
||||
}
|
||||
|
||||
@@ -141,25 +138,11 @@
|
||||
}
|
||||
|
||||
.dbv-kit-button__loader {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
pointer-events: none;
|
||||
--dbv-kit-spinner-stroke-color: var(--dbv-kit-btn-loader-color);
|
||||
--dbv-kit-spinner-height: calc(var(--dbv-kit-btn-height) * 0.6);
|
||||
--dbv-kit-spinner-stroke-width: 3px;
|
||||
|
||||
&::after {
|
||||
--loader-width: calc(var(--dbv-kit-btn-font-size) * 0.2);
|
||||
content: '';
|
||||
border: var(--loader-width) solid var(--dbv-kit-btn-loader-background);
|
||||
border-top: var(--loader-width) solid var(--dbv-kit-btn-loader-color);
|
||||
border-radius: 50%;
|
||||
opacity: 1;
|
||||
width: calc(var(--dbv-kit-btn-font-size) * 1.25);
|
||||
height: calc(var(--dbv-kit-btn-font-size) * 1.25);
|
||||
animation: var(--dbv-kit-btn-loader-animation);
|
||||
}
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
/* ---------------------------- */
|
||||
|
||||
@@ -10,6 +10,7 @@ import clsx from 'clsx';
|
||||
import './Button.css';
|
||||
import type { ControlSize } from '../types/controls.js';
|
||||
import { componentProviderWrapper } from '../componentProviderWrapper.js';
|
||||
import { Spinner } from '../Spinner/Spinner.js';
|
||||
|
||||
export interface ButtonProps extends Omit<AriaKitButtonProps, 'clickOnEnter' | 'clickOnSpace'> {
|
||||
variant?: 'primary' | 'secondary' | 'danger';
|
||||
@@ -28,7 +29,7 @@ export function ButtonBase({ className, variant = 'primary', size = 'medium', lo
|
||||
|
||||
return (
|
||||
<AriaButton onClick={loading ? () => null : onClick} className={classToApply} {...props}>
|
||||
{loading && (loader ? loader : <span className="dbv-kit-button__loader" />)}
|
||||
{loading && (loader ? loader : <Spinner className="dbv-kit-button__loader" />)}
|
||||
{children}
|
||||
</AriaButton>
|
||||
);
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
--dbv-kit-btn-font-weight: var(--tw-font-weight-normal);
|
||||
--dbv-kit-btn-font-size: calc(var(--dbv-kit-font-size-base) * 0.875);
|
||||
|
||||
--dbv-kit-btn-loader-base-color: var(--tw-color-white);
|
||||
--dbv-kit-btn-loader-animation: var(--tw-animate-spin);
|
||||
--dbv-kit-btn-loader-base-color: var(--dbv-kit-btn-foreground);
|
||||
--dbv-kit-btn-loader-height: calc(var(--dbv-kit-btn-height) * 0.6);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
@import './_base.css';
|
||||
@import './_sizes.css';
|
||||
|
||||
@layer base {
|
||||
.dbv-kit-spinner {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: var(--dbv-kit-spinner-height);
|
||||
height: var(--dbv-kit-spinner-height);
|
||||
}
|
||||
|
||||
.dbv-kit-spinner--small {
|
||||
width: var(--dbv-kit-spinner-small-height);
|
||||
height: var(--dbv-kit-spinner-small-height);
|
||||
}
|
||||
|
||||
.dbv-kit-spinner--medium {
|
||||
width: var(--dbv-kit-spinner-medium-height);
|
||||
height: var(--dbv-kit-spinner-medium-height);
|
||||
}
|
||||
|
||||
.dbv-kit-spinner--large {
|
||||
width: var(--dbv-kit-spinner-large-height);
|
||||
height: var(--dbv-kit-spinner-large-height);
|
||||
}
|
||||
|
||||
.dbv-kit-spinner--xlarge {
|
||||
width: var(--dbv-kit-spinner-xlarge-height);
|
||||
height: var(--dbv-kit-spinner-xlarge-height);
|
||||
}
|
||||
|
||||
.dbv-kit-spinner__svg {
|
||||
stroke-dasharray: 40px, 100px;
|
||||
stroke-dashoffset: 5px;
|
||||
stroke-width: var(--dbv-kit-spinner-stroke-width);
|
||||
stroke: var(--dbv-kit-spinner-stroke-color);
|
||||
stroke-linecap: var(--dbv-kit-spinner-stroke-linecap);
|
||||
|
||||
animation: var(--dbv-kit-animate-spin);
|
||||
}
|
||||
|
||||
.dbv-kit-spinner__circle {
|
||||
animation: var(--dbv-kit-animate-stroke);
|
||||
|
||||
@media screen and (prefers-reduced-motion: reduce) {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import clsx from 'clsx';
|
||||
import './Spinner.css';
|
||||
import type { ControlSize } from '../types/controls.js';
|
||||
|
||||
export interface SpinnerProps {
|
||||
active?: boolean;
|
||||
className?: string;
|
||||
size?: ControlSize;
|
||||
}
|
||||
|
||||
export function Spinner({ className, size, active = true }: SpinnerProps) {
|
||||
if (!active) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<span className={clsx('dbv-kit-spinner', size && `dbv-kit-spinner--${size}`, className)}>
|
||||
<svg className="dbv-kit-spinner__svg" viewBox="11 11 22 22">
|
||||
<circle className="dbv-kit-spinner__circle" cx="22" cy="22" r="9" fill="none"></circle>
|
||||
</svg>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
@keyframes stroke {
|
||||
0% {
|
||||
stroke-dasharray: 1px, 100px;
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
50% {
|
||||
stroke-dasharray: 45px, 100px;
|
||||
stroke-dashoffset: -10px;
|
||||
}
|
||||
100% {
|
||||
stroke-dasharray: 17px, 100px;
|
||||
stroke-dashoffset: -58px;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spinning {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
--dbv-kit-spinner-height: var(--dbv-kit-control-height-medium);
|
||||
--dbv-kit-spinner-animation-duration: 1.8s;
|
||||
|
||||
--dbv-kit-spinner-stroke-width: 2.5px;
|
||||
--dbv-kit-spinner-stroke-color: var(--dbv-kit-color-primary-600);
|
||||
--dbv-kit-spinner-stroke-linecap: butt;
|
||||
|
||||
--dbv-kit-animate-stroke: stroke var(--dbv-kit-spinner-animation-duration) linear infinite;
|
||||
--dbv-kit-animate-spin: spinning var(--dbv-kit-spinner-animation-duration) cubic-bezier(0.455, 0.03, 0.515, 0.955) infinite;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
@layer base {
|
||||
:root {
|
||||
--dbv-kit-spinner-small-height: var(--dbv-kit-control-height-small);
|
||||
--dbv-kit-spinner-medium-height: var(--dbv-kit-control-height-medium);
|
||||
--dbv-kit-spinner-large-height: var(--dbv-kit-control-height-large);
|
||||
--dbv-kit-spinner-xlarge-height: var(--dbv-kit-control-height-xlarge);
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,7 @@ export {
|
||||
type SelectItemProps,
|
||||
} from './Select/Select.js';
|
||||
export { SelectField, type SelectFieldProps, type SelectItem } from './Select/SelectField.js';
|
||||
export { Spinner, type SpinnerProps } from './Spinner/Spinner.js';
|
||||
export { Radio, RadioGroup, useRadioContext, useRadioStore, type RadioProviderProps, type RadioProps, type RadioGroupProps } from './Radio/index.js';
|
||||
export * from './utils/clsx.js';
|
||||
export * from './ComponentProvider.js';
|
||||
|
||||
@@ -254,11 +254,11 @@ export const Icons = () => (
|
||||
);
|
||||
|
||||
const CustomLoader = () => (
|
||||
<Button.Icon placement="start">
|
||||
<div>
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" className="tw:animate-spin tw:p-1">
|
||||
<circle cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeDasharray="31.415, 31.415" />
|
||||
</svg>
|
||||
</Button.Icon>
|
||||
</div>
|
||||
);
|
||||
|
||||
export const Loading = () => {
|
||||
@@ -280,9 +280,7 @@ export const Loading = () => {
|
||||
and one of the dark colors for dark theme.
|
||||
</span>
|
||||
</p>
|
||||
<div>
|
||||
<code>--dbv-kit-btn-loader-animation:</code> var(--animate-spin); <span className="comment"> Button loader animation</span>
|
||||
</div>
|
||||
|
||||
<label>
|
||||
Enable loaders <input type="checkbox" checked={loading} onChange={toggleLoading} />
|
||||
</label>
|
||||
|
||||
@@ -61,9 +61,13 @@ export const States = () => {
|
||||
</Checkbox>
|
||||
<Button onClick={() => setIndeterminate(prev => !prev)}>Set Indeterminate</Button>
|
||||
<Checkbox indeterminate={indeterminate}>Indeterminate</Checkbox>
|
||||
<Checkbox indeterminate={indeterminate} indeterminateIcon={<div className="tw:flex tw:relative tw:-top-[1px] tw:font-bold">▫</div>}>
|
||||
<Checkbox
|
||||
indeterminate={indeterminate}
|
||||
indeterminateIcon={<div className="tw:flex tw:relative tw:-top-[2px] tw:-left-[1px] tw:font-bold">▫</div>}
|
||||
>
|
||||
Indeterminate Custom
|
||||
</Checkbox>
|
||||
Long text example:
|
||||
<Checkbox>
|
||||
Insert spaces when pressing <code>Tab</code>. This setting is overridden based on the file contents when{' '}
|
||||
<a data-href="#" href="#">
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
.customLoader {
|
||||
--dbv-kit-spinner-stroke-color: orange;
|
||||
--dbv-kit-spinner-animation-duration: 5s;
|
||||
--dbv-kit-animate-stroke: stroke var(--dbv-kit-spinner-animation-duration) linear infinite;
|
||||
--dbv-kit-animate-spin: spinning var(--dbv-kit-spinner-animation-duration) cubic-bezier(0.455, 0.03, 0.515, 0.955) infinite;
|
||||
--dbv-kit-spinner-stroke-linecap: round;
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
import { Spinner } from '../../../index.js';
|
||||
import './spinner.stories.css';
|
||||
|
||||
export function Documentation() {
|
||||
return (
|
||||
<div>
|
||||
<h1>Spin</h1>
|
||||
<p>Loading spinner component.</p>
|
||||
<h2>Usage</h2>
|
||||
<p>Use the Spin component to indicate loading state.</p>
|
||||
<h2>Anatomy</h2>
|
||||
<p>
|
||||
The Spin component consists of an SVG element with a circle that rotates to indicate loading. The spinner can be customized with different
|
||||
sizes and colors. The spinner is animated using CSS animations.
|
||||
</p>
|
||||
<pre className="codeblock">
|
||||
{`
|
||||
<span class="dbv-kit-spinner">
|
||||
<svg class="dbv-kit-spinner__svg">
|
||||
<circle class="dbv-kit-spinner__circle" />
|
||||
</svg>
|
||||
</span>
|
||||
`}
|
||||
</pre>
|
||||
<h2>Class names</h2>
|
||||
<p>
|
||||
The Spin component uses the following class names:
|
||||
<ul>
|
||||
<li>
|
||||
<code>dbv-kit-spinner</code>: Base class for the spinner.
|
||||
</li>
|
||||
<li>
|
||||
<code>dbv-kit-spinner--small</code>: Small size variant.
|
||||
</li>
|
||||
<li>
|
||||
<code>dbv-kit-spinner--medium</code>: Medium size variant.
|
||||
</li>
|
||||
<li>
|
||||
<code>dbv-kit-spinner--large</code>: Large size variant.
|
||||
</li>
|
||||
<li>
|
||||
<code>dbv-kit-spinner--xlarge</code>: Extra large size variant.
|
||||
</li>
|
||||
<li>
|
||||
<code>dbv-kit-spinner__svg</code>: SVG element for the spinner.
|
||||
</li>
|
||||
<li>
|
||||
<code>dbv-kit-spinner__circle</code>: Circle element for the spinner.
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
<h2>Example</h2>
|
||||
<pre className="codeblock">{`<Spin />`}</pre>
|
||||
<h2>Props</h2>
|
||||
<table className="tw:w-full tw:table-auto">
|
||||
<thead>
|
||||
<tr>
|
||||
<th className="tw:py-2">Prop</th>
|
||||
<th className="tw:py-2">Type</th>
|
||||
<th className="tw:py-2">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="tw:border tw:p-2">size</td>
|
||||
<td className="tw:border tw:p-2">
|
||||
<pre> small | medium | large | xlarge | undefined</pre>{' '}
|
||||
</td>
|
||||
<td className="tw:border tw:p-2">Size of the spinner.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="tw:border tw:p-2">className</td>
|
||||
<td className="tw:border tw:p-2">
|
||||
<pre> string | undefined</pre>{' '}
|
||||
</td>
|
||||
<td className="tw:border tw:p-2">Additional class name for the spinner.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="tw:border tw:p-2">enabled</td>
|
||||
<td className="tw:border tw:p-2">
|
||||
<pre> true | false | undefined</pre>{' '}
|
||||
</td>
|
||||
<td className="tw:border tw:p-2">When we want to keep Spin component in the DOM but control </td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export function Sizes() {
|
||||
return (
|
||||
<div>
|
||||
<h1>Spin Sizes</h1>
|
||||
<div className="tw:flex tw:flex-col tw:gap-4">
|
||||
<div>
|
||||
<p>small</p> <Spinner size="small" />
|
||||
</div>
|
||||
<div>
|
||||
<p>medium</p> <Spinner size="medium" />
|
||||
</div>
|
||||
<div>
|
||||
<p>large</p> <Spinner size="large" />
|
||||
</div>
|
||||
<div>
|
||||
<p>xlarge</p> <Spinner size="xlarge" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function Tokens() {
|
||||
return (
|
||||
<div>
|
||||
<h1>Spin Tokens</h1>
|
||||
<p>Spin component uses the following CSS custom properties:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<code>--dbv-kit-spinner-height</code>: Controls the height of the spinner (default: var(--dbv-kit-control-height-medium))
|
||||
</li>
|
||||
<li>
|
||||
<code>--dbv-kit-spinner-stroke-width</code>: Specifies the width of the spinner's stroke (default: 2.5px)
|
||||
</li>
|
||||
<li>
|
||||
<code>--dbv-kit-spinner-stroke-color</code>: Sets the color of the spinner's stroke (default: var(--dbv-kit-color-primary-600))
|
||||
</li>
|
||||
<li>
|
||||
<code>--dbv-kit-spinner-stroke-linecap</code>: Defines the stroke-linecap of the spinner's stroke (default: butt)
|
||||
</li>
|
||||
<code>--dbv-kit-spinner-stroke-color-secondary</code>: Sets the color of the spinner's secondary stroke (default:
|
||||
var(--dbv-kit-color-primary-200))
|
||||
<li>
|
||||
<code>--dbv-kit-spinner-animation-duration</code>: Controls the duration of the spinner's animation (default: 1.8s)
|
||||
</li>
|
||||
<li>
|
||||
<code>--dbv-kit-animate-stroke</code>: Defines the animation for the spinner's stroke
|
||||
</li>
|
||||
<li>
|
||||
<code>--dbv-kit-animate-spin</code>: Defines the animation for the spinner's rotation
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function SpecialLoader() {
|
||||
return (
|
||||
<div className="tw:flex tw:h-screen tw:items-center tw:justify-center">
|
||||
<div className="tw:flex tw:flex-col tw:gap-1 tw:w-32">
|
||||
<div className="tw:relative tw:flex tw:items-center tw:justify-center tw:w-32 tw:h-32 ">
|
||||
<span className="tw:text-6xl">😜</span>
|
||||
<Spinner className="tw:absolute tw:w-full tw:h-full customLoader" />
|
||||
</div>
|
||||
<p className="tw:text-center">Loading...</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -12,8 +12,7 @@
|
||||
"devDependencies": {
|
||||
"@dbeaver/prettier-config": "workspace:^",
|
||||
"@wroud/ts-template": "^0",
|
||||
"prettier": "^3.5.1",
|
||||
"rimraf": "^6",
|
||||
"typescript": "^5.7.3"
|
||||
"prettier": "^3.5.3",
|
||||
"rimraf": "^6"
|
||||
}
|
||||
}
|
||||
|
||||
+8
-10
@@ -2677,9 +2677,8 @@ __metadata:
|
||||
dependencies:
|
||||
"@dbeaver/prettier-config": "workspace:^"
|
||||
"@wroud/ts-template": "npm:^0"
|
||||
prettier: "npm:^3.5.1"
|
||||
prettier: "npm:^3.5.3"
|
||||
rimraf: "npm:^6"
|
||||
typescript: "npm:^5.7.3"
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
@@ -2690,9 +2689,8 @@ __metadata:
|
||||
"@dbeaver/cli": "workspace:^"
|
||||
"@dbeaver/prettier-config": "workspace:^"
|
||||
"@wroud/ts-template": "npm:^0"
|
||||
prettier: "npm:^3.5.1"
|
||||
prettier: "npm:^3.5.3"
|
||||
rimraf: "npm:^6"
|
||||
typescript: "npm:^5.7.3"
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
@@ -5996,12 +5994,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"prettier@npm:^3.5.1":
|
||||
version: 3.5.1
|
||||
resolution: "prettier@npm:3.5.1"
|
||||
"prettier@npm:^3.5.3":
|
||||
version: 3.5.3
|
||||
resolution: "prettier@npm:3.5.3"
|
||||
bin:
|
||||
prettier: bin/prettier.cjs
|
||||
checksum: 10c0/9f6f810eae455d6e4213845151a484a2338f2e0d6a8b84ee8e13a83af8a2421ef6c1e31e61e4b135671fb57b9541f6624648880cc2061ac803e243ac898c0123
|
||||
checksum: 10c0/3880cb90b9dc0635819ab52ff571518c35bd7f15a6e80a2054c05dbc8a3aa6e74f135519e91197de63705bcb38388ded7e7230e2178432a1468005406238b877
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -7114,7 +7112,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"typescript@npm:^5, typescript@npm:^5.7.3":
|
||||
"typescript@npm:^5":
|
||||
version: 5.7.3
|
||||
resolution: "typescript@npm:5.7.3"
|
||||
bin:
|
||||
@@ -7124,7 +7122,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"typescript@patch:typescript@npm%3A^5#optional!builtin<compat/typescript>, typescript@patch:typescript@npm%3A^5.7.3#optional!builtin<compat/typescript>":
|
||||
"typescript@patch:typescript@npm%3A^5#optional!builtin<compat/typescript>":
|
||||
version: 5.7.3
|
||||
resolution: "typescript@patch:typescript@npm%3A5.7.3#optional!builtin<compat/typescript>::version=5.7.3&hash=5786d5"
|
||||
bin:
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
# artifacts
|
||||
lib
|
||||
out
|
||||
dist
|
||||
node_modules
|
||||
|
||||
# Yarn
|
||||
.yarn/*
|
||||
!.yarn/patches
|
||||
!.yarn/plugins
|
||||
!.yarn/releases
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
!.yarn/sdks/**
|
||||
|
||||
# Swap the comments on the following lines if you wish to use zero-installs
|
||||
# In that case, don't forget to run `yarn config set enableGlobalCache false`!
|
||||
@@ -11,9 +19,3 @@
|
||||
|
||||
#!.yarn/cache
|
||||
.pnp.*
|
||||
|
||||
# artifacts
|
||||
lib
|
||||
out
|
||||
dist
|
||||
node_modules
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "prettier",
|
||||
"version": "3.5.1-sdk",
|
||||
"version": "3.5.3-sdk",
|
||||
"main": "./index.cjs",
|
||||
"type": "commonjs",
|
||||
"bin": "./bin/prettier.cjs"
|
||||
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const {existsSync} = require(`fs`);
|
||||
const {createRequire, register} = require(`module`);
|
||||
const {resolve} = require(`path`);
|
||||
const {pathToFileURL} = require(`url`);
|
||||
|
||||
const relPnpApiPath = "../../../../.pnp.cjs";
|
||||
|
||||
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
|
||||
const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
|
||||
const absRequire = createRequire(absPnpApiPath);
|
||||
|
||||
const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
|
||||
const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
|
||||
|
||||
if (existsSync(absPnpApiPath)) {
|
||||
if (!process.versions.pnp) {
|
||||
// Setup the environment to be able to require typescript/bin/tsc
|
||||
require(absPnpApiPath).setup();
|
||||
if (isPnpLoaderEnabled && register) {
|
||||
register(pathToFileURL(absPnpLoaderPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const wrapWithUserWrapper = existsSync(absUserWrapperPath)
|
||||
? exports => absRequire(absUserWrapperPath)(exports)
|
||||
: exports => exports;
|
||||
|
||||
// Defer to the real typescript/bin/tsc your application uses
|
||||
module.exports = wrapWithUserWrapper(absRequire(`typescript/bin/tsc`));
|
||||
@@ -1,32 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const {existsSync} = require(`fs`);
|
||||
const {createRequire, register} = require(`module`);
|
||||
const {resolve} = require(`path`);
|
||||
const {pathToFileURL} = require(`url`);
|
||||
|
||||
const relPnpApiPath = "../../../../.pnp.cjs";
|
||||
|
||||
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
|
||||
const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
|
||||
const absRequire = createRequire(absPnpApiPath);
|
||||
|
||||
const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
|
||||
const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
|
||||
|
||||
if (existsSync(absPnpApiPath)) {
|
||||
if (!process.versions.pnp) {
|
||||
// Setup the environment to be able to require typescript/bin/tsserver
|
||||
require(absPnpApiPath).setup();
|
||||
if (isPnpLoaderEnabled && register) {
|
||||
register(pathToFileURL(absPnpLoaderPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const wrapWithUserWrapper = existsSync(absUserWrapperPath)
|
||||
? exports => absRequire(absUserWrapperPath)(exports)
|
||||
: exports => exports;
|
||||
|
||||
// Defer to the real typescript/bin/tsserver your application uses
|
||||
module.exports = wrapWithUserWrapper(absRequire(`typescript/bin/tsserver`));
|
||||
@@ -1,32 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const {existsSync} = require(`fs`);
|
||||
const {createRequire, register} = require(`module`);
|
||||
const {resolve} = require(`path`);
|
||||
const {pathToFileURL} = require(`url`);
|
||||
|
||||
const relPnpApiPath = "../../../../.pnp.cjs";
|
||||
|
||||
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
|
||||
const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
|
||||
const absRequire = createRequire(absPnpApiPath);
|
||||
|
||||
const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
|
||||
const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
|
||||
|
||||
if (existsSync(absPnpApiPath)) {
|
||||
if (!process.versions.pnp) {
|
||||
// Setup the environment to be able to require typescript/lib/tsc.js
|
||||
require(absPnpApiPath).setup();
|
||||
if (isPnpLoaderEnabled && register) {
|
||||
register(pathToFileURL(absPnpLoaderPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const wrapWithUserWrapper = existsSync(absUserWrapperPath)
|
||||
? exports => absRequire(absUserWrapperPath)(exports)
|
||||
: exports => exports;
|
||||
|
||||
// Defer to the real typescript/lib/tsc.js your application uses
|
||||
module.exports = wrapWithUserWrapper(absRequire(`typescript/lib/tsc.js`));
|
||||
@@ -1,248 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const {existsSync} = require(`fs`);
|
||||
const {createRequire, register} = require(`module`);
|
||||
const {resolve} = require(`path`);
|
||||
const {pathToFileURL} = require(`url`);
|
||||
|
||||
const relPnpApiPath = "../../../../.pnp.cjs";
|
||||
|
||||
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
|
||||
const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
|
||||
const absRequire = createRequire(absPnpApiPath);
|
||||
|
||||
const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
|
||||
const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
|
||||
|
||||
if (existsSync(absPnpApiPath)) {
|
||||
if (!process.versions.pnp) {
|
||||
// Setup the environment to be able to require typescript/lib/tsserver.js
|
||||
require(absPnpApiPath).setup();
|
||||
if (isPnpLoaderEnabled && register) {
|
||||
register(pathToFileURL(absPnpLoaderPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const wrapWithUserWrapper = existsSync(absUserWrapperPath)
|
||||
? exports => absRequire(absUserWrapperPath)(exports)
|
||||
: exports => exports;
|
||||
|
||||
const moduleWrapper = exports => {
|
||||
return wrapWithUserWrapper(moduleWrapperFn(exports));
|
||||
};
|
||||
|
||||
const moduleWrapperFn = tsserver => {
|
||||
if (!process.versions.pnp) {
|
||||
return tsserver;
|
||||
}
|
||||
|
||||
const {isAbsolute} = require(`path`);
|
||||
const pnpApi = require(`pnpapi`);
|
||||
|
||||
const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//);
|
||||
const isPortal = str => str.startsWith("portal:/");
|
||||
const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`);
|
||||
|
||||
const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => {
|
||||
return `${locator.name}@${locator.reference}`;
|
||||
}));
|
||||
|
||||
// VSCode sends the zip paths to TS using the "zip://" prefix, that TS
|
||||
// doesn't understand. This layer makes sure to remove the protocol
|
||||
// before forwarding it to TS, and to add it back on all returned paths.
|
||||
|
||||
function toEditorPath(str) {
|
||||
// We add the `zip:` prefix to both `.zip/` paths and virtual paths
|
||||
if (isAbsolute(str) && !str.match(/^\^?(zip:|\/zip\/)/) && (str.match(/\.zip\//) || isVirtual(str))) {
|
||||
// We also take the opportunity to turn virtual paths into physical ones;
|
||||
// this makes it much easier to work with workspaces that list peer
|
||||
// dependencies, since otherwise Ctrl+Click would bring us to the virtual
|
||||
// file instances instead of the real ones.
|
||||
//
|
||||
// We only do this to modules owned by the the dependency tree roots.
|
||||
// This avoids breaking the resolution when jumping inside a vendor
|
||||
// with peer dep (otherwise jumping into react-dom would show resolution
|
||||
// errors on react).
|
||||
//
|
||||
const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str;
|
||||
if (resolved) {
|
||||
const locator = pnpApi.findPackageLocator(resolved);
|
||||
if (locator && (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || isPortal(locator.reference))) {
|
||||
str = resolved;
|
||||
}
|
||||
}
|
||||
|
||||
str = normalize(str);
|
||||
|
||||
if (str.match(/\.zip\//)) {
|
||||
switch (hostInfo) {
|
||||
// Absolute VSCode `Uri.fsPath`s need to start with a slash.
|
||||
// VSCode only adds it automatically for supported schemes,
|
||||
// so we have to do it manually for the `zip` scheme.
|
||||
// The path needs to start with a caret otherwise VSCode doesn't handle the protocol
|
||||
//
|
||||
// Ref: https://github.com/microsoft/vscode/issues/105014#issuecomment-686760910
|
||||
//
|
||||
// 2021-10-08: VSCode changed the format in 1.61.
|
||||
// Before | ^zip:/c:/foo/bar.zip/package.json
|
||||
// After | ^/zip//c:/foo/bar.zip/package.json
|
||||
//
|
||||
// 2022-04-06: VSCode changed the format in 1.66.
|
||||
// Before | ^/zip//c:/foo/bar.zip/package.json
|
||||
// After | ^/zip/c:/foo/bar.zip/package.json
|
||||
//
|
||||
// 2022-05-06: VSCode changed the format in 1.68
|
||||
// Before | ^/zip/c:/foo/bar.zip/package.json
|
||||
// After | ^/zip//c:/foo/bar.zip/package.json
|
||||
//
|
||||
case `vscode <1.61`: {
|
||||
str = `^zip:${str}`;
|
||||
} break;
|
||||
|
||||
case `vscode <1.66`: {
|
||||
str = `^/zip/${str}`;
|
||||
} break;
|
||||
|
||||
case `vscode <1.68`: {
|
||||
str = `^/zip${str}`;
|
||||
} break;
|
||||
|
||||
case `vscode`: {
|
||||
str = `^/zip/${str}`;
|
||||
} break;
|
||||
|
||||
// To make "go to definition" work,
|
||||
// We have to resolve the actual file system path from virtual path
|
||||
// and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip)
|
||||
case `coc-nvim`: {
|
||||
str = normalize(resolved).replace(/\.zip\//, `.zip::`);
|
||||
str = resolve(`zipfile:${str}`);
|
||||
} break;
|
||||
|
||||
// Support neovim native LSP and [typescript-language-server](https://github.com/theia-ide/typescript-language-server)
|
||||
// We have to resolve the actual file system path from virtual path,
|
||||
// everything else is up to neovim
|
||||
case `neovim`: {
|
||||
str = normalize(resolved).replace(/\.zip\//, `.zip::`);
|
||||
str = `zipfile://${str}`;
|
||||
} break;
|
||||
|
||||
default: {
|
||||
str = `zip:${str}`;
|
||||
} break;
|
||||
}
|
||||
} else {
|
||||
str = str.replace(/^\/?/, process.platform === `win32` ? `` : `/`);
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
function fromEditorPath(str) {
|
||||
switch (hostInfo) {
|
||||
case `coc-nvim`: {
|
||||
str = str.replace(/\.zip::/, `.zip/`);
|
||||
// The path for coc-nvim is in format of /<pwd>/zipfile:/<pwd>/.yarn/...
|
||||
// So in order to convert it back, we use .* to match all the thing
|
||||
// before `zipfile:`
|
||||
return process.platform === `win32`
|
||||
? str.replace(/^.*zipfile:\//, ``)
|
||||
: str.replace(/^.*zipfile:/, ``);
|
||||
} break;
|
||||
|
||||
case `neovim`: {
|
||||
str = str.replace(/\.zip::/, `.zip/`);
|
||||
// The path for neovim is in format of zipfile:///<pwd>/.yarn/...
|
||||
return str.replace(/^zipfile:\/\//, ``);
|
||||
} break;
|
||||
|
||||
case `vscode`:
|
||||
default: {
|
||||
return str.replace(/^\^?(zip:|\/zip(\/ts-nul-authority)?)\/+/, process.platform === `win32` ? `` : `/`)
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
// Force enable 'allowLocalPluginLoads'
|
||||
// TypeScript tries to resolve plugins using a path relative to itself
|
||||
// which doesn't work when using the global cache
|
||||
// https://github.com/microsoft/TypeScript/blob/1b57a0395e0bff191581c9606aab92832001de62/src/server/project.ts#L2238
|
||||
// VSCode doesn't want to enable 'allowLocalPluginLoads' due to security concerns but
|
||||
// TypeScript already does local loads and if this code is running the user trusts the workspace
|
||||
// https://github.com/microsoft/vscode/issues/45856
|
||||
const ConfiguredProject = tsserver.server.ConfiguredProject;
|
||||
const {enablePluginsWithOptions: originalEnablePluginsWithOptions} = ConfiguredProject.prototype;
|
||||
ConfiguredProject.prototype.enablePluginsWithOptions = function() {
|
||||
this.projectService.allowLocalPluginLoads = true;
|
||||
return originalEnablePluginsWithOptions.apply(this, arguments);
|
||||
};
|
||||
|
||||
// And here is the point where we hijack the VSCode <-> TS communications
|
||||
// by adding ourselves in the middle. We locate everything that looks
|
||||
// like an absolute path of ours and normalize it.
|
||||
|
||||
const Session = tsserver.server.Session;
|
||||
const {onMessage: originalOnMessage, send: originalSend} = Session.prototype;
|
||||
let hostInfo = `unknown`;
|
||||
|
||||
Object.assign(Session.prototype, {
|
||||
onMessage(/** @type {string | object} */ message) {
|
||||
const isStringMessage = typeof message === 'string';
|
||||
const parsedMessage = isStringMessage ? JSON.parse(message) : message;
|
||||
|
||||
if (
|
||||
parsedMessage != null &&
|
||||
typeof parsedMessage === `object` &&
|
||||
parsedMessage.arguments &&
|
||||
typeof parsedMessage.arguments.hostInfo === `string`
|
||||
) {
|
||||
hostInfo = parsedMessage.arguments.hostInfo;
|
||||
if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK) {
|
||||
const [, major, minor] = (process.env.VSCODE_IPC_HOOK.match(
|
||||
// The RegExp from https://semver.org/ but without the caret at the start
|
||||
/(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/
|
||||
) ?? []).map(Number)
|
||||
|
||||
if (major === 1) {
|
||||
if (minor < 61) {
|
||||
hostInfo += ` <1.61`;
|
||||
} else if (minor < 66) {
|
||||
hostInfo += ` <1.66`;
|
||||
} else if (minor < 68) {
|
||||
hostInfo += ` <1.68`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const processedMessageJSON = JSON.stringify(parsedMessage, (key, value) => {
|
||||
return typeof value === 'string' ? fromEditorPath(value) : value;
|
||||
});
|
||||
|
||||
return originalOnMessage.call(
|
||||
this,
|
||||
isStringMessage ? processedMessageJSON : JSON.parse(processedMessageJSON)
|
||||
);
|
||||
},
|
||||
|
||||
send(/** @type {any} */ msg) {
|
||||
return originalSend.call(this, JSON.parse(JSON.stringify(msg, (key, value) => {
|
||||
return typeof value === `string` ? toEditorPath(value) : value;
|
||||
})));
|
||||
}
|
||||
});
|
||||
|
||||
return tsserver;
|
||||
};
|
||||
|
||||
const [major, minor] = absRequire(`typescript/package.json`).version.split(`.`, 2).map(value => parseInt(value, 10));
|
||||
// In TypeScript@>=5.5 the tsserver uses the public TypeScript API so that needs to be patched as well.
|
||||
// Ref https://github.com/microsoft/TypeScript/pull/55326
|
||||
if (major > 5 || (major === 5 && minor >= 5)) {
|
||||
moduleWrapper(absRequire(`typescript`));
|
||||
}
|
||||
|
||||
// Defer to the real typescript/lib/tsserver.js your application uses
|
||||
module.exports = moduleWrapper(absRequire(`typescript/lib/tsserver.js`));
|
||||
@@ -1,248 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const {existsSync} = require(`fs`);
|
||||
const {createRequire, register} = require(`module`);
|
||||
const {resolve} = require(`path`);
|
||||
const {pathToFileURL} = require(`url`);
|
||||
|
||||
const relPnpApiPath = "../../../../.pnp.cjs";
|
||||
|
||||
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
|
||||
const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
|
||||
const absRequire = createRequire(absPnpApiPath);
|
||||
|
||||
const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
|
||||
const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
|
||||
|
||||
if (existsSync(absPnpApiPath)) {
|
||||
if (!process.versions.pnp) {
|
||||
// Setup the environment to be able to require typescript/lib/tsserverlibrary.js
|
||||
require(absPnpApiPath).setup();
|
||||
if (isPnpLoaderEnabled && register) {
|
||||
register(pathToFileURL(absPnpLoaderPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const wrapWithUserWrapper = existsSync(absUserWrapperPath)
|
||||
? exports => absRequire(absUserWrapperPath)(exports)
|
||||
: exports => exports;
|
||||
|
||||
const moduleWrapper = exports => {
|
||||
return wrapWithUserWrapper(moduleWrapperFn(exports));
|
||||
};
|
||||
|
||||
const moduleWrapperFn = tsserver => {
|
||||
if (!process.versions.pnp) {
|
||||
return tsserver;
|
||||
}
|
||||
|
||||
const {isAbsolute} = require(`path`);
|
||||
const pnpApi = require(`pnpapi`);
|
||||
|
||||
const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//);
|
||||
const isPortal = str => str.startsWith("portal:/");
|
||||
const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`);
|
||||
|
||||
const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => {
|
||||
return `${locator.name}@${locator.reference}`;
|
||||
}));
|
||||
|
||||
// VSCode sends the zip paths to TS using the "zip://" prefix, that TS
|
||||
// doesn't understand. This layer makes sure to remove the protocol
|
||||
// before forwarding it to TS, and to add it back on all returned paths.
|
||||
|
||||
function toEditorPath(str) {
|
||||
// We add the `zip:` prefix to both `.zip/` paths and virtual paths
|
||||
if (isAbsolute(str) && !str.match(/^\^?(zip:|\/zip\/)/) && (str.match(/\.zip\//) || isVirtual(str))) {
|
||||
// We also take the opportunity to turn virtual paths into physical ones;
|
||||
// this makes it much easier to work with workspaces that list peer
|
||||
// dependencies, since otherwise Ctrl+Click would bring us to the virtual
|
||||
// file instances instead of the real ones.
|
||||
//
|
||||
// We only do this to modules owned by the the dependency tree roots.
|
||||
// This avoids breaking the resolution when jumping inside a vendor
|
||||
// with peer dep (otherwise jumping into react-dom would show resolution
|
||||
// errors on react).
|
||||
//
|
||||
const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str;
|
||||
if (resolved) {
|
||||
const locator = pnpApi.findPackageLocator(resolved);
|
||||
if (locator && (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || isPortal(locator.reference))) {
|
||||
str = resolved;
|
||||
}
|
||||
}
|
||||
|
||||
str = normalize(str);
|
||||
|
||||
if (str.match(/\.zip\//)) {
|
||||
switch (hostInfo) {
|
||||
// Absolute VSCode `Uri.fsPath`s need to start with a slash.
|
||||
// VSCode only adds it automatically for supported schemes,
|
||||
// so we have to do it manually for the `zip` scheme.
|
||||
// The path needs to start with a caret otherwise VSCode doesn't handle the protocol
|
||||
//
|
||||
// Ref: https://github.com/microsoft/vscode/issues/105014#issuecomment-686760910
|
||||
//
|
||||
// 2021-10-08: VSCode changed the format in 1.61.
|
||||
// Before | ^zip:/c:/foo/bar.zip/package.json
|
||||
// After | ^/zip//c:/foo/bar.zip/package.json
|
||||
//
|
||||
// 2022-04-06: VSCode changed the format in 1.66.
|
||||
// Before | ^/zip//c:/foo/bar.zip/package.json
|
||||
// After | ^/zip/c:/foo/bar.zip/package.json
|
||||
//
|
||||
// 2022-05-06: VSCode changed the format in 1.68
|
||||
// Before | ^/zip/c:/foo/bar.zip/package.json
|
||||
// After | ^/zip//c:/foo/bar.zip/package.json
|
||||
//
|
||||
case `vscode <1.61`: {
|
||||
str = `^zip:${str}`;
|
||||
} break;
|
||||
|
||||
case `vscode <1.66`: {
|
||||
str = `^/zip/${str}`;
|
||||
} break;
|
||||
|
||||
case `vscode <1.68`: {
|
||||
str = `^/zip${str}`;
|
||||
} break;
|
||||
|
||||
case `vscode`: {
|
||||
str = `^/zip/${str}`;
|
||||
} break;
|
||||
|
||||
// To make "go to definition" work,
|
||||
// We have to resolve the actual file system path from virtual path
|
||||
// and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip)
|
||||
case `coc-nvim`: {
|
||||
str = normalize(resolved).replace(/\.zip\//, `.zip::`);
|
||||
str = resolve(`zipfile:${str}`);
|
||||
} break;
|
||||
|
||||
// Support neovim native LSP and [typescript-language-server](https://github.com/theia-ide/typescript-language-server)
|
||||
// We have to resolve the actual file system path from virtual path,
|
||||
// everything else is up to neovim
|
||||
case `neovim`: {
|
||||
str = normalize(resolved).replace(/\.zip\//, `.zip::`);
|
||||
str = `zipfile://${str}`;
|
||||
} break;
|
||||
|
||||
default: {
|
||||
str = `zip:${str}`;
|
||||
} break;
|
||||
}
|
||||
} else {
|
||||
str = str.replace(/^\/?/, process.platform === `win32` ? `` : `/`);
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
function fromEditorPath(str) {
|
||||
switch (hostInfo) {
|
||||
case `coc-nvim`: {
|
||||
str = str.replace(/\.zip::/, `.zip/`);
|
||||
// The path for coc-nvim is in format of /<pwd>/zipfile:/<pwd>/.yarn/...
|
||||
// So in order to convert it back, we use .* to match all the thing
|
||||
// before `zipfile:`
|
||||
return process.platform === `win32`
|
||||
? str.replace(/^.*zipfile:\//, ``)
|
||||
: str.replace(/^.*zipfile:/, ``);
|
||||
} break;
|
||||
|
||||
case `neovim`: {
|
||||
str = str.replace(/\.zip::/, `.zip/`);
|
||||
// The path for neovim is in format of zipfile:///<pwd>/.yarn/...
|
||||
return str.replace(/^zipfile:\/\//, ``);
|
||||
} break;
|
||||
|
||||
case `vscode`:
|
||||
default: {
|
||||
return str.replace(/^\^?(zip:|\/zip(\/ts-nul-authority)?)\/+/, process.platform === `win32` ? `` : `/`)
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
// Force enable 'allowLocalPluginLoads'
|
||||
// TypeScript tries to resolve plugins using a path relative to itself
|
||||
// which doesn't work when using the global cache
|
||||
// https://github.com/microsoft/TypeScript/blob/1b57a0395e0bff191581c9606aab92832001de62/src/server/project.ts#L2238
|
||||
// VSCode doesn't want to enable 'allowLocalPluginLoads' due to security concerns but
|
||||
// TypeScript already does local loads and if this code is running the user trusts the workspace
|
||||
// https://github.com/microsoft/vscode/issues/45856
|
||||
const ConfiguredProject = tsserver.server.ConfiguredProject;
|
||||
const {enablePluginsWithOptions: originalEnablePluginsWithOptions} = ConfiguredProject.prototype;
|
||||
ConfiguredProject.prototype.enablePluginsWithOptions = function() {
|
||||
this.projectService.allowLocalPluginLoads = true;
|
||||
return originalEnablePluginsWithOptions.apply(this, arguments);
|
||||
};
|
||||
|
||||
// And here is the point where we hijack the VSCode <-> TS communications
|
||||
// by adding ourselves in the middle. We locate everything that looks
|
||||
// like an absolute path of ours and normalize it.
|
||||
|
||||
const Session = tsserver.server.Session;
|
||||
const {onMessage: originalOnMessage, send: originalSend} = Session.prototype;
|
||||
let hostInfo = `unknown`;
|
||||
|
||||
Object.assign(Session.prototype, {
|
||||
onMessage(/** @type {string | object} */ message) {
|
||||
const isStringMessage = typeof message === 'string';
|
||||
const parsedMessage = isStringMessage ? JSON.parse(message) : message;
|
||||
|
||||
if (
|
||||
parsedMessage != null &&
|
||||
typeof parsedMessage === `object` &&
|
||||
parsedMessage.arguments &&
|
||||
typeof parsedMessage.arguments.hostInfo === `string`
|
||||
) {
|
||||
hostInfo = parsedMessage.arguments.hostInfo;
|
||||
if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK) {
|
||||
const [, major, minor] = (process.env.VSCODE_IPC_HOOK.match(
|
||||
// The RegExp from https://semver.org/ but without the caret at the start
|
||||
/(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/
|
||||
) ?? []).map(Number)
|
||||
|
||||
if (major === 1) {
|
||||
if (minor < 61) {
|
||||
hostInfo += ` <1.61`;
|
||||
} else if (minor < 66) {
|
||||
hostInfo += ` <1.66`;
|
||||
} else if (minor < 68) {
|
||||
hostInfo += ` <1.68`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const processedMessageJSON = JSON.stringify(parsedMessage, (key, value) => {
|
||||
return typeof value === 'string' ? fromEditorPath(value) : value;
|
||||
});
|
||||
|
||||
return originalOnMessage.call(
|
||||
this,
|
||||
isStringMessage ? processedMessageJSON : JSON.parse(processedMessageJSON)
|
||||
);
|
||||
},
|
||||
|
||||
send(/** @type {any} */ msg) {
|
||||
return originalSend.call(this, JSON.parse(JSON.stringify(msg, (key, value) => {
|
||||
return typeof value === `string` ? toEditorPath(value) : value;
|
||||
})));
|
||||
}
|
||||
});
|
||||
|
||||
return tsserver;
|
||||
};
|
||||
|
||||
const [major, minor] = absRequire(`typescript/package.json`).version.split(`.`, 2).map(value => parseInt(value, 10));
|
||||
// In TypeScript@>=5.5 the tsserver uses the public TypeScript API so that needs to be patched as well.
|
||||
// Ref https://github.com/microsoft/TypeScript/pull/55326
|
||||
if (major > 5 || (major === 5 && minor >= 5)) {
|
||||
moduleWrapper(absRequire(`typescript`));
|
||||
}
|
||||
|
||||
// Defer to the real typescript/lib/tsserverlibrary.js your application uses
|
||||
module.exports = moduleWrapper(absRequire(`typescript/lib/tsserverlibrary.js`));
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"name": "typescript",
|
||||
"version": "5.7.3-sdk",
|
||||
"main": "./lib/typescript.js",
|
||||
"type": "commonjs",
|
||||
"bin": {
|
||||
"tsc": "./bin/tsc",
|
||||
"tsserver": "./bin/tsserver"
|
||||
}
|
||||
}
|
||||
@@ -14,8 +14,7 @@
|
||||
"@dbeaver/cli": "workspace:^",
|
||||
"@dbeaver/prettier-config": "workspace:^",
|
||||
"@wroud/ts-template": "^0",
|
||||
"prettier": "^3.5.1",
|
||||
"rimraf": "^6",
|
||||
"typescript": "^5.7.3"
|
||||
"prettier": "^3.5.3",
|
||||
"rimraf": "^6"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1396,9 +1396,8 @@ __metadata:
|
||||
"@dbeaver/cli": "workspace:^"
|
||||
"@dbeaver/prettier-config": "workspace:^"
|
||||
"@wroud/ts-template": "npm:^0"
|
||||
prettier: "npm:^3.5.1"
|
||||
prettier: "npm:^3.5.3"
|
||||
rimraf: "npm:^6"
|
||||
typescript: "npm:^5.7.3"
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
@@ -2702,12 +2701,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"prettier@npm:^3.5.1":
|
||||
version: 3.5.1
|
||||
resolution: "prettier@npm:3.5.1"
|
||||
"prettier@npm:^3.5.3":
|
||||
version: 3.5.3
|
||||
resolution: "prettier@npm:3.5.3"
|
||||
bin:
|
||||
prettier: bin/prettier.cjs
|
||||
checksum: 10c0/9f6f810eae455d6e4213845151a484a2338f2e0d6a8b84ee8e13a83af8a2421ef6c1e31e61e4b135671fb57b9541f6624648880cc2061ac803e243ac898c0123
|
||||
checksum: 10c0/3880cb90b9dc0635819ab52ff571518c35bd7f15a6e80a2054c05dbc8a3aa6e74f135519e91197de63705bcb38388ded7e7230e2178432a1468005406238b877
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -3288,7 +3287,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"typescript@npm:^5, typescript@npm:^5.7.3":
|
||||
"typescript@npm:^5":
|
||||
version: 5.7.3
|
||||
resolution: "typescript@npm:5.7.3"
|
||||
bin:
|
||||
@@ -3298,7 +3297,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"typescript@patch:typescript@npm%3A^5#optional!builtin<compat/typescript>, typescript@patch:typescript@npm%3A^5.7.3#optional!builtin<compat/typescript>":
|
||||
"typescript@patch:typescript@npm%3A^5#optional!builtin<compat/typescript>":
|
||||
version: 5.7.3
|
||||
resolution: "typescript@patch:typescript@npm%3A5.7.3#optional!builtin<compat/typescript>::version=5.7.3&hash=5786d5"
|
||||
bin:
|
||||
|
||||
@@ -36,5 +36,6 @@ exec java ${JAVA_OPTS} \
|
||||
-jar ${launcherJar} \
|
||||
-product io.cloudbeaver.product.ce.product \
|
||||
-web-config conf/cloudbeaver.conf \
|
||||
${CLI_OPTS} \
|
||||
-nl en \
|
||||
-registryMultiLanguage
|
||||
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
set -Eeo pipefail
|
||||
CLI_OPTS="$@"
|
||||
if [[ $# -eq 0 ]] ;
|
||||
then
|
||||
CLI_OPTS='-help'
|
||||
fi
|
||||
source run-server.sh
|
||||
+1
-1
@@ -26,7 +26,7 @@ testBundles=\
|
||||
productsPaths=\
|
||||
dbeaver/product/community/DBeaver.product;\
|
||||
cloudbeaver/server/product/web-server/CloudbeaverServer.product:../../opt/cloudbeaver;\
|
||||
cloudbeaver/server/product/web-server-test/CloudbeaverServerTest.product:../../opt/cloudbeaver;
|
||||
cloudbeaver/server/product/web-server-test/CloudbeaverServerUnitTest.product:../../opt/cloudbeaver;
|
||||
ideaConfigurationFilesPaths=\
|
||||
dbeaver/.ide/.idea;
|
||||
additionalModuleRoots=\
|
||||
|
||||
@@ -3,13 +3,14 @@ Bundle-ManifestVersion: 2
|
||||
Bundle-Vendor: DBeaver Corp
|
||||
Bundle-Name: Cloudbeaver Web Model
|
||||
Bundle-SymbolicName: io.cloudbeaver.model;singleton:=true
|
||||
Bundle-Version: 1.0.76.qualifier
|
||||
Bundle-Release-Date: 20250505
|
||||
Bundle-Version: 1.0.77.qualifier
|
||||
Bundle-Release-Date: 20250519
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-17
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-ClassPath: .
|
||||
Require-Bundle: org.jkiss.dbeaver.data.gis;visibility:=reexport,
|
||||
org.jkiss.dbeaver.model;visibility:=reexport,
|
||||
org.jkiss.dbeaver.model.cli;visibility:=reexport,
|
||||
org.jkiss.dbeaver.model.sm;visibility:=reexport,
|
||||
org.jkiss.dbeaver.model.event;visibility:=reexport,
|
||||
org.jkiss.dbeaver.model.nio;visibility:=reexport,
|
||||
@@ -29,6 +30,7 @@ Export-Package: io.cloudbeaver,
|
||||
io.cloudbeaver.model,
|
||||
io.cloudbeaver.model.app,
|
||||
io.cloudbeaver.model.config,
|
||||
io.cloudbeaver.model.cli,
|
||||
io.cloudbeaver.model.events,
|
||||
io.cloudbeaver.model.fs,
|
||||
io.cloudbeaver.model.log,
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<artifactId>io.cloudbeaver.model</artifactId>
|
||||
<version>1.0.76-SNAPSHOT</version>
|
||||
<version>1.0.77-SNAPSHOT</version>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -61,6 +61,8 @@ public class WebConnectionConfig {
|
||||
private DBPDriverConfigurationType configurationType;
|
||||
private String selectedSecretId;
|
||||
private boolean defaultAutoCommit;
|
||||
private String defaultCatalogName;
|
||||
private String defaultSchemaName;
|
||||
|
||||
public WebConnectionConfig() {
|
||||
}
|
||||
@@ -96,6 +98,8 @@ public class WebConnectionConfig {
|
||||
|
||||
mainPropertyValues = JSONUtils.getObjectOrNull(params, "mainPropertyValues");
|
||||
providerProperties = JSONUtils.getObjectOrNull(params, "providerProperties");
|
||||
defaultCatalogName = JSONUtils.getString(params, "defaultCatalogName");
|
||||
defaultSchemaName = JSONUtils.getString(params, "defaultSchemaName");
|
||||
|
||||
String configType = JSONUtils.getString(params, "configurationType");
|
||||
configurationType = configType == null ? null : DBPDriverConfigurationType.valueOf(configType);
|
||||
@@ -234,4 +238,14 @@ public class WebConnectionConfig {
|
||||
public String getSelectedSecretId() {
|
||||
return selectedSecretId;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDefaultCatalogName() {
|
||||
return defaultCatalogName;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDefaultSchemaName() {
|
||||
return defaultSchemaName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -491,6 +491,18 @@ public class WebConnectionInfo {
|
||||
return isAutoCommit;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDefaultCatalogName() {
|
||||
DBPConnectionConfiguration connectionConfiguration = dataSourceContainer.getConnectionConfiguration();
|
||||
return connectionConfiguration.getBootstrap().getDefaultCatalogName();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDefaultSchemaName() {
|
||||
DBPConnectionConfiguration connectionConfiguration = dataSourceContainer.getConnectionConfiguration();
|
||||
return connectionConfiguration.getBootstrap().getDefaultSchemaName();
|
||||
}
|
||||
|
||||
@Property
|
||||
public List<WebSecretInfo> getSharedSecrets() throws DBException {
|
||||
return dataSourceContainer.listSharedCredentials()
|
||||
|
||||
+14
-1
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package io.cloudbeaver.model.app;
|
||||
|
||||
import io.cloudbeaver.model.cli.CloudBeaverInstanceServer;
|
||||
import io.cloudbeaver.model.log.SLF4JLogHandler;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.equinox.app.IApplicationContext;
|
||||
@@ -27,6 +28,7 @@ import org.jkiss.dbeaver.model.DBFileController;
|
||||
import org.jkiss.dbeaver.model.app.DBPWorkspace;
|
||||
import org.jkiss.dbeaver.model.auth.SMCredentialsProvider;
|
||||
import org.jkiss.dbeaver.model.auth.SMSessionContext;
|
||||
import org.jkiss.dbeaver.model.cli.ApplicationInstanceController;
|
||||
import org.jkiss.dbeaver.model.data.json.JSONUtils;
|
||||
import org.jkiss.dbeaver.model.impl.app.ApplicationRegistry;
|
||||
import org.jkiss.dbeaver.model.impl.app.BaseApplicationImpl;
|
||||
@@ -57,7 +59,7 @@ public abstract class BaseServletApplication extends BaseApplicationImpl impleme
|
||||
private static final Log log = Log.getLog(BaseServletApplication.class);
|
||||
|
||||
private String instanceId;
|
||||
|
||||
private CloudBeaverInstanceServer instanceServer;
|
||||
@Override
|
||||
public RMController createResourceController(
|
||||
@NotNull SMCredentialsProvider credentialsProvider,
|
||||
@@ -200,6 +202,11 @@ public abstract class BaseServletApplication extends BaseApplicationImpl impleme
|
||||
public Object start(IApplicationContext context) {
|
||||
initializeApplicationServices();
|
||||
try {
|
||||
try {
|
||||
this.instanceServer = new CloudBeaverInstanceServer();
|
||||
} catch (Exception e) {
|
||||
log.error("Error initializing instance server", e);
|
||||
}
|
||||
startServer();
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
@@ -266,4 +273,10 @@ public abstract class BaseServletApplication extends BaseApplicationImpl impleme
|
||||
log.error("Failed close " + name, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ApplicationInstanceController getInstanceServer() {
|
||||
return instanceServer;
|
||||
}
|
||||
}
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2025 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.cloudbeaver.model.cli;
|
||||
|
||||
import org.jkiss.dbeaver.model.cli.ApplicationCommandLine;
|
||||
import org.jkiss.dbeaver.model.cli.ApplicationInstanceController;
|
||||
|
||||
public class CloudBeaverCommandLine extends ApplicationCommandLine<ApplicationInstanceController> {
|
||||
private static CloudBeaverCommandLine INSTANCE = null;
|
||||
|
||||
private CloudBeaverCommandLine() {
|
||||
super();
|
||||
}
|
||||
|
||||
public synchronized static CloudBeaverCommandLine getInstance() {
|
||||
if (INSTANCE == null) {
|
||||
INSTANCE = new CloudBeaverCommandLine();
|
||||
}
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2025 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.cloudbeaver.model.cli;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.dbeaver.model.cli.ApplicationInstanceController;
|
||||
import org.jkiss.dbeaver.model.cli.ApplicationInstanceServer;
|
||||
import org.jkiss.dbeaver.model.cli.CmdProcessResult;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class CloudBeaverInstanceServer extends ApplicationInstanceServer<ApplicationInstanceController> {
|
||||
public CloudBeaverInstanceServer() throws IOException {
|
||||
super(ApplicationInstanceController.class);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public CmdProcessResult handleCommandLine(@NotNull String[] args) {
|
||||
CommandLine cmd = CloudBeaverCommandLine.getInstance().getCommandLine(args);
|
||||
try {
|
||||
return CloudBeaverCommandLine.getInstance().executeCommandLineCommands(
|
||||
cmd,
|
||||
this,
|
||||
false
|
||||
);
|
||||
} catch (Exception e) {
|
||||
return new CmdProcessResult(CmdProcessResult.PostAction.ERROR, "Error executing command: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -19,8 +19,8 @@ package io.cloudbeaver.model.config;
|
||||
import com.google.gson.annotations.Expose;
|
||||
import io.cloudbeaver.auth.provider.local.LocalAuthProviderConstants;
|
||||
import io.cloudbeaver.model.app.BaseWebAppConfiguration;
|
||||
import io.cloudbeaver.model.app.WebAppConfiguration;
|
||||
import io.cloudbeaver.model.app.ServletAuthConfiguration;
|
||||
import io.cloudbeaver.model.app.WebAppConfiguration;
|
||||
import io.cloudbeaver.registry.WebAuthProviderDescriptor;
|
||||
import io.cloudbeaver.registry.WebAuthProviderRegistry;
|
||||
import org.jkiss.code.NotNull;
|
||||
|
||||
+7
-1
@@ -37,7 +37,13 @@ public class WebSessionPreferenceStore extends AbstractUserPreferenceStore {
|
||||
|
||||
// to avoid redundant sm api call
|
||||
public void updatePreferenceValues(@NotNull Map<String, Object> newValues) {
|
||||
userPreferences.putAll(newValues);
|
||||
for (Map.Entry<String, Object> entry : newValues.entrySet()) {
|
||||
if (entry.getValue() == null) {
|
||||
userPreferences.remove(entry.getKey());
|
||||
} else {
|
||||
userPreferences.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -89,13 +89,13 @@ public class ServletAppUtils {
|
||||
var additionalValue = additional.get(rootKey);
|
||||
|
||||
if (originValue == null || additionalValue == null) {
|
||||
Object resultValue = null;
|
||||
if (additional.containsKey(rootKey)) {
|
||||
resultValue = additionalValue;
|
||||
if (additionalValue != null) {
|
||||
resultConfig.put(rootKey, additionalValue);
|
||||
}
|
||||
} else if (originValue != null) {
|
||||
resultValue = originValue;
|
||||
resultConfig.put(rootKey, originValue);
|
||||
}
|
||||
resultConfig.put(rootKey, resultValue);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2
|
||||
Bundle-Vendor: DBeaver Corp
|
||||
Bundle-Name: Cloudbeaver Community Product
|
||||
Bundle-SymbolicName: io.cloudbeaver.product.ce;singleton:=true
|
||||
Bundle-Version: 25.0.4.qualifier
|
||||
Bundle-Release-Date: 20250505
|
||||
Bundle-Version: 25.0.5.qualifier
|
||||
Bundle-Release-Date: 20250519
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-17
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-ClassPath: .
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<artifactId>io.cloudbeaver.product.ce</artifactId>
|
||||
<version>25.0.4-SNAPSHOT</version>
|
||||
<version>25.0.5-SNAPSHOT</version>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -2,8 +2,8 @@ Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Cloudbeaver Base JDBC drivers
|
||||
Bundle-SymbolicName: io.cloudbeaver.resources.drivers.base;singleton:=true
|
||||
Bundle-Version: 1.0.121.qualifier
|
||||
Bundle-Release-Date: 20250505
|
||||
Bundle-Version: 1.0.122.qualifier
|
||||
Bundle-Release-Date: 20250519
|
||||
Bundle-Vendor: DBeaver Corp
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Automatic-Module-Name: io.cloudbeaver.resources.drivers.base
|
||||
|
||||
@@ -9,6 +9,6 @@
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<artifactId>io.cloudbeaver.resources.drivers.base</artifactId>
|
||||
<version>1.0.121-SNAPSHOT</version>
|
||||
<version>1.0.122-SNAPSHOT</version>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
</project>
|
||||
|
||||
@@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2
|
||||
Bundle-Vendor: DBeaver Corp
|
||||
Bundle-Name: Cloudbeaver CE Server
|
||||
Bundle-SymbolicName: io.cloudbeaver.server.ce;singleton:=true
|
||||
Bundle-Version: 25.0.4.qualifier
|
||||
Bundle-Release-Date: 20250505
|
||||
Bundle-Version: 25.0.5.qualifier
|
||||
Bundle-Release-Date: 20250519
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-17
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-Activator: io.cloudbeaver.server.CBPlatformActivator
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<artifactId>io.cloudbeaver.server.ce</artifactId>
|
||||
<version>25.0.4-SNAPSHOT</version>
|
||||
<version>25.0.5-SNAPSHOT</version>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2
|
||||
Bundle-Vendor: DBeaver Corp
|
||||
Bundle-Name: Cloudbeaver Web Server
|
||||
Bundle-SymbolicName: io.cloudbeaver.server;singleton:=true
|
||||
Bundle-Version: 25.0.4.qualifier
|
||||
Bundle-Release-Date: 20250505
|
||||
Bundle-Version: 25.0.5.qualifier
|
||||
Bundle-Release-Date: 20250519
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-17
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-ClassPath: .
|
||||
|
||||
@@ -62,4 +62,8 @@
|
||||
</propertyGroup>
|
||||
</extension>
|
||||
|
||||
<extension point="org.jkiss.dbeaver.language">
|
||||
<language code="vi" label="Tiếng Việt"/>
|
||||
</extension>
|
||||
|
||||
</plugin>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<artifactId>io.cloudbeaver.server</artifactId>
|
||||
<version>25.0.4-SNAPSHOT</version>
|
||||
<version>25.0.5-SNAPSHOT</version>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -418,6 +418,8 @@ type ConnectionInfo {
|
||||
|
||||
projectId: ID!
|
||||
requiredAuth: String
|
||||
defaultCatalogName: String @since(version: "25.0.5")
|
||||
defaultSchemaName: String @since(version: "25.0.5")
|
||||
|
||||
tools: [String!]! @since(version: "24.1.3")
|
||||
}
|
||||
@@ -570,6 +572,8 @@ input ConnectionConfig {
|
||||
|
||||
# Configuration type
|
||||
configurationType: DriverConfigurationType
|
||||
defaultCatalogName: String @since(version: "25.0.5")
|
||||
defaultSchemaName: String @since(version: "25.0.5")
|
||||
}
|
||||
|
||||
####################################################
|
||||
|
||||
@@ -18,8 +18,6 @@ package io.cloudbeaver;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.InstanceCreator;
|
||||
import com.google.gson.Strictness;
|
||||
import io.cloudbeaver.model.WebConnectionConfig;
|
||||
import io.cloudbeaver.model.WebNetworkHandlerConfigInput;
|
||||
import io.cloudbeaver.model.WebPropertyInfo;
|
||||
@@ -175,6 +173,8 @@ public class WebServiceUtils extends WebCommonUtils {
|
||||
if (config.isDefaultAutoCommit() != null) {
|
||||
dsConfig.getBootstrap().setDefaultAutoCommit(config.isDefaultAutoCommit());
|
||||
}
|
||||
dsConfig.getBootstrap().setDefaultCatalogName(config.getDefaultCatalogName());
|
||||
dsConfig.getBootstrap().setDefaultSchemaName(config.getDefaultSchemaName());
|
||||
// Save provider props
|
||||
if (config.getProviderProperties() != null) {
|
||||
dsConfig.setProviderProperties(new LinkedHashMap<>());
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.jkiss.dbeaver.utils.GeneralUtils;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -136,6 +137,8 @@ public class WebServerConfig {
|
||||
@Property
|
||||
public WebServerLanguage[] getSupportedLanguages() {
|
||||
List<PlatformLanguageDescriptor> langs = PlatformLanguageRegistry.getInstance().getLanguages();
|
||||
// FIXME: remove hardcoded ordering
|
||||
langs.sort(Comparator.comparingInt(x -> x.getCode().equals("vi") ? 1 : -1));
|
||||
WebServerLanguage[] webLangs = new WebServerLanguage[langs.size()];
|
||||
for (int i = 0; i < webLangs.length; i++) {
|
||||
webLangs[i] = new WebServerLanguage(langs.get(i));
|
||||
|
||||
+2
-2
@@ -44,10 +44,10 @@ public interface DBWServiceCore extends DBWService {
|
||||
/**
|
||||
* Returns information of system.
|
||||
*/
|
||||
@WebAction(authRequired = false)
|
||||
@WebAction
|
||||
WebPropertyInfo[] getSystemInformationProperties(@NotNull WebSession webSession);
|
||||
|
||||
@WebAction(authRequired = false)
|
||||
@WebAction
|
||||
WebProductSettings getProductSettings(@NotNull WebSession webSession);
|
||||
|
||||
@WebAction
|
||||
|
||||
@@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2
|
||||
Bundle-Vendor: DBeaver Corp
|
||||
Bundle-Name: Cloudbeaver Web Service - Administration
|
||||
Bundle-SymbolicName: io.cloudbeaver.service.admin;singleton:=true
|
||||
Bundle-Version: 1.0.120.qualifier
|
||||
Bundle-Release-Date: 20250505
|
||||
Bundle-Version: 1.0.121.qualifier
|
||||
Bundle-Release-Date: 20250519
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-17
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-ClassPath: .
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<artifactId>io.cloudbeaver.service.admin</artifactId>
|
||||
<version>1.0.120-SNAPSHOT</version>
|
||||
<version>1.0.121-SNAPSHOT</version>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2
|
||||
Bundle-Vendor: DBeaver Corp
|
||||
Bundle-Name: Cloudbeaver Web Service - Authentication
|
||||
Bundle-SymbolicName: io.cloudbeaver.service.auth;singleton:=true
|
||||
Bundle-Version: 1.0.120.qualifier
|
||||
Bundle-Release-Date: 20250505
|
||||
Bundle-Version: 1.0.121.qualifier
|
||||
Bundle-Release-Date: 20250519
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-17
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-ClassPath: .
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<artifactId>io.cloudbeaver.service.auth</artifactId>
|
||||
<version>1.0.120-SNAPSHOT</version>
|
||||
<version>1.0.121-SNAPSHOT</version>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -40,6 +40,7 @@ type AuthProviderConfiguration {
|
||||
# Otherwise authLogin function must be called.
|
||||
signInLink: String
|
||||
signOutLink: String
|
||||
redirectLink: String
|
||||
metadataLink: String
|
||||
acsLink: String
|
||||
entityIdLink: String @since(version: "24.2.1")
|
||||
|
||||
@@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2
|
||||
Bundle-Vendor: DBeaver Corp
|
||||
Bundle-Name: Cloudbeaver Web Service - Data Transfer
|
||||
Bundle-SymbolicName: io.cloudbeaver.service.data.transfer;singleton:=true
|
||||
Bundle-Version: 1.0.121.qualifier
|
||||
Bundle-Release-Date: 20250505
|
||||
Bundle-Version: 1.0.122.qualifier
|
||||
Bundle-Release-Date: 20250519
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-17
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-ClassPath: .
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<artifactId>io.cloudbeaver.service.data.transfer</artifactId>
|
||||
<version>1.0.121-SNAPSHOT</version>
|
||||
<version>1.0.122-SNAPSHOT</version>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2
|
||||
Bundle-Vendor: DBeaver Corp
|
||||
Bundle-Name: Cloudbeaver Web Service - File System
|
||||
Bundle-SymbolicName: io.cloudbeaver.service.fs;singleton:=true
|
||||
Bundle-Version: 1.0.38.qualifier
|
||||
Bundle-Release-Date: 20250505
|
||||
Bundle-Version: 1.0.39.qualifier
|
||||
Bundle-Release-Date: 20250519
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-17
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-ClassPath: .
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<artifactId>io.cloudbeaver.service.fs</artifactId>
|
||||
<version>1.0.38-SNAPSHOT</version>
|
||||
<version>1.0.39-SNAPSHOT</version>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Cloudbeaver Web Service - LDAP
|
||||
Bundle-Vendor: DBeaver Corp
|
||||
Bundle-SymbolicName: io.cloudbeaver.service.ldap.auth;singleton:=true
|
||||
Bundle-Version: 1.0.3.qualifier
|
||||
Bundle-Release-Date: 20250505
|
||||
Bundle-Version: 1.0.4.qualifier
|
||||
Bundle-Release-Date: 20250519
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-17
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-ClassPath: .
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<artifactId>io.cloudbeaver.service.ldap.auth</artifactId>
|
||||
<version>1.0.3-SNAPSHOT</version>
|
||||
<version>1.0.4-SNAPSHOT</version>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
|
||||
</project>
|
||||
|
||||
+46
-26
@@ -77,10 +77,9 @@ public class LdapAuthProvider implements SMAuthProviderExternal<SMSession>, SMBr
|
||||
|
||||
}
|
||||
if (CommonUtils.isEmpty(userData)) {
|
||||
userData = new HashMap<>();
|
||||
String fullUserDN = buildFullUserDN(userName, ldapSettings);
|
||||
validateUserAccess(fullUserDN, ldapSettings, userData);
|
||||
authenticateLdap(fullUserDN, password, ldapSettings, null, environment, userData);
|
||||
validateUserAccess(fullUserDN, ldapSettings);
|
||||
userData = authenticateLdap(fullUserDN, password, ldapSettings, null, environment);
|
||||
}
|
||||
return userData;
|
||||
}
|
||||
@@ -130,7 +129,7 @@ public class LdapAuthProvider implements SMAuthProviderExternal<SMSession>, SMBr
|
||||
if (userDN == null) {
|
||||
return null;
|
||||
}
|
||||
return authenticateLdap(userDN, password, ldapSettings, login, creteAuthEnvironment(ldapSettings), new HashMap<>());
|
||||
return authenticateLdap(userDN, password, ldapSettings, login, creteAuthEnvironment(ldapSettings));
|
||||
} catch (Exception e) {
|
||||
throw new DBException("LDAP authentication failed: " + e.getMessage(), e);
|
||||
}
|
||||
@@ -141,8 +140,7 @@ public class LdapAuthProvider implements SMAuthProviderExternal<SMSession>, SMBr
|
||||
*/
|
||||
private void validateUserAccess(
|
||||
@NotNull String fullUserDN,
|
||||
@NotNull LdapSettings ldapSettings,
|
||||
@NotNull Map<String, Object> userData
|
||||
@NotNull LdapSettings ldapSettings
|
||||
) throws DBException {
|
||||
if (
|
||||
CommonUtils.isEmpty(ldapSettings.getFilter())
|
||||
@@ -386,13 +384,13 @@ public class LdapAuthProvider implements SMAuthProviderExternal<SMSession>, SMBr
|
||||
}
|
||||
|
||||
private Map<String, Object> authenticateLdap(
|
||||
String userDN,
|
||||
String password,
|
||||
LdapSettings ldapSettings,
|
||||
@NotNull String userDN,
|
||||
@NotNull String password,
|
||||
@NotNull LdapSettings ldapSettings,
|
||||
@Nullable String login,
|
||||
Hashtable<String, String> environment,
|
||||
Map<String, Object> userData
|
||||
@NotNull Hashtable<String, String> environment
|
||||
) throws DBException {
|
||||
Map<String, Object> userData = new HashMap<>();
|
||||
environment.put(Context.SECURITY_PRINCIPAL, userDN);
|
||||
environment.put(Context.SECURITY_CREDENTIALS, password);
|
||||
DirContext userContext = null;
|
||||
@@ -417,9 +415,10 @@ public class LdapAuthProvider implements SMAuthProviderExternal<SMSession>, SMBr
|
||||
);
|
||||
doCustomModifyUserDataAfterAuthentication(ldapSettings, attributes, userData);
|
||||
}
|
||||
userData.putIfAbsent(LdapConstants.CRED_USERNAME, CommonUtils.isNotEmpty(userId) ? userId : login);
|
||||
userData.putIfAbsent(LdapConstants.CRED_USERNAME, CommonUtils.isNotEmpty(login) ? login : userId);
|
||||
userData.put(LdapConstants.CRED_USER_DN, userDN);
|
||||
userData.put(LdapConstants.CRED_DISPLAY_NAME, findUserNameFromDN(userDN, ldapSettings));
|
||||
userData.put(LdapConstants.CRED_PASSWORD, password);
|
||||
userData.put(LdapConstants.CRED_DISPLAY_NAME, CommonUtils.isNotEmpty(login) ? login : findUserNameFromDN(userDN, ldapSettings));
|
||||
userData.put(LdapConstants.CRED_SESSION_ID, UUID.randomUUID());
|
||||
|
||||
return userData;
|
||||
@@ -463,12 +462,7 @@ public class LdapAuthProvider implements SMAuthProviderExternal<SMSession>, SMBr
|
||||
|
||||
List<String> result = new ArrayList<>();
|
||||
result.add(userDN);
|
||||
|
||||
String groupDN = getGroupForMember(userDN, ldapSettings);
|
||||
if (groupDN != null) {
|
||||
result.add(groupDN);
|
||||
}
|
||||
|
||||
result.addAll(getGroupForMember(userDN, ldapSettings, authParameters));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -483,21 +477,47 @@ public class LdapAuthProvider implements SMAuthProviderExternal<SMSession>, SMBr
|
||||
}
|
||||
}
|
||||
|
||||
private String getGroupForMember(String fullDN, LdapSettings ldapSettings) {
|
||||
DirContext context;
|
||||
@NotNull
|
||||
private List<String> getGroupForMember(String fullDN, LdapSettings ldapSettings, Map<String, Object> authParameters) {
|
||||
DirContext context = null;
|
||||
NamingEnumeration<SearchResult> searchResults = null;
|
||||
List<String> result = new ArrayList<>();
|
||||
try {
|
||||
context = new InitialDirContext(creteAuthEnvironment(ldapSettings));
|
||||
Hashtable<String, String> environment = creteAuthEnvironment(ldapSettings);
|
||||
if (CommonUtils.isEmpty(ldapSettings.getBindUserDN())) {
|
||||
environment.put(Context.SECURITY_PRINCIPAL, String.valueOf(authParameters.get(LdapConstants.CRED_USER_DN)));
|
||||
environment.put(Context.SECURITY_CREDENTIALS, String.valueOf(authParameters.get(LdapConstants.CRED_PASSWORD)));
|
||||
} else {
|
||||
environment.put(Context.SECURITY_PRINCIPAL, ldapSettings.getBindUserDN());
|
||||
environment.put(Context.SECURITY_CREDENTIALS, ldapSettings.getBindUserPassword());
|
||||
}
|
||||
//it's a hack. Otherwise password will be written to database
|
||||
authParameters.remove(LdapConstants.CRED_PASSWORD);
|
||||
|
||||
context = new InitialDirContext(environment);
|
||||
|
||||
String searchFilter = "(member=" + fullDN + ")";
|
||||
SearchControls searchControls = new SearchControls();
|
||||
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
|
||||
|
||||
NamingEnumeration<SearchResult> results = context.search(ldapSettings.getBaseDN(), searchFilter, searchControls);
|
||||
if (results.hasMore()) {
|
||||
return results.next().getName();
|
||||
searchResults = context.search(ldapSettings.getBaseDN(), searchFilter, searchControls);
|
||||
while (searchResults.hasMore()) {
|
||||
result.add(searchResults.next().getName());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Group not found", e);
|
||||
} finally {
|
||||
try {
|
||||
if (context != null) {
|
||||
context.close();
|
||||
}
|
||||
if (searchResults != null) {
|
||||
searchResults.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Close resource of ldap group search failed", e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2
|
||||
Bundle-Vendor: DBeaver Corp
|
||||
Bundle-Name: Cloudbeaver Web Service - Metadata
|
||||
Bundle-SymbolicName: io.cloudbeaver.service.metadata;singleton:=true
|
||||
Bundle-Version: 1.0.124.qualifier
|
||||
Bundle-Release-Date: 20250505
|
||||
Bundle-Version: 1.0.125.qualifier
|
||||
Bundle-Release-Date: 20250519
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-17
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-ClassPath: .
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<artifactId>io.cloudbeaver.service.metadata</artifactId>
|
||||
<version>1.0.124-SNAPSHOT</version>
|
||||
<version>1.0.125-SNAPSHOT</version>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2
|
||||
Bundle-Vendor: DBeaver Corp
|
||||
Bundle-Name: Cloudbeaver Resource manager NIO implementation
|
||||
Bundle-SymbolicName: io.cloudbeaver.service.rm.nio;singleton:=true
|
||||
Bundle-Version: 1.0.38.qualifier
|
||||
Bundle-Release-Date: 20250505
|
||||
Bundle-Version: 1.0.39.qualifier
|
||||
Bundle-Release-Date: 20250519
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-17
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-ClassPath: .
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<artifactId>io.cloudbeaver.service.rm.nio</artifactId>
|
||||
<version>1.0.38-SNAPSHOT</version>
|
||||
<version>1.0.39-SNAPSHOT</version>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2
|
||||
Bundle-Vendor: DBeaver Corp
|
||||
Bundle-Name: Cloudbeaver Web Service - Resource manager
|
||||
Bundle-SymbolicName: io.cloudbeaver.service.rm;singleton:=true
|
||||
Bundle-Version: 1.0.73.qualifier
|
||||
Bundle-Release-Date: 20250505
|
||||
Bundle-Version: 1.0.74.qualifier
|
||||
Bundle-Release-Date: 20250519
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-17
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-ClassPath: .
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<artifactId>io.cloudbeaver.service.rm</artifactId>
|
||||
<version>1.0.73-SNAPSHOT</version>
|
||||
<version>1.0.74-SNAPSHOT</version>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -52,12 +52,12 @@ extend type Query {
|
||||
folder: String,
|
||||
nameMask: String,
|
||||
readProperties: Boolean,
|
||||
readHistory: Boolean): [RMResource!]! @deprecated
|
||||
readHistory: Boolean): [RMResource!]!
|
||||
|
||||
# Reads resource contents as string in UTF-8
|
||||
rmReadResourceAsString(
|
||||
projectId: String!,
|
||||
resourcePath: String!): String! @deprecated
|
||||
resourcePath: String!): String!
|
||||
|
||||
}
|
||||
|
||||
@@ -65,28 +65,28 @@ extend type Mutation {
|
||||
rmCreateResource(
|
||||
projectId: String!,
|
||||
resourcePath: String!,
|
||||
isFolder: Boolean!): String! @deprecated
|
||||
isFolder: Boolean!): String!
|
||||
|
||||
rmMoveResource(
|
||||
projectId: String!,
|
||||
oldResourcePath: String!,
|
||||
newResourcePath: String): String! @deprecated
|
||||
newResourcePath: String): String!
|
||||
|
||||
rmDeleteResource(
|
||||
projectId: String!,
|
||||
resourcePath: String!,
|
||||
recursive: Boolean!): Boolean @deprecated
|
||||
recursive: Boolean!): Boolean
|
||||
|
||||
rmWriteResourceStringContent(
|
||||
projectId: String!,
|
||||
resourcePath: String!,
|
||||
data: String!,
|
||||
forceOverwrite: Boolean!): String! @deprecated
|
||||
forceOverwrite: Boolean!): String!
|
||||
|
||||
rmCreateProject(
|
||||
projectId: ID,
|
||||
projectName: String!,
|
||||
description: String): RMProject! @deprecated
|
||||
description: String): RMProject!
|
||||
|
||||
rmDeleteProject(projectId: ID!): Boolean!
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Cloudbeaver Web Service - Security
|
||||
Bundle-Vendor: DBeaver Corp
|
||||
Bundle-SymbolicName: io.cloudbeaver.service.security;singleton:=true
|
||||
Bundle-Version: 1.0.76.qualifier
|
||||
Bundle-Release-Date: 20250505
|
||||
Bundle-Version: 1.0.77.qualifier
|
||||
Bundle-Release-Date: 20250519
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-17
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-ClassPath: .
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<artifactId>io.cloudbeaver.service.security</artifactId>
|
||||
<version>1.0.76-SNAPSHOT</version>
|
||||
<version>1.0.77-SNAPSHOT</version>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
|
||||
</project>
|
||||
|
||||
+5
-1
@@ -194,6 +194,10 @@ public class CBEmbeddedSecurityController<T extends ServletAuthApplication>
|
||||
for (SMUserProvisioning user : userImportList.getUsers()) {
|
||||
String authRole = user.getAuthRole() == null ? userImportList.getAuthRole() : user.getAuthRole();
|
||||
String userId = user.getUserId();
|
||||
Map<String, String> metaParameters = user.getMetaParameters();
|
||||
if (CommonUtils.isNotEmpty(metaParameters.get(SMStandardMeta.META_USER_ID))) {
|
||||
userId = metaParameters.get(SMStandardMeta.META_USER_ID);
|
||||
}
|
||||
for (String possibleUserId : List.of(userId, userId.toLowerCase())) {
|
||||
if (isSubjectExists(possibleUserId)) {
|
||||
log.info("User already exist : " + possibleUserId);
|
||||
@@ -202,7 +206,7 @@ public class CBEmbeddedSecurityController<T extends ServletAuthApplication>
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
createUser(connection, userId.toLowerCase(), user.getMetaParameters(), true, authRole);
|
||||
createUser(connection, userId.toLowerCase(), metaParameters, true, authRole);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2
|
||||
Bundle-Vendor: DBeaver Corp
|
||||
Bundle-Name: CloudBeaver SLF4j Binding
|
||||
Bundle-SymbolicName: io.cloudbeaver.slf4j;singleton:=true
|
||||
Bundle-Version: 1.0.36.qualifier
|
||||
Bundle-Release-Date: 20250505
|
||||
Bundle-Version: 1.0.37.qualifier
|
||||
Bundle-Release-Date: 20250519
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-17
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-ClassPath: .
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<artifactId>io.cloudbeaver.slf4j</artifactId>
|
||||
<version>1.0.36-SNAPSHOT</version>
|
||||
<version>1.0.37-SNAPSHOT</version>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<dependency>
|
||||
<groupId>com.clickhouse</groupId>
|
||||
<artifactId>clickhouse-jdbc</artifactId>
|
||||
<version>0.8.5</version>
|
||||
<version>0.7.2</version>
|
||||
<classifier>http</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<feature
|
||||
id="io.cloudbeaver.ce.drivers.feature"
|
||||
label="Cloudbeaver CE 3rd Party Drivers"
|
||||
version="1.0.144.qualifier"
|
||||
version="1.0.145.qualifier"
|
||||
provider-name="DBeaver Corp">
|
||||
|
||||
<plugin id="io.cloudbeaver.resources.drivers.base" download-size="0" install-size="0" version="0.0.0"/>
|
||||
|
||||
@@ -9,6 +9,6 @@
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<artifactId>io.cloudbeaver.ce.drivers.feature</artifactId>
|
||||
<version>1.0.144-SNAPSHOT</version>
|
||||
<version>1.0.145-SNAPSHOT</version>
|
||||
<packaging>eclipse-feature</packaging>
|
||||
</project>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<feature
|
||||
id="io.cloudbeaver.product.ce.feature"
|
||||
label="%featureName"
|
||||
version="25.0.4.qualifier"
|
||||
version="25.0.5.qualifier"
|
||||
provider-name="%providerName"
|
||||
plugin="io.cloudbeaver.product.ce">
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<artifactId>io.cloudbeaver.product.ce.feature</artifactId>
|
||||
<version>25.0.4-SNAPSHOT</version>
|
||||
<version>25.0.5-SNAPSHOT</version>
|
||||
<packaging>eclipse-feature</packaging>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<feature
|
||||
id="io.cloudbeaver.server.feature"
|
||||
label="%featureName"
|
||||
version="25.0.4.qualifier"
|
||||
version="25.0.5.qualifier"
|
||||
provider-name="%providerName"
|
||||
plugin="io.cloudbeaver.server">
|
||||
|
||||
|
||||
@@ -10,6 +10,6 @@
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<artifactId>io.cloudbeaver.server.feature</artifactId>
|
||||
<version>25.0.4-SNAPSHOT</version>
|
||||
<version>25.0.5-SNAPSHOT</version>
|
||||
<packaging>eclipse-feature</packaging>
|
||||
</project>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<feature
|
||||
id="io.cloudbeaver.ws.feature"
|
||||
label="%featureName"
|
||||
version="1.0.74.qualifier"
|
||||
version="1.0.75.qualifier"
|
||||
provider-name="%providerName"
|
||||
plugin="io.cloudbeaver.model">
|
||||
|
||||
|
||||
@@ -10,6 +10,6 @@
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<artifactId>io.cloudbeaver.ws.feature</artifactId>
|
||||
<version>1.0.74-SNAPSHOT</version>
|
||||
<version>1.0.75-SNAPSHOT</version>
|
||||
<packaging>eclipse-feature</packaging>
|
||||
</project>
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@
|
||||
|
||||
<properties>
|
||||
<dbeaver-product>CloudBeaver CE</dbeaver-product>
|
||||
<dbeaver-version>25.0.4</dbeaver-version>
|
||||
<dbeaver-version>25.0.5</dbeaver-version>
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<?pde version="3.5"?>
|
||||
|
||||
<product name="CloudBeaver ce Server" uid="io.cloudbeaver.product" id="io.cloudbeaver.product.ce.product"
|
||||
application="io.cloudbeaver.product.ce.application" version="25.0.4.qualifier" useFeatures="true"
|
||||
application="io.cloudbeaver.product.ce.application" version="25.0.5.qualifier" useFeatures="true"
|
||||
includeLaunchers="false">
|
||||
|
||||
<configIni use="default">
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../</relativePath>
|
||||
</parent>
|
||||
<version>25.0.4-SNAPSHOT</version>
|
||||
<version>25.0.5-SNAPSHOT</version>
|
||||
<artifactId>web-server</artifactId>
|
||||
<packaging>eclipse-repository</packaging>
|
||||
<name>Cloudbeaver Server Product</name>
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ import org.mockito.junit.MockitoJUnitRunner;
|
||||
import java.net.CookieManager;
|
||||
import java.net.http.HttpClient;
|
||||
|
||||
@RunWithProduct("CloudbeaverServerTest.product")
|
||||
@RunWithProduct("CloudbeaverServerUnitTest.product")
|
||||
@RunnerProxy(MockitoJUnitRunner.class)
|
||||
@RunWith(OSGITestRunner.class)
|
||||
@RunWithApplication(bundleName = "io.cloudbeaver.server.ce", registryName = "io.cloudbeaver.product.ce.application", args = {"-web-config", "workspace/conf/cloudbeaver.conf"})
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package io.cloudbeaver.model.rm;
|
||||
|
||||
import io.cloudbeaver.CloudbeaverMockTest;
|
||||
import io.cloudbeaver.app.CEAppStarter;
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
import io.cloudbeaver.server.CBConstants;
|
||||
@@ -46,7 +47,7 @@ import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class RMNIOTest {
|
||||
public class RMNIOTest extends CloudbeaverMockTest {
|
||||
|
||||
private static WebSession webSession;
|
||||
private static RMProject testProject;
|
||||
|
||||
+8
-4
@@ -16,11 +16,10 @@
|
||||
*/
|
||||
package io.cloudbeaver.model.rm.lock;
|
||||
|
||||
import io.cloudbeaver.CloudbeaverMockTest;
|
||||
import io.cloudbeaver.app.CEAppStarter;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.*;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
@@ -32,7 +31,7 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class RMLockTest {
|
||||
public class RMLockTest extends CloudbeaverMockTest {
|
||||
private static final Log log = Log.getLog(RMLockTest.class);
|
||||
private final String project1 = "s_fakeProject1";
|
||||
private final String project2 = "s_fakeProject2";
|
||||
@@ -43,6 +42,11 @@ public class RMLockTest {
|
||||
executor.shutdown();
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void startServer() throws Exception {
|
||||
CEAppStarter.startServerIfNotStarted();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProjectAccessUsingSeveralControllers() throws Throwable {
|
||||
var lockController1 = new TestLockController(CEAppStarter.getTestApp(), 1);
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ import org.junit.Test;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class SQLQueryTranslatorTest extends CloudbeaverMockTest {
|
||||
public class SQLQueryTranslatorTest extends CloudbeaverMockTest {
|
||||
@Test
|
||||
public void createSimpleTable() throws DBException {
|
||||
var basicSql = "CREATE TABLE CB_AUTH_SUBJECT (SUBJECT_ID VARCHAR(128) NOT NULL," +
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
!.yarn/releases
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
!.yarn/sdks/**
|
||||
|
||||
# Swap the comments on the following lines if you wish to use zero-installs
|
||||
# In that case, don't forget to run `yarn config set enableGlobalCache false`!
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "typescript",
|
||||
"version": "5.7.3-sdk",
|
||||
"version": "5.8.3-sdk",
|
||||
"main": "./lib/typescript.js",
|
||||
"type": "commonjs",
|
||||
"bin": {
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
"name": "vscode-java-configs",
|
||||
"packageManager": "yarn@4.6.0",
|
||||
"devDependencies": {
|
||||
"typescript": "^5.7.3"
|
||||
"typescript": "^5.8.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,23 +5,23 @@ __metadata:
|
||||
version: 8
|
||||
cacheKey: 10c0
|
||||
|
||||
"typescript@npm:^5.7.3":
|
||||
version: 5.7.3
|
||||
resolution: "typescript@npm:5.7.3"
|
||||
"typescript@npm:^5.8.3":
|
||||
version: 5.8.3
|
||||
resolution: "typescript@npm:5.8.3"
|
||||
bin:
|
||||
tsc: bin/tsc
|
||||
tsserver: bin/tsserver
|
||||
checksum: 10c0/b7580d716cf1824736cc6e628ab4cd8b51877408ba2be0869d2866da35ef8366dd6ae9eb9d0851470a39be17cbd61df1126f9e211d8799d764ea7431d5435afa
|
||||
checksum: 10c0/5f8bb01196e542e64d44db3d16ee0e4063ce4f3e3966df6005f2588e86d91c03e1fb131c2581baf0fb65ee79669eea6e161cd448178986587e9f6844446dbb48
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"typescript@patch:typescript@npm%3A^5.7.3#optional!builtin<compat/typescript>":
|
||||
version: 5.7.3
|
||||
resolution: "typescript@patch:typescript@npm%3A5.7.3#optional!builtin<compat/typescript>::version=5.7.3&hash=5786d5"
|
||||
"typescript@patch:typescript@npm%3A^5.8.3#optional!builtin<compat/typescript>":
|
||||
version: 5.8.3
|
||||
resolution: "typescript@patch:typescript@npm%3A5.8.3#optional!builtin<compat/typescript>::version=5.8.3&hash=5786d5"
|
||||
bin:
|
||||
tsc: bin/tsc
|
||||
tsserver: bin/tsserver
|
||||
checksum: 10c0/6fd7e0ed3bf23a81246878c613423730c40e8bdbfec4c6e4d7bf1b847cbb39076e56ad5f50aa9d7ebd89877999abaee216002d3f2818885e41c907caaa192cc4
|
||||
checksum: 10c0/39117e346ff8ebd87ae1510b3a77d5d92dae5a89bde588c747d25da5c146603a99c8ee588c7ef80faaf123d89ed46f6dbd918d534d641083177d5fac38b8a1cb
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -29,6 +29,6 @@ __metadata:
|
||||
version: 0.0.0-use.local
|
||||
resolution: "vscode-java-configs@workspace:."
|
||||
dependencies:
|
||||
typescript: "npm:^5.7.3"
|
||||
typescript: "npm:^5.8.3"
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user