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
3 changes: 3 additions & 0 deletions lib/commands/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const { Java } = require("../type-generation/languages/java");
const { Dart } = require("../type-generation/languages/dart");
const { JavaScript } = require("../type-generation/languages/javascript");
const { CSharp } = require("../type-generation/languages/csharp");
const { Golang } = require("../type-generation/languages/golang");

/**
* @param {string} language
Expand All @@ -36,6 +37,8 @@ function createLanguageMeta(language) {
return new Dart();
case "cs":
return new CSharp();
case "go":
return new Golang();
default:
throw new Error(`Language '${language}' is not supported`);
}
Expand Down
110 changes: 110 additions & 0 deletions lib/type-generation/languages/golang.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/** @typedef {import('../attribute').Attribute} Attribute */
const { AttributeType } = require('../attribute');
const { LanguageMeta } = require("./language");

class Golang extends LanguageMeta {
getType(attribute, collections) {
let type = "";

switch (attribute.type) {
case AttributeType.STRING:
case AttributeType.EMAIL:
case AttributeType.DATETIME:
case AttributeType.IP:
case AttributeType.URL:
type = "string";
if (attribute.format === AttributeType.ENUM) {
type = LanguageMeta.toPascalCase(attribute.key);
}
break;
case AttributeType.INTEGER:
type = "int64";
break;
case AttributeType.FLOAT:
type = "float64";
break;
case AttributeType.BOOLEAN:
type = "bool";
break;
case AttributeType.RELATIONSHIP:
const relatedCollection = collections.find(c => c.$id === attribute.relatedCollection);
if (!relatedCollection) {
throw new Error(`Related collection with ID '${attribute.relatedCollection}' not found.`);
}
type = LanguageMeta.toPascalCase(relatedCollection.name);
if ((attribute.relationType === 'oneToMany' && attribute.side === 'parent') ||
(attribute.relationType === 'manyToOne' && attribute.side === 'child') ||
attribute.relationType === 'manyToMany') {
type = `[]${type}`;
}
break;
default:
throw new Error(`Unknown attribute type: ${attribute.type}`);
}

if (attribute.array) {
type = `[]${type}`;
}

// Handle nullable types with pointer
if (!attribute.required && attribute.default === null) {
type = `*${type}`;
}

return type;
}

isSingleFile() {
return true;
}

getTemplate() {
return `package main

import (
"encoding/json"
"time"
)

// This file is auto-generated by the Appwrite CLI.
// You can regenerate it by running \`appwrite <%= process.argv.slice(2).join(' ') %>\`.

<% for (const collection of collections) { -%>
<% for (const attribute of collection.attributes) { -%>
<% if (attribute.format === 'enum') { -%>
// <%= toPascalCase(attribute.key) %> represents the possible values for <%= attribute.key %>
type <%= toPascalCase(attribute.key) %> string

const (
<% const entries = Object.entries(attribute.elements); -%>
<% for (let i = 0; i < entries.length; i++) { -%>
<%= toPascalCase(attribute.key) %><%= toPascalCase(entries[i][1]) %> <%= toPascalCase(attribute.key) %> = "<%= entries[i][1] %>"
<% } -%>
)

<% } -%>
<% } -%>
<% } -%>

<% for (const [index, collection] of Object.entries(collections)) { -%>
// <%= toPascalCase(collection.name) %> represents a document from the <%= collection.name %> collection
type <%= toPascalCase(collection.name) %> struct {
ID string \`json:"$id"\`
CreatedAt time.Time \`json:"$createdAt"\`
UpdatedAt time.Time \`json:"$updatedAt"\`
Permission []string \`json:"$permissions"\`
<% for (const attribute of collection.attributes) { -%>
<%= toPascalCase(attribute.key) %> <%= getType(attribute, collections) %> \`json:"<%= strict ? toCamelCase(attribute.key) : attribute.key %>"\`
<% } -%>
}<% if (index < collections.length - 1) { %>

<% } -%>
<% } -%>`;
}

getFileName(_) {
return "appwrite.go";
}
}

module.exports = { Golang };
5 changes: 5 additions & 0 deletions lib/type-generation/languages/language.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ function detectLanguage() {
if (existsFiles("pubspec.yaml")) {
return "dart";
}

// Golang support
if (existsFiles("go.mod", "go.sum")) {
return "go";
}
throw new Error("Could not detect language, please specify with -l");
}

Expand Down