Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,34 @@ if (lintResult.issues.length > 0) {
}
```

### HTTP Client

For environments where WebSocket connections aren't suitable, you can use the HTTP client:

```typescript
import { createSynapseHTTPClient } from "@appwrite.io/synapse";

// Create HTTP client
const client = createSynapseHTTPClient({
endpoint: "https://your-synapse-server.com",
artifactId: "your-artifact-id",
baseDir: "/optional/base/directory",
});

// File operations
const fileContent = await client.readFile({ path: "/path/to/file.txt" });
await client.createFile({ path: "/path/to/new-file.txt", content: "Hello!" });

// Execute commands
const result = await client.executeCommand({
command: "ls -la",
workingDirectory: "/path/to/dir",
});

// Git operations
await client.git({ operation: "status" });
```

### Event handling

```typescript
Expand Down
47 changes: 47 additions & 0 deletions src/client/base.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
export type SynapseRequest = {
type: string;
operation: string;
params?: Record<string, any>;
requestId?: string;
};

export type SynapseResponse<T = any> = {
success: boolean;
data?: T;
error?: string;
requestId?: string;
};

export class BaseHTTPClient {
protected endpoint: string;

constructor({ endpoint }: { endpoint: string }) {
this.endpoint = endpoint;
}

protected async request<T = any>(
body: SynapseRequest,
): Promise<SynapseResponse<T>> {
try {
const response = await fetch(this.endpoint, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(body),
});

if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}

const result = (await response.json()) as SynapseResponse<T>;
return result;
} catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : String(error),
};
}
}
}
165 changes: 165 additions & 0 deletions src/client/http.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import { FilesystemHTTPService } from "./services/filesystem";
import { TerminalHTTPService } from "./services/terminal";
import { GitHTTPService } from "./services/git";
import { SystemHTTPService } from "./services/system";
import { CodeHTTPService } from "./services/code";
import { AppwriteHTTPService } from "./services/appwrite";

export type { SynapseRequest, SynapseResponse } from "./base";

export type {
AppwriteInitParams,
AppwriteCallParams,
} from "./services/appwrite";

export type { FormatOptions, LintResult } from "./services/code";

export type {
FileItem,
FileContent,
FileListItem,
ListFilesInDirParams,
ListFilesInDirResult,
} from "./services/filesystem";

export type {
GitOperationResult,
GitOperation,
GitParams,
} from "./services/git";

export type { SystemUsageData } from "./services/system";

export type {
ExecuteCommandParams,
ExecuteCommandResult,
} from "./services/terminal";

export class SynapseHTTPClient {
private filesystemService: FilesystemHTTPService;
private terminalService: TerminalHTTPService;
private gitService: GitHTTPService;
private systemService: SystemHTTPService;
private codeService: CodeHTTPService;
private appwriteService: AppwriteHTTPService;

constructor({
endpoint,
artifactId,
baseDir = "",
}: {
endpoint: string;
artifactId: string;
baseDir?: string;
}) {
const artifactBasePath = `artifact/${artifactId}`;

this.appwriteService = new AppwriteHTTPService({ endpoint });
this.codeService = new CodeHTTPService({ endpoint });
this.filesystemService = new FilesystemHTTPService({
endpoint,
artifactBasePath,
baseDir,
});
this.gitService = new GitHTTPService({ endpoint });
this.systemService = new SystemHTTPService({ endpoint });
this.terminalService = new TerminalHTTPService({
endpoint,
artifactBasePath,
baseDir,
});
}

// Appwrite
async initAppwrite(
params: Parameters<AppwriteHTTPService["initAppwrite"]>[0],
) {
return this.appwriteService.initAppwrite(params);
}

async callAppwrite(
params: Parameters<AppwriteHTTPService["callAppwrite"]>[0],
) {
return this.appwriteService.callAppwrite(params);
}

// Code
async formatCode(params: Parameters<CodeHTTPService["formatCode"]>[0]) {
return this.codeService.formatCode(params);
}

async lintCode(params: Parameters<CodeHTTPService["lintCode"]>[0]) {
return this.codeService.lintCode(params);
}

// Filesystem
async getFolder(params: Parameters<FilesystemHTTPService["getFolder"]>[0]) {
return this.filesystemService.getFolder(params);
}

async readFile(params: Parameters<FilesystemHTTPService["readFile"]>[0]) {
return this.filesystemService.readFile(params);
}

async createFile(params: Parameters<FilesystemHTTPService["createFile"]>[0]) {
return this.filesystemService.createFile(params);
}

async createOrUpdateFile(
params: Parameters<FilesystemHTTPService["createOrUpdateFile"]>[0],
) {
return this.filesystemService.createOrUpdateFile(params);
}

async updateFilePath(
params: Parameters<FilesystemHTTPService["updateFilePath"]>[0],
) {
return this.filesystemService.updateFilePath(params);
}

async deleteFile(params: Parameters<FilesystemHTTPService["deleteFile"]>[0]) {
return this.filesystemService.deleteFile(params);
}

async listFilesInDir<WithContent extends boolean = false>(params: {
dirPath: string;
recursive?: boolean;
withContent?: WithContent;
additionalIgnorePatterns?: string[];
}) {
return this.filesystemService.listFilesInDir<WithContent>(params);
}

// Git
async git(params: Parameters<GitHTTPService["git"]>[0]) {
return this.gitService.git(params);
}

// System
async getSystemUsage() {
return this.systemService.getSystemUsage();
}

// Terminal
async executeCommand(
params: Parameters<TerminalHTTPService["executeCommand"]>[0],
) {
return this.terminalService.executeCommand(params);
}
}

export function createSynapseHTTPClient({
endpoint,
artifactId,
baseDir = "",
}: {
endpoint: string;
artifactId: string;
baseDir?: string;
}): SynapseHTTPClient {
return new SynapseHTTPClient({
endpoint,
artifactId,
baseDir,
});
}
57 changes: 57 additions & 0 deletions src/client/services/appwrite.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { SynapseResponse, BaseHTTPClient } from "../base";

export type AppwriteInitParams = {
endpoint?: string;
projectId: string;
jwt: string;
};

export type AppwriteCallParams = {
service: string;
method: string;
args?: Record<string, any>;
};

export class AppwriteHTTPService extends BaseHTTPClient {
constructor({ endpoint }: { endpoint: string }) {
super({ endpoint });
}

/**
* Initialize Appwrite client
*/
async initAppwrite({
endpoint,
projectId,
jwt,
}: AppwriteInitParams): Promise<SynapseResponse<any>> {
return this.request({
type: "appwrite",
operation: "init",
params: {
endpoint,
projectId,
jwt,
},
});
}

/**
* Call Appwrite service method
*/
async callAppwrite({
service,
method,
args = {},
}: AppwriteCallParams): Promise<SynapseResponse<any>> {
return this.request({
type: "appwrite",
operation: "call",
params: {
service,
method,
args,
},
});
}
}
73 changes: 73 additions & 0 deletions src/client/services/code.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { BaseHTTPClient, SynapseResponse } from "../base";

export type FormatOptions = {
language: string;
indent?: number;
useTabs?: boolean;
semi?: boolean;
singleQuote?: boolean;
printWidth?: number;
};

export type LintResult = {
errors: Array<{
line: number;
column: number;
message: string;
rule?: string;
severity: "error" | "warning";
}>;
warnings: Array<{
line: number;
column: number;
message: string;
rule?: string;
severity: "error" | "warning";
}>;
};

export class CodeHTTPService extends BaseHTTPClient {
constructor({ endpoint }: { endpoint: string }) {
super({ endpoint });
}

/**
* Format code
*/
async formatCode({
code,
options,
}: {
code: string;
options: FormatOptions;
}): Promise<SynapseResponse<string>> {
return this.request({
type: "code",
operation: "format",
params: {
code,
options,
},
});
}

/**
* Lint code
*/
async lintCode({
code,
language,
}: {
code: string;
language: string;
}): Promise<SynapseResponse<LintResult>> {
return this.request({
type: "code",
operation: "lint",
params: {
code,
language,
},
});
}
}
Loading