bolt.diy/app/workbench/components/editor/codemirror/EnvMasking.ts
KevIsDev 6913e9471f refactor: move workbench components and stores to its own directory structure
Restructure the workbench module by moving components and stores from shared/workbench to workbench directory. This includes terminal components, editor utilities, preview stores, and UI components. Update all import paths to reflect the new structure.

The changes include:
- Moving terminal components and theme files
- Relocating editor utilities like EnvMasking and indent
- Transferring stores for previews, editor, and terminal
- Updating all affected import statements across the codebase
- Moving UI components like PortDropdown and Inspector
2025-06-20 15:40:44 +01:00

81 lines
2.2 KiB
TypeScript

import { EditorView, Decoration, type DecorationSet, ViewPlugin, WidgetType } from '@codemirror/view';
// Create a proper WidgetType class for the masked text
class MaskedTextWidget extends WidgetType {
constructor(private readonly _value: string) {
super();
}
eq(other: MaskedTextWidget) {
return other._value === this._value;
}
toDOM() {
const span = document.createElement('span');
span.textContent = '*'.repeat(this._value.length);
span.className = 'cm-masked-text';
return span;
}
ignoreEvent() {
return false;
}
}
export function createEnvMaskingExtension(getFilePath: () => string | undefined) {
return ViewPlugin.fromClass(
class {
decorations: DecorationSet;
constructor(view: EditorView) {
this.decorations = this.buildDecorations(view);
}
update(update: { docChanged: boolean; view: EditorView; viewportChanged: boolean }) {
if (update.docChanged || update.viewportChanged) {
this.decorations = this.buildDecorations(update.view);
}
}
buildDecorations(view: EditorView) {
const filePath = getFilePath();
const isEnvFile = filePath?.endsWith('.env') || filePath?.includes('.env.') || filePath?.includes('/.env');
if (!isEnvFile) {
return Decoration.none;
}
const decorations: any[] = [];
const doc = view.state.doc;
for (let i = 1; i <= doc.lines; i++) {
const line = doc.line(i);
const text = line.text;
// Match lines with KEY=VALUE format
const match = text.match(/^([^=]+)=(.+)$/);
if (match && !text.trim().startsWith('#')) {
const [, key, value] = match;
const valueStart = line.from + key.length + 1;
// Create a decoration that replaces the value with asterisks
decorations.push(
Decoration.replace({
inclusive: true,
widget: new MaskedTextWidget(value),
}).range(valueStart, line.to),
);
}
}
return Decoration.set(decorations);
}
},
{
decorations: (v) => v.decorations,
},
);
}