Format & lint
This commit is contained in:
parent
fefac224b0
commit
7f62273e72
42 changed files with 2149 additions and 1258 deletions
|
|
@ -8,6 +8,7 @@ import type { FileSystemOperations } from "./filesystem-operations";
|
|||
import type { TextWithCursors } from "reconcile-text";
|
||||
import type { ServerConfig, ServerConfigData } from "../services/server-config";
|
||||
import { CONFLICT_PATH_REGEX } from "../sync-operations/conflict-path";
|
||||
import { removeFromArray } from "../utils/remove-from-array";
|
||||
|
||||
class MockServerConfig implements Pick<ServerConfig, "getConfig"> {
|
||||
public async getConfig(): Promise<ServerConfigData> {
|
||||
|
|
@ -81,9 +82,7 @@ function singleConflictPath(
|
|||
expectedNonConflictNames: string[]
|
||||
): string {
|
||||
const expected = new Set(expectedNonConflictNames);
|
||||
const conflicts = Array.from(names).filter(
|
||||
(name) => !expected.has(name)
|
||||
);
|
||||
const conflicts = Array.from(names).filter((name) => !expected.has(name));
|
||||
assert.equal(
|
||||
conflicts.length,
|
||||
1,
|
||||
|
|
@ -139,7 +138,11 @@ describe("File operations", () => {
|
|||
it("move with EXISTING displaces the target to a conflict path", async () => {
|
||||
const { fs, ops } = makeOps();
|
||||
|
||||
await ops.create("source.md", new Uint8Array(), MoveOnConflict.EXISTING);
|
||||
await ops.create(
|
||||
"source.md",
|
||||
new Uint8Array(),
|
||||
MoveOnConflict.EXISTING
|
||||
);
|
||||
await ops.create("dest.md", new Uint8Array(), MoveOnConflict.EXISTING);
|
||||
|
||||
await ops.move("source.md", "dest.md", MoveOnConflict.EXISTING);
|
||||
|
|
@ -156,7 +159,11 @@ describe("File operations", () => {
|
|||
it("move with NEW redirects the moved file to a conflict path", async () => {
|
||||
const { fs, ops } = makeOps();
|
||||
|
||||
await ops.create("source.md", new Uint8Array(), MoveOnConflict.EXISTING);
|
||||
await ops.create(
|
||||
"source.md",
|
||||
new Uint8Array(),
|
||||
MoveOnConflict.EXISTING
|
||||
);
|
||||
await ops.create("dest.md", new Uint8Array(), MoveOnConflict.EXISTING);
|
||||
|
||||
await ops.move("source.md", "dest.md", MoveOnConflict.NEW);
|
||||
|
|
@ -190,7 +197,11 @@ describe("File operations", () => {
|
|||
it("handles dotfiles without mangling the extension", async () => {
|
||||
const { fs, ops } = makeOps();
|
||||
|
||||
await ops.create(".gitignore", new Uint8Array(), MoveOnConflict.EXISTING);
|
||||
await ops.create(
|
||||
".gitignore",
|
||||
new Uint8Array(),
|
||||
MoveOnConflict.EXISTING
|
||||
);
|
||||
await ops.create("temp", new Uint8Array(), MoveOnConflict.EXISTING);
|
||||
await ops.move("temp", ".gitignore", MoveOnConflict.EXISTING);
|
||||
|
||||
|
|
@ -200,7 +211,11 @@ describe("File operations", () => {
|
|||
`conflict should preserve the dotfile name verbatim, got ${conflict}`
|
||||
);
|
||||
|
||||
await ops.create(".config.json", new Uint8Array(), MoveOnConflict.EXISTING);
|
||||
await ops.create(
|
||||
".config.json",
|
||||
new Uint8Array(),
|
||||
MoveOnConflict.EXISTING
|
||||
);
|
||||
await ops.create("temp2", new Uint8Array(), MoveOnConflict.EXISTING);
|
||||
await ops.move("temp2", ".config.json", MoveOnConflict.EXISTING);
|
||||
|
||||
|
|
@ -221,7 +236,8 @@ describe("File operations", () => {
|
|||
await ops.create("x", new Uint8Array(), MoveOnConflict.EXISTING);
|
||||
await ops.create("x", new Uint8Array(), MoveOnConflict.EXISTING);
|
||||
|
||||
const conflicts = Array.from(fs.names).filter((n) => n !== "x");
|
||||
const conflicts = Array.from(fs.names);
|
||||
removeFromArray(conflicts, "x");
|
||||
assert.equal(conflicts.length, 2);
|
||||
assert.ok(conflicts.every((c) => CONFLICT_PATH_REGEX.test(c)));
|
||||
assert.notEqual(
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import type { Logger } from "../tracing/logger";
|
||||
import type { FileSystemOperations } from "./filesystem-operations";
|
||||
import type { RelativePath } from "../sync-operations/types";
|
||||
import type { SyncEventQueue } from "../sync-operations/sync-event-queue";
|
||||
import { SafeFileSystemOperations } from "./safe-filesystem-operations";
|
||||
import type { TextWithCursors } from "reconcile-text";
|
||||
import { reconcile } from "reconcile-text";
|
||||
|
|
@ -10,10 +9,9 @@ import { isBinary } from "../utils/is-binary";
|
|||
import { buildConflictFileName } from "../sync-operations/conflict-path";
|
||||
import type { ServerConfig } from "../services/server-config";
|
||||
|
||||
|
||||
export enum MoveOnConflict {
|
||||
EXISTING = "EXISTING",
|
||||
NEW = "NEW",
|
||||
NEW = "NEW"
|
||||
}
|
||||
|
||||
export class FileOperations {
|
||||
|
|
@ -40,6 +38,17 @@ export class FileOperations {
|
|||
return [pathParts.join("/"), fileName];
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a local-only conflict path for a file the client has to set aside.
|
||||
* Format: `<dir>/conflict-<uuid>-<originalName>` — UUID makes collisions
|
||||
* statistically impossible, so no disk probe / lock dance is needed.
|
||||
*/
|
||||
private static buildConflictPath(path: RelativePath): RelativePath {
|
||||
const [directory, fileName] = FileOperations.getParentDirAndFile(path);
|
||||
const conflictName = buildConflictFileName(fileName);
|
||||
return directory ? `${directory}/${conflictName}` : conflictName;
|
||||
}
|
||||
|
||||
public async listFilesRecursively(
|
||||
root: RelativePath | undefined = undefined
|
||||
): Promise<RelativePath[]> {
|
||||
|
|
@ -55,7 +64,7 @@ export class FileOperations {
|
|||
*
|
||||
* If a file with the same name already exists, it is moved before creating the new one.
|
||||
* Parent directories are created if necessary.
|
||||
*
|
||||
*
|
||||
* Returns the actual path the file was created at.
|
||||
*/
|
||||
public async create(
|
||||
|
|
@ -68,30 +77,6 @@ export class FileOperations {
|
|||
return actualPath;
|
||||
}
|
||||
|
||||
private async ensureClearPath(
|
||||
path: RelativePath,
|
||||
moveOnConflict: MoveOnConflict
|
||||
): Promise<RelativePath> {
|
||||
if (await this.fs.exists(path)) {
|
||||
const conflictPath = FileOperations.buildConflictPath(path);
|
||||
|
||||
if (moveOnConflict === MoveOnConflict.NEW) {
|
||||
return conflictPath;
|
||||
}
|
||||
|
||||
this.logger.debug(
|
||||
`Displacing existing file at ${path} to '${conflictPath}' to make room`
|
||||
);
|
||||
|
||||
await this.fs.rename(path, conflictPath);
|
||||
return path;
|
||||
}
|
||||
|
||||
this.logger.debug(`No existing file at ${path}, creating parent directories if needed`);
|
||||
await this.createParentDirectories(path);
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the file at the given path.
|
||||
*
|
||||
|
|
@ -129,8 +114,8 @@ export class FileOperations {
|
|||
return;
|
||||
}
|
||||
|
||||
let expectedText: string;
|
||||
let newText: string;
|
||||
let expectedText = "";
|
||||
let newText = "";
|
||||
try {
|
||||
expectedText = new TextDecoder("utf-8", { fatal: true }).decode(
|
||||
expectedContent
|
||||
|
|
@ -206,6 +191,31 @@ export class FileOperations {
|
|||
return actualPath;
|
||||
}
|
||||
|
||||
private async ensureClearPath(
|
||||
path: RelativePath,
|
||||
moveOnConflict: MoveOnConflict
|
||||
): Promise<RelativePath> {
|
||||
if (await this.fs.exists(path)) {
|
||||
const conflictPath = FileOperations.buildConflictPath(path);
|
||||
|
||||
if (moveOnConflict === MoveOnConflict.NEW) {
|
||||
return conflictPath;
|
||||
}
|
||||
|
||||
this.logger.debug(
|
||||
`Displacing existing file at ${path} to '${conflictPath}' to make room`
|
||||
);
|
||||
|
||||
await this.fs.rename(path, conflictPath);
|
||||
return path;
|
||||
}
|
||||
|
||||
this.logger.debug(
|
||||
`No existing file at ${path}, creating parent directories if needed`
|
||||
);
|
||||
await this.createParentDirectories(path);
|
||||
return path;
|
||||
}
|
||||
|
||||
private async deletingEmptyParentDirectoriesOfDeletedFile(
|
||||
path: RelativePath
|
||||
|
|
@ -265,16 +275,4 @@ export class FileOperations {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a local-only conflict path for a file the client has to set aside.
|
||||
* Format: `<dir>/conflict-<uuid>-<originalName>` — UUID makes collisions
|
||||
* statistically impossible, so no disk probe / lock dance is needed.
|
||||
*/
|
||||
private static buildConflictPath(path: RelativePath): RelativePath {
|
||||
const [directory, fileName] =
|
||||
FileOperations.getParentDirAndFile(path);
|
||||
const conflictName = buildConflictFileName(fileName);
|
||||
return directory ? `${directory}/${conflictName}` : conflictName;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,11 @@ export {
|
|||
export { Logger, LogLevel, LogLine } from "./tracing/logger";
|
||||
export { type SyncSettings, DEFAULT_SETTINGS } from "./persistence/settings";
|
||||
export { rateLimit } from "./utils/rate-limit";
|
||||
export type { RelativePath, StoredSyncState as StoredDatabase, DocumentRecord } from "./sync-operations/types";
|
||||
export type {
|
||||
RelativePath,
|
||||
StoredSyncState as StoredDatabase,
|
||||
DocumentRecord
|
||||
} from "./sync-operations/types";
|
||||
export type { FileSystemOperations } from "./file-operations/filesystem-operations";
|
||||
export type { PersistenceProvider } from "./persistence/persistence";
|
||||
export type { CursorSpan } from "./services/types/CursorSpan";
|
||||
|
|
|
|||
|
|
@ -19,7 +19,11 @@ export class FetchController {
|
|||
private _canFetch: boolean,
|
||||
private readonly logger: Logger
|
||||
) {
|
||||
({ promise: this.until, resolve: this.resolveUntil, reject: this.rejectUntil } = Promise.withResolvers<symbol>());
|
||||
({
|
||||
promise: this.until,
|
||||
resolve: this.resolveUntil,
|
||||
reject: this.rejectUntil
|
||||
} = Promise.withResolvers<symbol>());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -40,7 +44,11 @@ export class FetchController {
|
|||
|
||||
if (!this.isResetting) {
|
||||
const previousResolve = this.resolveUntil;
|
||||
({ promise: this.until, resolve: this.resolveUntil, reject: this.rejectUntil } = Promise.withResolvers<symbol>());
|
||||
({
|
||||
promise: this.until,
|
||||
resolve: this.resolveUntil,
|
||||
reject: this.rejectUntil
|
||||
} = Promise.withResolvers<symbol>());
|
||||
previousResolve(FetchController.UNTIL_RESOLUTION);
|
||||
}
|
||||
}
|
||||
|
|
@ -78,7 +86,11 @@ export class FetchController {
|
|||
}
|
||||
|
||||
this.isResetting = false;
|
||||
({ promise: this.until, resolve: this.resolveUntil, reject: this.rejectUntil } = Promise.withResolvers<symbol>());
|
||||
({
|
||||
promise: this.until,
|
||||
resolve: this.resolveUntil,
|
||||
reject: this.rejectUntil
|
||||
} = Promise.withResolvers<symbol>());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -66,6 +66,42 @@ export class SyncService {
|
|||
return result;
|
||||
}
|
||||
|
||||
private static async throwIfNotOk(
|
||||
response: Response,
|
||||
operation: string
|
||||
): Promise<void> {
|
||||
if (response.ok) return;
|
||||
const message = `Failed to ${operation}: ${await SyncService.errorFromResponse(response)}`;
|
||||
// 429 is the only 4xx the server uses for *transient* contention
|
||||
// (`WriteBusyError` → HTTP 429). Every other 4xx means the request
|
||||
// is permanently rejected and shouldn't be retried.
|
||||
if (response.status === 429) {
|
||||
throw new Error(message);
|
||||
}
|
||||
if (response.status >= 400 && response.status < 500) {
|
||||
throw new HttpClientError(response.status, message);
|
||||
}
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Signal that the service is shutting down so any in-flight
|
||||
* `retryForever` exits at its next iteration instead of looping
|
||||
* indefinitely after the rest of the client has stopped. Idempotent.
|
||||
*/
|
||||
public stop(): void {
|
||||
this.isStopped = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-enable the service after a `stop()`. Used when the client pauses
|
||||
* and resumes syncing within the same lifecycle (e.g. user toggles
|
||||
* sync off and on).
|
||||
*/
|
||||
public resume(): void {
|
||||
this.isStopped = false;
|
||||
}
|
||||
|
||||
public async create({
|
||||
relativePath,
|
||||
lastSeenVaultUpdateId,
|
||||
|
|
@ -146,8 +182,7 @@ export class SyncService {
|
|||
(await response.json()) as DocumentUpdateResponse; // eslint-disable-line @typescript-eslint/no-unsafe-type-assertion
|
||||
|
||||
this.logger.debug(
|
||||
`Updated document ${JSON.stringify(result)} with id ${
|
||||
result.documentId
|
||||
`Updated document ${JSON.stringify(result)} with id ${result.documentId
|
||||
}}`
|
||||
);
|
||||
|
||||
|
|
@ -193,8 +228,7 @@ export class SyncService {
|
|||
(await response.json()) as DocumentUpdateResponse; // eslint-disable-line @typescript-eslint/no-unsafe-type-assertion
|
||||
|
||||
this.logger.debug(
|
||||
`Updated document ${JSON.stringify(result)} with id ${
|
||||
result.documentId
|
||||
`Updated document ${JSON.stringify(result)} with id ${result.documentId
|
||||
}}`
|
||||
);
|
||||
|
||||
|
|
@ -284,7 +318,10 @@ export class SyncService {
|
|||
}
|
||||
);
|
||||
|
||||
await SyncService.throwIfNotOk(response, "get document version content");
|
||||
await SyncService.throwIfNotOk(
|
||||
response,
|
||||
"get document version content"
|
||||
);
|
||||
|
||||
const result = await response.bytes();
|
||||
this.logger.debug(
|
||||
|
|
@ -300,7 +337,7 @@ export class SyncService {
|
|||
return this.retryForever(async () => {
|
||||
this.logger.debug(
|
||||
"Getting all documents" +
|
||||
(since != null ? ` since ${since}` : "")
|
||||
(since != null ? ` since ${since}` : "")
|
||||
);
|
||||
|
||||
const url = new URL(this.getUrl("/documents"));
|
||||
|
|
@ -369,30 +406,10 @@ export class SyncService {
|
|||
return headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Signal that the service is shutting down so any in-flight
|
||||
* `retryForever` exits at its next iteration instead of looping
|
||||
* indefinitely after the rest of the client has stopped. Idempotent.
|
||||
*/
|
||||
public stop(): void {
|
||||
this.isStopped = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-enable the service after a `stop()`. Used when the client pauses
|
||||
* and resumes syncing within the same lifecycle (e.g. user toggles
|
||||
* sync off and on).
|
||||
*/
|
||||
public resume(): void {
|
||||
this.isStopped = false;
|
||||
}
|
||||
|
||||
private async retryForever<T>(fn: () => Promise<T>): Promise<T> {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
while (true) {
|
||||
if (this.isStopped) {
|
||||
throw new SyncResetError();
|
||||
}
|
||||
this.throwIfStopped();
|
||||
try {
|
||||
return await fn();
|
||||
} catch (e) {
|
||||
|
|
@ -402,9 +419,7 @@ export class SyncService {
|
|||
) {
|
||||
throw e;
|
||||
}
|
||||
if (this.isStopped) {
|
||||
throw new SyncResetError();
|
||||
}
|
||||
this.throwIfStopped();
|
||||
|
||||
const retryInterval =
|
||||
this.settings.getSettings().networkRetryIntervalMs;
|
||||
|
|
@ -416,21 +431,9 @@ export class SyncService {
|
|||
}
|
||||
}
|
||||
|
||||
private static async throwIfNotOk(
|
||||
response: Response,
|
||||
operation: string
|
||||
): Promise<void> {
|
||||
if (response.ok) return;
|
||||
const message = `Failed to ${operation}: ${await SyncService.errorFromResponse(response)}`;
|
||||
// 429 is the only 4xx the server uses for *transient* contention
|
||||
// (`WriteBusyError` → HTTP 429). Every other 4xx means the request
|
||||
// is permanently rejected and shouldn't be retried.
|
||||
if (response.status === 429) {
|
||||
throw new Error(message);
|
||||
private throwIfStopped(): void {
|
||||
if (this.isStopped) {
|
||||
throw new SyncResetError();
|
||||
}
|
||||
if (response.status >= 400 && response.status < 500) {
|
||||
throw new HttpClientError(response.status, message);
|
||||
}
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { DocumentWithCursors } from "./DocumentWithCursors";
|
||||
|
||||
export interface ClientCursors { userName: string, deviceId: string, documentsWithCursors: DocumentWithCursors[], }
|
||||
export interface ClientCursors {
|
||||
userName: string;
|
||||
deviceId: string;
|
||||
documentsWithCursors: DocumentWithCursors[];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export interface CreateDocumentVersion { relative_path: string, last_seen_vault_update_id: number, content: number[], }
|
||||
export interface CreateDocumentVersion {
|
||||
relative_path: string;
|
||||
last_seen_vault_update_id: number;
|
||||
content: number[];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { DocumentWithCursors } from "./DocumentWithCursors";
|
||||
|
||||
export interface CursorPositionFromClient { documentsWithCursors: DocumentWithCursors[], }
|
||||
export interface CursorPositionFromClient {
|
||||
documentsWithCursors: DocumentWithCursors[];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { ClientCursors } from "./ClientCursors";
|
||||
|
||||
export interface CursorPositionFromServer { clients: ClientCursors[], }
|
||||
export interface CursorPositionFromServer {
|
||||
clients: ClientCursors[];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export interface CursorSpan { start: number, end: number, }
|
||||
export interface CursorSpan {
|
||||
start: number;
|
||||
end: number;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,4 +5,6 @@ import type { DocumentVersionWithoutContent } from "./DocumentVersionWithoutCont
|
|||
/**
|
||||
* Response to a create/update document request.
|
||||
*/
|
||||
export type DocumentUpdateResponse = { "type": "FastForwardUpdate" } & DocumentVersionWithoutContent | { "type": "MergingUpdate" } & DocumentVersion;
|
||||
export type DocumentUpdateResponse =
|
||||
| ({ type: "FastForwardUpdate" } & DocumentVersionWithoutContent)
|
||||
| ({ type: "MergingUpdate" } & DocumentVersion);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,12 @@
|
|||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export interface DocumentVersion { vaultUpdateId: number, documentId: string, relativePath: string, updatedDate: string, contentBase64: string, isDeleted: boolean, userId: string, deviceId: string, }
|
||||
export interface DocumentVersion {
|
||||
vaultUpdateId: number;
|
||||
documentId: string;
|
||||
relativePath: string;
|
||||
updatedDate: string;
|
||||
contentBase64: string;
|
||||
isDeleted: boolean;
|
||||
userId: string;
|
||||
deviceId: string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,12 @@
|
|||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export interface DocumentVersionWithoutContent { vaultUpdateId: number, documentId: string, relativePath: string, updatedDate: string, isDeleted: boolean, userId: string, deviceId: string, contentSize: number, }
|
||||
export interface DocumentVersionWithoutContent {
|
||||
vaultUpdateId: number;
|
||||
documentId: string;
|
||||
relativePath: string;
|
||||
updatedDate: string;
|
||||
isDeleted: boolean;
|
||||
userId: string;
|
||||
deviceId: string;
|
||||
contentSize: number;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { CursorSpan } from "./CursorSpan";
|
||||
|
||||
export interface DocumentWithCursors { vaultUpdateId: number | null, documentId: string, relativePath: string, cursors: CursorSpan[], }
|
||||
export interface DocumentWithCursors {
|
||||
vaultUpdateId: number | null;
|
||||
documentId: string;
|
||||
relativePath: string;
|
||||
cursors: CursorSpan[];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,10 @@ import type { DocumentVersionWithoutContent } from "./DocumentVersionWithoutCont
|
|||
/**
|
||||
* Response to a fetch latest documents request.
|
||||
*/
|
||||
export interface FetchLatestDocumentsResponse { latestDocuments: DocumentVersionWithoutContent[],
|
||||
/**
|
||||
* The update ID of the latest document in the response.
|
||||
*/
|
||||
lastUpdateId: bigint, }
|
||||
export interface FetchLatestDocumentsResponse {
|
||||
latestDocuments: DocumentVersionWithoutContent[];
|
||||
/**
|
||||
* The update ID of the latest document in the response.
|
||||
*/
|
||||
lastUpdateId: bigint;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,4 +4,8 @@ import type { VaultInfo } from "./VaultInfo";
|
|||
/**
|
||||
* Response to listing vaults accessible to the authenticated user.
|
||||
*/
|
||||
export interface ListVaultsResponse { vaults: VaultInfo[], hasMore: boolean, userName: string, }
|
||||
export interface ListVaultsResponse {
|
||||
vaults: VaultInfo[];
|
||||
hasMore: boolean;
|
||||
userName: string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,22 +3,23 @@
|
|||
/**
|
||||
* Response to a ping request.
|
||||
*/
|
||||
export interface PingResponse {
|
||||
/**
|
||||
* Semantic version of the server.
|
||||
*/
|
||||
serverVersion: string,
|
||||
/**
|
||||
* Whether the client is authenticated based on the sent Authorization
|
||||
* header.
|
||||
*/
|
||||
isAuthenticated: boolean,
|
||||
/**
|
||||
* List of file extensions that are allowed to be merged.
|
||||
*/
|
||||
mergeableFileExtensions: string[],
|
||||
/**
|
||||
* API version ensuring backwards & forwards compatibility between the client
|
||||
* and server.
|
||||
*/
|
||||
supportedApiVersion: number, }
|
||||
export interface PingResponse {
|
||||
/**
|
||||
* Semantic version of the server.
|
||||
*/
|
||||
serverVersion: string;
|
||||
/**
|
||||
* Whether the client is authenticated based on the sent Authorization
|
||||
* header.
|
||||
*/
|
||||
isAuthenticated: boolean;
|
||||
/**
|
||||
* List of file extensions that are allowed to be merged.
|
||||
*/
|
||||
mergeableFileExtensions: string[];
|
||||
/**
|
||||
* API version ensuring backwards & forwards compatibility between the client
|
||||
* and server.
|
||||
*/
|
||||
supportedApiVersion: number;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export interface SerializedError { errorType: string, message: string, causes: string[], }
|
||||
export interface SerializedError {
|
||||
errorType: string;
|
||||
message: string;
|
||||
causes: string[];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export interface UpdateTextDocumentVersion { parentVersionId: number, relativePath: string, content: (number | string)[], }
|
||||
export interface UpdateTextDocumentVersion {
|
||||
parentVersionId: number;
|
||||
relativePath: string;
|
||||
content: (number | string)[];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,4 +4,7 @@ import type { DocumentVersionWithoutContent } from "./DocumentVersionWithoutCont
|
|||
/**
|
||||
* Response to a vault history request (paginated).
|
||||
*/
|
||||
export interface VaultHistoryResponse { versions: DocumentVersionWithoutContent[], hasMore: boolean, }
|
||||
export interface VaultHistoryResponse {
|
||||
versions: DocumentVersionWithoutContent[];
|
||||
hasMore: boolean;
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue