diff --git a/lib/commands/types.js b/lib/commands/types.js index 78428f1..9d769e8 100644 --- a/lib/commands/types.js +++ b/lib/commands/types.js @@ -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 @@ -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`); } diff --git a/lib/type-generation/languages/golang.js b/lib/type-generation/languages/golang.js new file mode 100644 index 0000000..a0b2c55 --- /dev/null +++ b/lib/type-generation/languages/golang.js @@ -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 }; diff --git a/lib/type-generation/languages/language.js b/lib/type-generation/languages/language.js index 96ba0bb..bf9e937 100644 --- a/lib/type-generation/languages/language.js +++ b/lib/type-generation/languages/language.js @@ -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"); }