appwrite-cli 7.0.0 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/index.js +2 -2
- package/install.ps1 +2 -2
- package/install.sh +1 -1
- package/lib/client.js +2 -2
- package/lib/commands/databases.js +4 -4
- package/lib/commands/types.js +126 -0
- package/lib/parser.js +1 -2
- package/lib/type-generation/attribute.js +16 -0
- package/lib/type-generation/languages/dart.js +152 -0
- package/lib/type-generation/languages/java.js +121 -0
- package/lib/type-generation/languages/javascript.js +84 -0
- package/lib/type-generation/languages/kotlin.js +75 -0
- package/lib/type-generation/languages/language.js +125 -0
- package/lib/type-generation/languages/php.js +100 -0
- package/lib/type-generation/languages/swift.js +156 -0
- package/lib/type-generation/languages/typescript.js +95 -0
- package/package.json +2 -1
- package/scoop/appwrite.json +3 -3
- package/docs/examples/assistant/chat.md +0 -2
- package/lib/commands/assistant.js +0 -85
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ Once the installation is complete, you can verify the install using
|
|
|
29
29
|
|
|
30
30
|
```sh
|
|
31
31
|
$ appwrite -v
|
|
32
|
-
|
|
32
|
+
8.0.0
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
### Install using prebuilt binaries
|
|
@@ -60,7 +60,7 @@ $ scoop install https://raw.githubusercontent.com/appwrite/sdk-for-cli/master/sc
|
|
|
60
60
|
Once the installation completes, you can verify your install using
|
|
61
61
|
```
|
|
62
62
|
$ appwrite -v
|
|
63
|
-
|
|
63
|
+
8.0.0
|
|
64
64
|
```
|
|
65
65
|
|
|
66
66
|
## Getting Started
|
package/index.js
CHANGED
|
@@ -13,12 +13,12 @@ const { client } = require("./lib/commands/generic");
|
|
|
13
13
|
const inquirer = require("inquirer");
|
|
14
14
|
const { login, logout, whoami, migrate, register } = require("./lib/commands/generic");
|
|
15
15
|
const { init } = require("./lib/commands/init");
|
|
16
|
+
const { types } = require("./lib/commands/types");
|
|
16
17
|
const { pull } = require("./lib/commands/pull");
|
|
17
18
|
const { run } = require("./lib/commands/run");
|
|
18
19
|
const { push, deploy } = require("./lib/commands/push");
|
|
19
20
|
const { account } = require("./lib/commands/account");
|
|
20
21
|
const { avatars } = require("./lib/commands/avatars");
|
|
21
|
-
const { assistant } = require("./lib/commands/assistant");
|
|
22
22
|
const { console } = require("./lib/commands/console");
|
|
23
23
|
const { databases } = require("./lib/commands/databases");
|
|
24
24
|
const { functions } = require("./lib/commands/functions");
|
|
@@ -80,12 +80,12 @@ program
|
|
|
80
80
|
.addCommand(init)
|
|
81
81
|
.addCommand(pull)
|
|
82
82
|
.addCommand(push)
|
|
83
|
+
.addCommand(types)
|
|
83
84
|
.addCommand(deploy)
|
|
84
85
|
.addCommand(run)
|
|
85
86
|
.addCommand(logout)
|
|
86
87
|
.addCommand(account)
|
|
87
88
|
.addCommand(avatars)
|
|
88
|
-
.addCommand(assistant)
|
|
89
89
|
.addCommand(console)
|
|
90
90
|
.addCommand(databases)
|
|
91
91
|
.addCommand(functions)
|
package/install.ps1
CHANGED
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
# You can use "View source" of this page to see the full script.
|
|
14
14
|
|
|
15
15
|
# REPO
|
|
16
|
-
$GITHUB_x64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/
|
|
17
|
-
$GITHUB_arm64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/
|
|
16
|
+
$GITHUB_x64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/8.0.0/appwrite-cli-win-x64.exe"
|
|
17
|
+
$GITHUB_arm64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/8.0.0/appwrite-cli-win-arm64.exe"
|
|
18
18
|
|
|
19
19
|
$APPWRITE_BINARY_NAME = "appwrite.exe"
|
|
20
20
|
|
package/install.sh
CHANGED
|
@@ -97,7 +97,7 @@ printSuccess() {
|
|
|
97
97
|
downloadBinary() {
|
|
98
98
|
echo "[2/4] Downloading executable for $OS ($ARCH) ..."
|
|
99
99
|
|
|
100
|
-
GITHUB_LATEST_VERSION="
|
|
100
|
+
GITHUB_LATEST_VERSION="8.0.0"
|
|
101
101
|
GITHUB_FILE="appwrite-cli-${OS}-${ARCH}"
|
|
102
102
|
GITHUB_URL="https://github.com/$GITHUB_REPOSITORY_NAME/releases/download/$GITHUB_LATEST_VERSION/$GITHUB_FILE"
|
|
103
103
|
|
package/lib/client.js
CHANGED
|
@@ -16,8 +16,8 @@ class Client {
|
|
|
16
16
|
'x-sdk-name': 'Command Line',
|
|
17
17
|
'x-sdk-platform': 'console',
|
|
18
18
|
'x-sdk-language': 'cli',
|
|
19
|
-
'x-sdk-version': '
|
|
20
|
-
'user-agent' : `AppwriteCLI/
|
|
19
|
+
'x-sdk-version': '8.0.0',
|
|
20
|
+
'user-agent' : `AppwriteCLI/8.0.0 (${os.type()} ${os.version()}; ${os.arch()})`,
|
|
21
21
|
'X-Appwrite-Response-Format' : '1.7.0',
|
|
22
22
|
};
|
|
23
23
|
}
|
|
@@ -2660,7 +2660,7 @@ databases
|
|
|
2660
2660
|
|
|
2661
2661
|
databases
|
|
2662
2662
|
.command(`create-documents`)
|
|
2663
|
-
.description(
|
|
2663
|
+
.description(`**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions. Create new Documents. Before using this route, you should create a new collection resource using either a [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) API or directly from your database console.`)
|
|
2664
2664
|
.requiredOption(`--database-id <database-id>`, `Database ID.`)
|
|
2665
2665
|
.requiredOption(`--collection-id <collection-id>`, `Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). Make sure to define attributes before creating documents.`)
|
|
2666
2666
|
.requiredOption(`--documents [documents...]`, `Array of documents data as JSON objects.`)
|
|
@@ -2668,7 +2668,7 @@ databases
|
|
|
2668
2668
|
|
|
2669
2669
|
databases
|
|
2670
2670
|
.command(`upsert-documents`)
|
|
2671
|
-
.description(
|
|
2671
|
+
.description(`**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions. Create or update Documents. Before using this route, you should create a new collection resource using either a [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) API or directly from your database console. `)
|
|
2672
2672
|
.requiredOption(`--database-id <database-id>`, `Database ID.`)
|
|
2673
2673
|
.requiredOption(`--collection-id <collection-id>`, `Collection ID.`)
|
|
2674
2674
|
.requiredOption(`--documents [documents...]`, `Array of document data as JSON objects. May contain partial documents.`)
|
|
@@ -2685,7 +2685,7 @@ databases
|
|
|
2685
2685
|
|
|
2686
2686
|
databases
|
|
2687
2687
|
.command(`delete-documents`)
|
|
2688
|
-
.description(
|
|
2688
|
+
.description(`**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions. Bulk delete documents using queries, if no queries are passed then all documents are deleted.`)
|
|
2689
2689
|
.requiredOption(`--database-id <database-id>`, `Database ID.`)
|
|
2690
2690
|
.requiredOption(`--collection-id <collection-id>`, `Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).`)
|
|
2691
2691
|
.option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long.`)
|
|
@@ -2703,7 +2703,7 @@ databases
|
|
|
2703
2703
|
|
|
2704
2704
|
databases
|
|
2705
2705
|
.command(`upsert-document`)
|
|
2706
|
-
.description(
|
|
2706
|
+
.description(`**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions. Create or update a Document. Before using this route, you should create a new collection resource using either a [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) API or directly from your database console.`)
|
|
2707
2707
|
.requiredOption(`--database-id <database-id>`, `Database ID.`)
|
|
2708
2708
|
.requiredOption(`--collection-id <collection-id>`, `Collection ID.`)
|
|
2709
2709
|
.requiredOption(`--document-id <document-id>`, `Document ID.`)
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
const ejs = require("ejs");
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
const path = require("path");
|
|
4
|
+
const { LanguageMeta, detectLanguage } = require("../type-generation/languages/language");
|
|
5
|
+
const { Command, Option, Argument } = require("commander");
|
|
6
|
+
const { localConfig } = require("../config");
|
|
7
|
+
const { success, log, actionRunner } = require("../parser");
|
|
8
|
+
const { PHP } = require("../type-generation/languages/php");
|
|
9
|
+
const { TypeScript } = require("../type-generation/languages/typescript");
|
|
10
|
+
const { Kotlin } = require("../type-generation/languages/kotlin");
|
|
11
|
+
const { Swift } = require("../type-generation/languages/swift");
|
|
12
|
+
const { Java } = require("../type-generation/languages/java");
|
|
13
|
+
const { Dart } = require("../type-generation/languages/dart");
|
|
14
|
+
const { JavaScript } = require("../type-generation/languages/javascript");
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @param {string} language
|
|
18
|
+
* @returns {import("../type-generation/languages/language").LanguageMeta}
|
|
19
|
+
*/
|
|
20
|
+
function createLanguageMeta(language) {
|
|
21
|
+
switch (language) {
|
|
22
|
+
case "ts":
|
|
23
|
+
return new TypeScript();
|
|
24
|
+
case "js":
|
|
25
|
+
return new JavaScript();
|
|
26
|
+
case "php":
|
|
27
|
+
return new PHP();
|
|
28
|
+
case "kotlin":
|
|
29
|
+
return new Kotlin();
|
|
30
|
+
case "swift":
|
|
31
|
+
return new Swift();
|
|
32
|
+
case "java":
|
|
33
|
+
return new Java();
|
|
34
|
+
case "dart":
|
|
35
|
+
return new Dart();
|
|
36
|
+
default:
|
|
37
|
+
throw new Error(`Language '${language}' is not supported`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const templateHelpers = {
|
|
42
|
+
toPascalCase: LanguageMeta.toPascalCase,
|
|
43
|
+
toCamelCase: LanguageMeta.toCamelCase,
|
|
44
|
+
toSnakeCase: LanguageMeta.toSnakeCase,
|
|
45
|
+
toKebabCase: LanguageMeta.toKebabCase,
|
|
46
|
+
toUpperSnakeCase: LanguageMeta.toUpperSnakeCase
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const typesOutputArgument = new Argument(
|
|
50
|
+
"<output-directory>",
|
|
51
|
+
"The directory to write the types to"
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
const typesLanguageOption = new Option(
|
|
55
|
+
"-l, --language <language>",
|
|
56
|
+
"The language of the types"
|
|
57
|
+
)
|
|
58
|
+
.choices(["auto", "ts", "js", "php", "kotlin", "swift", "java", "dart"])
|
|
59
|
+
.default("auto");
|
|
60
|
+
|
|
61
|
+
const typesCommand = actionRunner(async (rawOutputDirectory, {language}) => {
|
|
62
|
+
if (language === "auto") {
|
|
63
|
+
language = detectLanguage();
|
|
64
|
+
log(`Detected language: ${language}`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const meta = createLanguageMeta(language);
|
|
68
|
+
|
|
69
|
+
const outputDirectory = path.resolve(rawOutputDirectory);
|
|
70
|
+
if (!fs.existsSync(outputDirectory)) {
|
|
71
|
+
log(`Directory: ${outputDirectory} does not exist, creating...`);
|
|
72
|
+
fs.mkdirSync(outputDirectory, { recursive: true });
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (!fs.existsSync("appwrite.json")) {
|
|
76
|
+
throw new Error("appwrite.json not found in current directory");
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const collections = localConfig.getCollections();
|
|
80
|
+
if (collections.length === 0) {
|
|
81
|
+
throw new Error("No collections found in appwrite.json");
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
log(`Found ${collections.length} collections: ${collections.map(c => c.name).join(", ")}`);
|
|
85
|
+
|
|
86
|
+
const totalAttributes = collections.reduce((count, collection) => count + collection.attributes.length, 0);
|
|
87
|
+
log(`Found ${totalAttributes} attributes across all collections`);
|
|
88
|
+
|
|
89
|
+
const templater = ejs.compile(meta.getTemplate());
|
|
90
|
+
|
|
91
|
+
if (meta.isSingleFile()) {
|
|
92
|
+
const content = templater({
|
|
93
|
+
collections,
|
|
94
|
+
...templateHelpers,
|
|
95
|
+
getType: meta.getType
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
const destination = path.join(outputDirectory, meta.getFileName());
|
|
99
|
+
|
|
100
|
+
fs.writeFileSync(destination, content);
|
|
101
|
+
log(`Added types to ${destination}`);
|
|
102
|
+
} else {
|
|
103
|
+
for (const collection of collections) {
|
|
104
|
+
const content = templater({
|
|
105
|
+
collection,
|
|
106
|
+
...templateHelpers,
|
|
107
|
+
getType: meta.getType
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
const destination = path.join(outputDirectory, meta.getFileName(collection));
|
|
111
|
+
|
|
112
|
+
fs.writeFileSync(destination, content);
|
|
113
|
+
log(`Added types for ${collection.name} to ${destination}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
success(`Generated types for all the listed collections`);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
const types = new Command("types")
|
|
121
|
+
.description("Generate types for your Appwrite project")
|
|
122
|
+
.addArgument(typesOutputArgument)
|
|
123
|
+
.addOption(typesLanguageOption)
|
|
124
|
+
.action(actionRunner(typesCommand));
|
|
125
|
+
|
|
126
|
+
module.exports = { types };
|
package/lib/parser.js
CHANGED
|
@@ -120,7 +120,7 @@ const parseError = (err) => {
|
|
|
120
120
|
} catch {
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
const version = '
|
|
123
|
+
const version = '8.0.0';
|
|
124
124
|
const stepsToReproduce = `Running \`appwrite ${cliConfig.reportData.data.args.join(' ')}\``;
|
|
125
125
|
const yourEnvironment = `CLI version: ${version}\nOperation System: ${os.type()}\nAppwrite version: ${appwriteVersion}\nIs Cloud: ${isCloud}`;
|
|
126
126
|
|
|
@@ -221,7 +221,6 @@ const commandDescriptions = {
|
|
|
221
221
|
"whoami": `The whomai command gives information about the currently logged-in user.`,
|
|
222
222
|
"register": `Outputs the link to create an Appwrite account.`,
|
|
223
223
|
"console" : `The console command gives you access to the APIs used by the Appwrite Console.`,
|
|
224
|
-
"assistant": `The assistant command allows you to interact with the Appwrite Assistant AI`,
|
|
225
224
|
"messaging": `The messaging command allows you to manage topics and targets and send messages.`,
|
|
226
225
|
"migrations": `The migrations command allows you to migrate data between services.`,
|
|
227
226
|
"vcs": `The vcs command allows you to interact with VCS providers and manage your code repositories.`,
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const AttributeType = {
|
|
2
|
+
STRING: "string",
|
|
3
|
+
INTEGER: "integer",
|
|
4
|
+
FLOAT: "float",
|
|
5
|
+
BOOLEAN: "boolean",
|
|
6
|
+
DATETIME: "datetime",
|
|
7
|
+
EMAIL: "email",
|
|
8
|
+
IP: "ip",
|
|
9
|
+
URL: "url",
|
|
10
|
+
ENUM: "enum",
|
|
11
|
+
RELATIONSHIP: "relationship",
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
module.exports = {
|
|
15
|
+
AttributeType,
|
|
16
|
+
};
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/** @typedef {import('../attribute').Attribute} Attribute */
|
|
2
|
+
const { AttributeType } = require('../attribute');
|
|
3
|
+
const { LanguageMeta } = require("./language");
|
|
4
|
+
|
|
5
|
+
class Dart extends LanguageMeta {
|
|
6
|
+
getType(attribute) {
|
|
7
|
+
let type = "";
|
|
8
|
+
switch (attribute.type) {
|
|
9
|
+
case AttributeType.STRING:
|
|
10
|
+
case AttributeType.EMAIL:
|
|
11
|
+
case AttributeType.DATETIME:
|
|
12
|
+
type = "String";
|
|
13
|
+
if (attribute.format === AttributeType.ENUM) {
|
|
14
|
+
type = LanguageMeta.toPascalCase(attribute.key);
|
|
15
|
+
}
|
|
16
|
+
break;
|
|
17
|
+
case AttributeType.INTEGER:
|
|
18
|
+
type = "int";
|
|
19
|
+
break;
|
|
20
|
+
case AttributeType.FLOAT:
|
|
21
|
+
type = "double";
|
|
22
|
+
break;
|
|
23
|
+
case AttributeType.BOOLEAN:
|
|
24
|
+
type = "bool";
|
|
25
|
+
break;
|
|
26
|
+
case AttributeType.RELATIONSHIP:
|
|
27
|
+
type = LanguageMeta.toPascalCase(attribute.relatedCollection);
|
|
28
|
+
if ((attribute.relationType === 'oneToMany' && attribute.side === 'parent') || (attribute.relationType === 'manyToOne' && attribute.side === 'child') || attribute.relationType === 'manyToMany') {
|
|
29
|
+
type = `List<${type}>`;
|
|
30
|
+
}
|
|
31
|
+
break;
|
|
32
|
+
default:
|
|
33
|
+
throw new Error(`Unknown attribute type: ${attribute.type}`);
|
|
34
|
+
}
|
|
35
|
+
if (attribute.array) {
|
|
36
|
+
type = `List<${type}>`;
|
|
37
|
+
}
|
|
38
|
+
if (!attribute.required) {
|
|
39
|
+
type += "?";
|
|
40
|
+
}
|
|
41
|
+
return type;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
getTemplate() {
|
|
45
|
+
return `<% for (const attribute of collection.attributes) { -%>
|
|
46
|
+
<% if (attribute.type === 'relationship') { -%>
|
|
47
|
+
import '<%- attribute.relatedCollection.toLowerCase() %>.dart';
|
|
48
|
+
|
|
49
|
+
<% } -%>
|
|
50
|
+
<% } -%>
|
|
51
|
+
<% for (const attribute of collection.attributes) { -%>
|
|
52
|
+
<% if (attribute.format === 'enum') { -%>
|
|
53
|
+
enum <%- toPascalCase(attribute.key) %> {
|
|
54
|
+
<% for (const element of attribute.elements) { -%>
|
|
55
|
+
<%- element %>,
|
|
56
|
+
<% } -%>
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
<% } -%>
|
|
60
|
+
<% } -%>
|
|
61
|
+
class <%= toPascalCase(collection.name) %> {
|
|
62
|
+
<% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
|
|
63
|
+
<%- getType(attribute) %> <%= toCamelCase(attribute.key) %>;
|
|
64
|
+
<% } -%>
|
|
65
|
+
|
|
66
|
+
<%= toPascalCase(collection.name) %>({
|
|
67
|
+
<% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
|
|
68
|
+
<% if (attribute.required) { %>required <% } %>this.<%= toCamelCase(attribute.key) %>,
|
|
69
|
+
<% } -%>
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
factory <%= toPascalCase(collection.name) %>.fromMap(Map<String, dynamic> map) {
|
|
73
|
+
return <%= toPascalCase(collection.name) %>(
|
|
74
|
+
<% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
|
|
75
|
+
<%= toCamelCase(attribute.key) %>: <% if (attribute.type === 'string' || attribute.type === 'email' || attribute.type === 'datetime') { -%>
|
|
76
|
+
<% if (attribute.format === 'enum') { -%>
|
|
77
|
+
<% if (attribute.array) { -%>
|
|
78
|
+
(map['<%= attribute.key %>'] as List<dynamic>?)?.map((e) => <%- toPascalCase(attribute.key) %>.values.firstWhere((element) => element.name == e)).toList()<% if (!attribute.required) { %> ?? []<% } -%>
|
|
79
|
+
<% } else { -%>
|
|
80
|
+
<% if (!attribute.required) { -%>
|
|
81
|
+
map['<%= attribute.key %>'] != null ? <%- toPascalCase(attribute.key) %>.values.where((e) => e.name == map['<%= attribute.key %>']).firstOrNull : null<% } else { -%>
|
|
82
|
+
<%- toPascalCase(attribute.key) %>.values.firstWhere((e) => e.name == map['<%= attribute.key %>'])<% } -%>
|
|
83
|
+
<% } -%>
|
|
84
|
+
<% } else { -%>
|
|
85
|
+
<% if (attribute.array) { -%>
|
|
86
|
+
List<String>.from(map['<%= attribute.key %>'] ?? [])<% if (!attribute.required) { %> ?? []<% } -%>
|
|
87
|
+
<% } else { -%>
|
|
88
|
+
map['<%= attribute.key %>']<% if (!attribute.required) { %>?<% } %>.toString()<% if (!attribute.required) { %> ?? null<% } -%>
|
|
89
|
+
<% } -%>
|
|
90
|
+
<% } -%>
|
|
91
|
+
<% } else if (attribute.type === 'integer') { -%>
|
|
92
|
+
<% if (attribute.array) { -%>
|
|
93
|
+
List<int>.from(map['<%= attribute.key %>'] ?? [])<% if (!attribute.required) { %> ?? []<% } -%>
|
|
94
|
+
<% } else { -%>
|
|
95
|
+
map['<%= attribute.key %>']<% if (!attribute.required) { %> ?? null<% } -%>
|
|
96
|
+
<% } -%>
|
|
97
|
+
<% } else if (attribute.type === 'float') { -%>
|
|
98
|
+
<% if (attribute.array) { -%>
|
|
99
|
+
List<double>.from(map['<%= attribute.key %>'] ?? [])<% if (!attribute.required) { %> ?? []<% } -%>
|
|
100
|
+
<% } else { -%>
|
|
101
|
+
map['<%= attribute.key %>']<% if (!attribute.required) { %> ?? null<% } -%>
|
|
102
|
+
<% } -%>
|
|
103
|
+
<% } else if (attribute.type === 'boolean') { -%>
|
|
104
|
+
<% if (attribute.array) { -%>
|
|
105
|
+
List<bool>.from(map['<%= attribute.key %>'] ?? [])<% if (!attribute.required) { %> ?? []<% } -%>
|
|
106
|
+
<% } else { -%>
|
|
107
|
+
map['<%= attribute.key %>']<% if (!attribute.required) { %> ?? null<% } -%>
|
|
108
|
+
<% } -%>
|
|
109
|
+
<% } else if (attribute.type === 'relationship') { -%>
|
|
110
|
+
<% if ((attribute.relationType === 'oneToMany' && attribute.side === 'parent') || (attribute.relationType === 'manyToOne' && attribute.side === 'child') || attribute.relationType === 'manyToMany') { -%>
|
|
111
|
+
(map['<%= attribute.key %>'] as List<dynamic>?)?.map((e) => <%- toPascalCase(attribute.relatedCollection) %>.fromMap(e)).toList()<% if (!attribute.required) { %> ?? []<% } -%>
|
|
112
|
+
<% } else { -%>
|
|
113
|
+
<% if (!attribute.required) { -%>
|
|
114
|
+
map['<%= attribute.key %>'] != null ? <%- toPascalCase(attribute.relatedCollection) %>.fromMap(map['<%= attribute.key %>']) : null<% } else { -%>
|
|
115
|
+
<%- toPascalCase(attribute.relatedCollection) %>.fromMap(map['<%= attribute.key %>'])<% } -%>
|
|
116
|
+
<% } -%>
|
|
117
|
+
<% } -%>,
|
|
118
|
+
<% } -%>
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
Map<String, dynamic> toMap() {
|
|
123
|
+
return {
|
|
124
|
+
<% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
|
|
125
|
+
"<%= attribute.key %>": <% if (attribute.type === 'relationship') { -%>
|
|
126
|
+
<% if ((attribute.relationType === 'oneToMany' && attribute.side === 'parent') || (attribute.relationType === 'manyToOne' && attribute.side === 'child') || attribute.relationType === 'manyToMany') { -%>
|
|
127
|
+
<%= toCamelCase(attribute.key) %><% if (!attribute.required) { %>?<% } %>.map((e) => e.toMap()).toList()<% if (!attribute.required) { %> ?? []<% } -%>
|
|
128
|
+
<% } else { -%>
|
|
129
|
+
<%= toCamelCase(attribute.key) %><% if (!attribute.required) { %>?<% } %>.toMap()<% if (!attribute.required) { %> ?? {}<% } -%>
|
|
130
|
+
<% } -%>
|
|
131
|
+
<% } else if (attribute.format === 'enum') { -%>
|
|
132
|
+
<% if (attribute.array) { -%>
|
|
133
|
+
<%= toCamelCase(attribute.key) %><% if (!attribute.required) { %>?<% } %>.map((e) => e.name).toList()<% if (!attribute.required) { %> ?? []<% } -%>
|
|
134
|
+
<% } else { -%>
|
|
135
|
+
<%= toCamelCase(attribute.key) %><% if (!attribute.required) { %>?<% } %>.name<% if (!attribute.required) { %> ?? null<% } -%>
|
|
136
|
+
<% } -%>
|
|
137
|
+
<% } else { -%>
|
|
138
|
+
<%= toCamelCase(attribute.key) -%>
|
|
139
|
+
<% } -%>,
|
|
140
|
+
<% } -%>
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
`;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
getFileName(collection) {
|
|
148
|
+
return LanguageMeta.toSnakeCase(collection.name) + ".dart";
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
module.exports = { Dart };
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/** @typedef {import('../attribute').Attribute} Attribute */
|
|
2
|
+
const { AttributeType } = require('../attribute');
|
|
3
|
+
const { LanguageMeta } = require("./language");
|
|
4
|
+
|
|
5
|
+
class Java extends LanguageMeta {
|
|
6
|
+
getType(attribute) {
|
|
7
|
+
let type = "";
|
|
8
|
+
switch (attribute.type) {
|
|
9
|
+
case AttributeType.STRING:
|
|
10
|
+
case AttributeType.EMAIL:
|
|
11
|
+
case AttributeType.DATETIME:
|
|
12
|
+
type = "String";
|
|
13
|
+
if (attribute.format === AttributeType.ENUM) {
|
|
14
|
+
type = LanguageMeta.toPascalCase(attribute.key);
|
|
15
|
+
}
|
|
16
|
+
break;
|
|
17
|
+
case AttributeType.INTEGER:
|
|
18
|
+
type = "int";
|
|
19
|
+
break;
|
|
20
|
+
case AttributeType.FLOAT:
|
|
21
|
+
type = "double";
|
|
22
|
+
break;
|
|
23
|
+
case AttributeType.BOOLEAN:
|
|
24
|
+
type = "boolean";
|
|
25
|
+
break;
|
|
26
|
+
case AttributeType.RELATIONSHIP:
|
|
27
|
+
type = LanguageMeta.toPascalCase(attribute.relatedCollection);
|
|
28
|
+
if ((attribute.relationType === 'oneToMany' && attribute.side === 'parent') || (attribute.relationType === 'manyToOne' && attribute.side === 'child') || attribute.relationType === 'manyToMany') {
|
|
29
|
+
type = "List<" + type + ">";
|
|
30
|
+
}
|
|
31
|
+
break;
|
|
32
|
+
default:
|
|
33
|
+
throw new Error(`Unknown attribute type: ${attribute.type}`);
|
|
34
|
+
}
|
|
35
|
+
if (attribute.array) {
|
|
36
|
+
type = "List<" + type + ">";
|
|
37
|
+
}
|
|
38
|
+
return type;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
getTemplate() {
|
|
42
|
+
return `package io.appwrite.models;
|
|
43
|
+
|
|
44
|
+
import java.util.*;
|
|
45
|
+
<% for (const attribute of collection.attributes) { -%>
|
|
46
|
+
<% if (attribute.type === 'relationship') { -%>
|
|
47
|
+
import <%- toPascalCase(attribute.relatedCollection) %>;
|
|
48
|
+
|
|
49
|
+
<% } -%>
|
|
50
|
+
<% } -%>
|
|
51
|
+
public class <%- toPascalCase(collection.name) %> {
|
|
52
|
+
<% for (const attribute of collection.attributes) { -%>
|
|
53
|
+
<% if (attribute.format === 'enum') { -%>
|
|
54
|
+
|
|
55
|
+
public enum <%- toPascalCase(attribute.key) %> {
|
|
56
|
+
<% for (const [index, element] of Object.entries(attribute.elements)) { -%>
|
|
57
|
+
<%- element %><%- index < attribute.elements.length - 1 ? ',' : ';' %>
|
|
58
|
+
<% } -%>
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
<% } -%>
|
|
62
|
+
<% } -%>
|
|
63
|
+
<% for (const attribute of collection.attributes) { -%>
|
|
64
|
+
private <%- getType(attribute) %> <%- toCamelCase(attribute.key) %>;
|
|
65
|
+
<% } -%>
|
|
66
|
+
|
|
67
|
+
public <%- toPascalCase(collection.name) %>() {
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
public <%- toPascalCase(collection.name) %>(
|
|
71
|
+
<% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
|
|
72
|
+
<%- getType(attribute) %> <%= toCamelCase(attribute.key) %><%- index < collection.attributes.length - 1 ? ',' : '' %>
|
|
73
|
+
<% } -%>
|
|
74
|
+
) {
|
|
75
|
+
<% for (const attribute of collection.attributes) { -%>
|
|
76
|
+
this.<%= toCamelCase(attribute.key) %> = <%= toCamelCase(attribute.key) %>;
|
|
77
|
+
<% } -%>
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
<% for (const attribute of collection.attributes) { -%>
|
|
81
|
+
public <%- getType(attribute) %> get<%- toPascalCase(attribute.key) %>() {
|
|
82
|
+
return <%= toCamelCase(attribute.key) %>;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
public void set<%- toPascalCase(attribute.key) %>(<%- getType(attribute) %> <%= toCamelCase(attribute.key) %>) {
|
|
86
|
+
this.<%= toCamelCase(attribute.key) %> = <%= toCamelCase(attribute.key) %>;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
<% } -%>
|
|
90
|
+
@Override
|
|
91
|
+
public boolean equals(Object obj) {
|
|
92
|
+
if (this == obj) return true;
|
|
93
|
+
if (obj == null || getClass() != obj.getClass()) return false;
|
|
94
|
+
<%- toPascalCase(collection.name) %> that = (<%- toPascalCase(collection.name) %>) obj;
|
|
95
|
+
return <% collection.attributes.forEach((attr, index) => { %>Objects.equals(<%= toCamelCase(attr.key) %>, that.<%= toCamelCase(attr.key) %>)<% if (index < collection.attributes.length - 1) { %> &&
|
|
96
|
+
<% } }); %>;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
@Override
|
|
100
|
+
public int hashCode() {
|
|
101
|
+
return Objects.hash(<%= collection.attributes.map(attr => toCamelCase(attr.key)).join(', ') %>);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
@Override
|
|
105
|
+
public String toString() {
|
|
106
|
+
return "<%- toPascalCase(collection.name) %>{" +
|
|
107
|
+
<% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
|
|
108
|
+
"<%= toCamelCase(attribute.key) %>=" + <%= toCamelCase(attribute.key) %> +
|
|
109
|
+
<% } -%>
|
|
110
|
+
'}';
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
`;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
getFileName(collection) {
|
|
117
|
+
return LanguageMeta.toPascalCase(collection.name) + ".java";
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
module.exports = { Java };
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/** @typedef {import('../attribute').Attribute} Attribute */
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
const path = require("path");
|
|
4
|
+
|
|
5
|
+
const { AttributeType } = require('../attribute');
|
|
6
|
+
const { LanguageMeta } = require("./language");
|
|
7
|
+
|
|
8
|
+
class JavaScript extends LanguageMeta {
|
|
9
|
+
getType(attribute) {
|
|
10
|
+
let type = ""
|
|
11
|
+
switch (attribute.type) {
|
|
12
|
+
case AttributeType.STRING:
|
|
13
|
+
case AttributeType.EMAIL:
|
|
14
|
+
case AttributeType.DATETIME:
|
|
15
|
+
case AttributeType.IP:
|
|
16
|
+
case AttributeType.URL:
|
|
17
|
+
type = "string";
|
|
18
|
+
if (attribute.format === AttributeType.ENUM) {
|
|
19
|
+
type = `"${attribute.elements.join('"|"')}"`;
|
|
20
|
+
}
|
|
21
|
+
break;
|
|
22
|
+
case AttributeType.INTEGER:
|
|
23
|
+
type = "number";
|
|
24
|
+
break;
|
|
25
|
+
case AttributeType.FLOAT:
|
|
26
|
+
type = "number";
|
|
27
|
+
break;
|
|
28
|
+
case AttributeType.BOOLEAN:
|
|
29
|
+
type = "boolean";
|
|
30
|
+
break;
|
|
31
|
+
case AttributeType.RELATIONSHIP:
|
|
32
|
+
type = LanguageMeta.toPascalCase(attribute.relatedCollection);
|
|
33
|
+
if ((attribute.relationType === 'oneToMany' && attribute.side === 'parent') || (attribute.relationType === 'manyToOne' && attribute.side === 'child') || attribute.relationType === 'manyToMany') {
|
|
34
|
+
type = `Array<${type}>`;
|
|
35
|
+
}
|
|
36
|
+
break;
|
|
37
|
+
default:
|
|
38
|
+
throw new Error(`Unknown attribute type: ${attribute.type}`);
|
|
39
|
+
}
|
|
40
|
+
if (attribute.array) {
|
|
41
|
+
type += "[]";
|
|
42
|
+
}
|
|
43
|
+
if (!attribute.required) {
|
|
44
|
+
type += "|null|undefined";
|
|
45
|
+
}
|
|
46
|
+
return type;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
isSingleFile() {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
_getAppwriteDependency() {
|
|
54
|
+
if (fs.existsSync(path.resolve(process.cwd(), 'package.json'))) {
|
|
55
|
+
const packageJsonRaw = fs.readFileSync(path.resolve(process.cwd(), 'package.json'));
|
|
56
|
+
const packageJson = JSON.parse(packageJsonRaw.toString('utf-8'));
|
|
57
|
+
return packageJson.dependencies['node-appwrite'] ? 'node-appwrite' : 'appwrite';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return "appwrite";
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
getTemplate() {
|
|
64
|
+
return `/**
|
|
65
|
+
* @typedef {import('${this._getAppwriteDependency()}').Models.Document} Document
|
|
66
|
+
*/
|
|
67
|
+
|
|
68
|
+
<% for (const collection of collections) { %>
|
|
69
|
+
/**
|
|
70
|
+
* @typedef {Object} <%- toPascalCase(collection.name) %>
|
|
71
|
+
<% for (const attribute of collection.attributes) { -%>
|
|
72
|
+
* @property {<%- getType(attribute) %>} <%- toCamelCase(attribute.key) %>
|
|
73
|
+
<% } -%>
|
|
74
|
+
*/
|
|
75
|
+
|
|
76
|
+
<% } %>`;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
getFileName(_) {
|
|
80
|
+
return "appwrite-types.js";
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
module.exports = { JavaScript };
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/** @typedef {import('../attribute').Attribute} Attribute */
|
|
2
|
+
const { AttributeType } = require('../attribute');
|
|
3
|
+
const { LanguageMeta } = require("./language");
|
|
4
|
+
|
|
5
|
+
class Kotlin extends LanguageMeta {
|
|
6
|
+
getType(attribute) {
|
|
7
|
+
let type = "";
|
|
8
|
+
switch (attribute.type) {
|
|
9
|
+
case AttributeType.STRING:
|
|
10
|
+
case AttributeType.EMAIL:
|
|
11
|
+
case AttributeType.DATETIME:
|
|
12
|
+
type = "String";
|
|
13
|
+
if (attribute.format === AttributeType.ENUM) {
|
|
14
|
+
type = LanguageMeta.toPascalCase(attribute.key);
|
|
15
|
+
}
|
|
16
|
+
break;
|
|
17
|
+
case AttributeType.INTEGER:
|
|
18
|
+
type = "Int";
|
|
19
|
+
break;
|
|
20
|
+
case AttributeType.FLOAT:
|
|
21
|
+
type = "Float";
|
|
22
|
+
break;
|
|
23
|
+
case AttributeType.BOOLEAN:
|
|
24
|
+
type = "Boolean";
|
|
25
|
+
break;
|
|
26
|
+
case AttributeType.RELATIONSHIP:
|
|
27
|
+
type = LanguageMeta.toPascalCase(attribute.relatedCollection);
|
|
28
|
+
if ((attribute.relationType === 'oneToMany' && attribute.side === 'parent') || (attribute.relationType === 'manyToOne' && attribute.side === 'child') || attribute.relationType === 'manyToMany') {
|
|
29
|
+
type = `List<${type}>`;
|
|
30
|
+
}
|
|
31
|
+
break;
|
|
32
|
+
default:
|
|
33
|
+
throw new Error(`Unknown attribute type: ${attribute.type}`);
|
|
34
|
+
}
|
|
35
|
+
if (attribute.array) {
|
|
36
|
+
type = "List<" + type + ">";
|
|
37
|
+
}
|
|
38
|
+
if (!attribute.required) {
|
|
39
|
+
type += "?";
|
|
40
|
+
}
|
|
41
|
+
return type;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
getTemplate() {
|
|
45
|
+
return `package io.appwrite.models
|
|
46
|
+
|
|
47
|
+
<% for (const attribute of collection.attributes) { -%>
|
|
48
|
+
<% if (attribute.type === 'relationship') { -%>
|
|
49
|
+
import <%- toPascalCase(attribute.relatedCollection) %>
|
|
50
|
+
|
|
51
|
+
<% } -%>
|
|
52
|
+
<% } -%>
|
|
53
|
+
<% for (const attribute of collection.attributes) { -%>
|
|
54
|
+
<% if (attribute.format === 'enum') { -%>
|
|
55
|
+
enum class <%- toPascalCase(attribute.key) %> {
|
|
56
|
+
<% for (const [index, element] of Object.entries(attribute.elements)) { -%>
|
|
57
|
+
<%- element %><%- index < attribute.elements.length - 1 ? ',' : '' %>
|
|
58
|
+
<% } -%>
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
<% } -%>
|
|
62
|
+
<% } -%>
|
|
63
|
+
data class <%- toPascalCase(collection.name) %>(
|
|
64
|
+
<% for (const attribute of collection.attributes) { -%>
|
|
65
|
+
val <%- toCamelCase(attribute.key) %>: <%- getType(attribute) %>,
|
|
66
|
+
<% } -%>
|
|
67
|
+
)`;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
getFileName(collection) {
|
|
71
|
+
return LanguageMeta.toPascalCase(collection.name) + ".kt";
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
module.exports = { Kotlin };
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/** @typedef {import('../attribute').Attribute} Attribute */
|
|
2
|
+
/** @typedef {import('../collection').Collection} Collection */
|
|
3
|
+
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
|
|
7
|
+
class LanguageMeta {
|
|
8
|
+
constructor() {
|
|
9
|
+
if (new.target === LanguageMeta) {
|
|
10
|
+
throw new TypeError("Abstract classes can't be instantiated.");
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
static toKebabCase(string) {
|
|
15
|
+
return string
|
|
16
|
+
.replace(/[^a-zA-Z0-9\s-_]/g, "") // Remove invalid characters
|
|
17
|
+
.replace(/([a-z])([A-Z])/g, "$1-$2") // Add hyphen between camelCase
|
|
18
|
+
.replace(/([A-Z])([A-Z][a-z])/g, "$1-$2") // Add hyphen between PascalCase
|
|
19
|
+
.replace(/[_\s]+/g, "-") // Replace spaces and underscores with hyphens
|
|
20
|
+
.replace(/^-+|-+$/g, "") // Remove leading and trailing hyphens
|
|
21
|
+
.replace(/--+/g, "-") // Replace multiple hyphens with a single hyphen
|
|
22
|
+
.toLowerCase();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
static toSnakeCase(string) {
|
|
26
|
+
return this.toKebabCase(string).replace(/-/g, "_");
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
static toUpperSnakeCase(string) {
|
|
30
|
+
return this.toSnakeCase(string).toUpperCase();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
static toCamelCase(string) {
|
|
34
|
+
return this.toKebabCase(string).replace(/-([a-z0-9])/g, (g) =>
|
|
35
|
+
g[1].toUpperCase()
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
static toPascalCase(string) {
|
|
40
|
+
return this.toCamelCase(string).replace(/^./, (g) => g.toUpperCase());
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Get the type literal of the given attribute.
|
|
45
|
+
*
|
|
46
|
+
* @abstract
|
|
47
|
+
* @param {Attribute} attribute
|
|
48
|
+
* @return {string}
|
|
49
|
+
*/
|
|
50
|
+
getType(attribute) {
|
|
51
|
+
throw new TypeError("Stub.");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Returns true if the language uses a single file for all types.
|
|
56
|
+
*
|
|
57
|
+
* @returns {boolean}
|
|
58
|
+
*/
|
|
59
|
+
isSingleFile() {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Get the EJS template used to generate the types for this language.
|
|
65
|
+
*
|
|
66
|
+
* @abstract
|
|
67
|
+
* @returns {string}
|
|
68
|
+
*/
|
|
69
|
+
getTemplate() {
|
|
70
|
+
throw new TypeError("Stub.");
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Get the file extension used by files of this language.
|
|
75
|
+
*
|
|
76
|
+
* @abstract
|
|
77
|
+
* @param {Collection|undefined} collection
|
|
78
|
+
* @returns {string}
|
|
79
|
+
*/
|
|
80
|
+
getFileName(collection) {
|
|
81
|
+
throw new TypeError("Stub.");
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const existsFiles = (...files) =>
|
|
86
|
+
files.some((file) => fs.existsSync(path.join(process.cwd(), file)));
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* @returns {string}
|
|
90
|
+
*/
|
|
91
|
+
function detectLanguage() {
|
|
92
|
+
if (existsFiles("tsconfig.json", "deno.json")) {
|
|
93
|
+
return "ts";
|
|
94
|
+
}
|
|
95
|
+
if (existsFiles("package.json")) {
|
|
96
|
+
return "js";
|
|
97
|
+
}
|
|
98
|
+
if (existsFiles("composer.json")) {
|
|
99
|
+
return "php";
|
|
100
|
+
}
|
|
101
|
+
if (existsFiles("requirements.txt", "Pipfile", "pyproject.toml")) {
|
|
102
|
+
return "python";
|
|
103
|
+
}
|
|
104
|
+
if (existsFiles("Gemfile", "Rakefile")) {
|
|
105
|
+
return "ruby";
|
|
106
|
+
}
|
|
107
|
+
if (existsFiles("build.gradle.kts")) {
|
|
108
|
+
return "kotlin";
|
|
109
|
+
}
|
|
110
|
+
if (existsFiles("build.gradle", "pom.xml")) {
|
|
111
|
+
return "java";
|
|
112
|
+
}
|
|
113
|
+
if (existsFiles("*.csproj")) {
|
|
114
|
+
return "dotnet";
|
|
115
|
+
}
|
|
116
|
+
if (existsFiles("Package.swift")) {
|
|
117
|
+
return "swift";
|
|
118
|
+
}
|
|
119
|
+
if (existsFiles("pubspec.yaml")) {
|
|
120
|
+
return "dart";
|
|
121
|
+
}
|
|
122
|
+
throw new Error("Could not detect language, please specify with -l");
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
module.exports = { LanguageMeta, detectLanguage };
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/** @typedef {import('../attribute').Attribute} Attribute */
|
|
2
|
+
const { AttributeType } = require('../attribute');
|
|
3
|
+
const { LanguageMeta } = require("./language");
|
|
4
|
+
|
|
5
|
+
class PHP extends LanguageMeta {
|
|
6
|
+
getType(attribute) {
|
|
7
|
+
if (attribute.array) {
|
|
8
|
+
return "array";
|
|
9
|
+
}
|
|
10
|
+
let type = ""
|
|
11
|
+
switch (attribute.type) {
|
|
12
|
+
case AttributeType.STRING:
|
|
13
|
+
case AttributeType.EMAIL:
|
|
14
|
+
case AttributeType.DATETIME:
|
|
15
|
+
type = "string";
|
|
16
|
+
if (attribute.format === AttributeType.ENUM) {
|
|
17
|
+
type = LanguageMeta.toPascalCase(attribute.key);
|
|
18
|
+
}
|
|
19
|
+
break;
|
|
20
|
+
case AttributeType.INTEGER:
|
|
21
|
+
type = "int";
|
|
22
|
+
break;
|
|
23
|
+
case AttributeType.FLOAT:
|
|
24
|
+
type = "float";
|
|
25
|
+
break;
|
|
26
|
+
case AttributeType.BOOLEAN:
|
|
27
|
+
type = "bool";
|
|
28
|
+
break;
|
|
29
|
+
case AttributeType.RELATIONSHIP:
|
|
30
|
+
type = LanguageMeta.toPascalCase(attribute.relatedCollection);
|
|
31
|
+
if ((attribute.relationType === 'oneToMany' && attribute.side === 'parent') || (attribute.relationType === 'manyToOne' && attribute.side === 'child') || attribute.relationType === 'manyToMany') {
|
|
32
|
+
type = "array";
|
|
33
|
+
}
|
|
34
|
+
break;
|
|
35
|
+
default:
|
|
36
|
+
throw new Error(`Unknown attribute type: ${attribute.type}`);
|
|
37
|
+
}
|
|
38
|
+
if (!attribute.required) {
|
|
39
|
+
type += "|null";
|
|
40
|
+
}
|
|
41
|
+
return type;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
getTemplate() {
|
|
45
|
+
return `<?php
|
|
46
|
+
namespace Appwrite\\Models;
|
|
47
|
+
|
|
48
|
+
<% for (const attribute of collection.attributes) { -%>
|
|
49
|
+
<% if (attribute.type === 'relationship' && !(attribute.relationType === 'manyToMany') && !(attribute.relationType === 'oneToMany' && attribute.side === 'parent')) { -%>
|
|
50
|
+
use Appwrite\\Models\\<%- toPascalCase(attribute.relatedCollection) %>;
|
|
51
|
+
|
|
52
|
+
<% } -%>
|
|
53
|
+
<% } -%>
|
|
54
|
+
<% for (const attribute of collection.attributes) { -%>
|
|
55
|
+
<% if (attribute.format === 'enum') { -%>
|
|
56
|
+
enum <%- toPascalCase(attribute.key) %> {
|
|
57
|
+
<% for (const [index, element] of Object.entries(attribute.elements)) { -%>
|
|
58
|
+
case <%- element.toUpperCase() %> = '<%- element %>';
|
|
59
|
+
<% } -%>
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
<% } -%>
|
|
63
|
+
<% } -%>
|
|
64
|
+
class <%- toPascalCase(collection.name) %> {
|
|
65
|
+
<% for (const attribute of collection.attributes ){ -%>
|
|
66
|
+
private <%- getType(attribute) %> $<%- toCamelCase(attribute.key) %>;
|
|
67
|
+
<% } -%>
|
|
68
|
+
|
|
69
|
+
public function __construct(
|
|
70
|
+
<% for (const attribute of collection.attributes ){ -%>
|
|
71
|
+
<% if (attribute.required) { -%>
|
|
72
|
+
<%- getType(attribute).replace('|null', '') %> $<%- toCamelCase(attribute.key) %><% if (collection.attributes.indexOf(attribute) < collection.attributes.length - 1) { %>,<% } %>
|
|
73
|
+
<% } else { -%>
|
|
74
|
+
?<%- getType(attribute).replace('|null', '') %> $<%- toCamelCase(attribute.key) %> = null<% if (collection.attributes.indexOf(attribute) < collection.attributes.length - 1) { %>,<% } %>
|
|
75
|
+
<% } -%>
|
|
76
|
+
<% } -%>
|
|
77
|
+
) {
|
|
78
|
+
<% for (const attribute of collection.attributes ){ -%>
|
|
79
|
+
$this-><%- toCamelCase(attribute.key) %> = $<%- toCamelCase(attribute.key) %>;
|
|
80
|
+
<% } -%>
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
<% for (const attribute of collection.attributes ){ -%>
|
|
84
|
+
public function get<%- toPascalCase(attribute.key) %>(): <%- getType(attribute) %> {
|
|
85
|
+
return $this-><%- toCamelCase(attribute.key) %>;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
public function set<%- toPascalCase(attribute.key) %>(<%- getType(attribute) %> $<%- toCamelCase(attribute.key) %>): void {
|
|
89
|
+
$this-><%- toCamelCase(attribute.key) %> = $<%- toCamelCase(attribute.key) %>;
|
|
90
|
+
}
|
|
91
|
+
<% } -%>
|
|
92
|
+
}`;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
getFileName(collection) {
|
|
96
|
+
return LanguageMeta.toPascalCase(collection.name) + ".php";
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
module.exports = { PHP };
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/** @typedef {import('../attribute').Attribute} Attribute */
|
|
2
|
+
const { AttributeType } = require('../attribute');
|
|
3
|
+
const { LanguageMeta } = require("./language");
|
|
4
|
+
|
|
5
|
+
class Swift extends LanguageMeta {
|
|
6
|
+
getType(attribute) {
|
|
7
|
+
let type = "";
|
|
8
|
+
switch (attribute.type) {
|
|
9
|
+
case AttributeType.STRING:
|
|
10
|
+
case AttributeType.EMAIL:
|
|
11
|
+
case AttributeType.DATETIME:
|
|
12
|
+
type = "String";
|
|
13
|
+
if (attribute.format === AttributeType.ENUM) {
|
|
14
|
+
type = LanguageMeta.toPascalCase(attribute.key);
|
|
15
|
+
}
|
|
16
|
+
break;
|
|
17
|
+
case AttributeType.INTEGER:
|
|
18
|
+
type = "Int";
|
|
19
|
+
break;
|
|
20
|
+
case AttributeType.FLOAT:
|
|
21
|
+
type = "Double";
|
|
22
|
+
break;
|
|
23
|
+
case AttributeType.BOOLEAN:
|
|
24
|
+
type = "Bool";
|
|
25
|
+
break;
|
|
26
|
+
case AttributeType.RELATIONSHIP:
|
|
27
|
+
type = LanguageMeta.toPascalCase(attribute.relatedCollection);
|
|
28
|
+
if ((attribute.relationType === 'oneToMany' && attribute.side === 'parent') || (attribute.relationType === 'manyToOne' && attribute.side === 'child') || attribute.relationType === 'manyToMany') {
|
|
29
|
+
type = `[${type}]`;
|
|
30
|
+
}
|
|
31
|
+
break;
|
|
32
|
+
default:
|
|
33
|
+
throw new Error(`Unknown attribute type: ${attribute.type}`);
|
|
34
|
+
}
|
|
35
|
+
if (attribute.array) {
|
|
36
|
+
type = "[" + type + "]";
|
|
37
|
+
}
|
|
38
|
+
if (!attribute.required) {
|
|
39
|
+
type += "?";
|
|
40
|
+
}
|
|
41
|
+
return type;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
getTemplate() {
|
|
45
|
+
return `import Foundation
|
|
46
|
+
|
|
47
|
+
<% for (const attribute of collection.attributes) { -%>
|
|
48
|
+
<% if (attribute.format === 'enum') { -%>
|
|
49
|
+
public enum <%- toPascalCase(attribute.key) %>: String, Codable, CaseIterable {
|
|
50
|
+
<% for (const [index, element] of Object.entries(attribute.elements)) { -%>
|
|
51
|
+
case <%- element %> = "<%- element %>"
|
|
52
|
+
<% } -%>
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
<% } -%>
|
|
56
|
+
<% } -%>
|
|
57
|
+
public class <%- toPascalCase(collection.name) %>: Codable {
|
|
58
|
+
<% for (const attribute of collection.attributes) { -%>
|
|
59
|
+
public let <%- toCamelCase(attribute.key) %>: <%- getType(attribute) %>
|
|
60
|
+
<% } %>
|
|
61
|
+
enum CodingKeys: String, CodingKey {
|
|
62
|
+
<% for (const attribute of collection.attributes) { -%>
|
|
63
|
+
case <%- toCamelCase(attribute.key) %> = "<%- attribute.key %>"
|
|
64
|
+
<% } -%>
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
init(
|
|
68
|
+
<% for (const attribute of collection.attributes) { -%>
|
|
69
|
+
<%- toCamelCase(attribute.key) %>: <%- getType(attribute) %><% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
|
|
70
|
+
<% } -%>
|
|
71
|
+
) {
|
|
72
|
+
<% for (const attribute of collection.attributes) { -%>
|
|
73
|
+
self.<%- toCamelCase(attribute.key) %> = <%- toCamelCase(attribute.key) %>
|
|
74
|
+
<% } -%>
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
public required init(from decoder: Decoder) throws {
|
|
78
|
+
let container = try decoder.container(keyedBy: CodingKeys.self)
|
|
79
|
+
|
|
80
|
+
<% for (const attribute of collection.attributes) { -%>
|
|
81
|
+
<% if (attribute.required) { -%>
|
|
82
|
+
self.<%- toCamelCase(attribute.key) %> = try container.decode(<%- getType(attribute).replace('?', '') %>.self, forKey: .<%- toCamelCase(attribute.key) %>)
|
|
83
|
+
<% } else { -%>
|
|
84
|
+
self.<%- toCamelCase(attribute.key) %> = try container.decodeIfPresent(<%- getType(attribute).replace('?', '') %>.self, forKey: .<%- toCamelCase(attribute.key) %>)
|
|
85
|
+
<% } -%>
|
|
86
|
+
<% } -%>
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
public func encode(to encoder: Encoder) throws {
|
|
90
|
+
var container = encoder.container(keyedBy: CodingKeys.self)
|
|
91
|
+
|
|
92
|
+
<% for (const attribute of collection.attributes) { -%>
|
|
93
|
+
<% if (attribute.required) { -%>
|
|
94
|
+
try container.encode(<%- toCamelCase(attribute.key) %>, forKey: .<%- toCamelCase(attribute.key) %>)
|
|
95
|
+
<% } else { -%>
|
|
96
|
+
try container.encodeIfPresent(<%- toCamelCase(attribute.key) %>, forKey: .<%- toCamelCase(attribute.key) %>)
|
|
97
|
+
<% } -%>
|
|
98
|
+
<% } -%>
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
public func toMap() -> [String: Any] {
|
|
102
|
+
return [
|
|
103
|
+
<% for (const attribute of collection.attributes) { -%>
|
|
104
|
+
<% if (attribute.type === 'relationship') { -%>
|
|
105
|
+
"<%- attribute.key %>": <%- toCamelCase(attribute.key) %> as Any<% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
|
|
106
|
+
<% } else if (attribute.array && attribute.type !== 'string' && attribute.type !== 'integer' && attribute.type !== 'float' && attribute.type !== 'boolean') { -%>
|
|
107
|
+
"<%- attribute.key %>": <%- toCamelCase(attribute.key) %>?.map { $0.toMap() } as Any<% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
|
|
108
|
+
<% } else { -%>
|
|
109
|
+
"<%- attribute.key %>": <%- toCamelCase(attribute.key) %> as Any<% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
|
|
110
|
+
<% } -%>
|
|
111
|
+
<% } -%>
|
|
112
|
+
]
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
public static func from(map: [String: Any]) -> <%- toPascalCase(collection.name) %> {
|
|
116
|
+
return <%- toPascalCase(collection.name) %>(
|
|
117
|
+
<% for (const attribute of collection.attributes) { -%>
|
|
118
|
+
<% if (attribute.type === 'relationship') { -%>
|
|
119
|
+
<%- toCamelCase(attribute.key) %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> <%- toPascalCase(attribute.relatedCollection) %><% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
|
|
120
|
+
<% } else if (attribute.array) { -%>
|
|
121
|
+
<% if (attribute.type === 'string') { -%>
|
|
122
|
+
<%- toCamelCase(attribute.key) %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> [String]<% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
|
|
123
|
+
<% } else if (attribute.type === 'integer') { -%>
|
|
124
|
+
<%- toCamelCase(attribute.key) %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> [Int]<% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
|
|
125
|
+
<% } else if (attribute.type === 'float') { -%>
|
|
126
|
+
<%- toCamelCase(attribute.key) %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> [Double]<% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
|
|
127
|
+
<% } else if (attribute.type === 'boolean') { -%>
|
|
128
|
+
<%- toCamelCase(attribute.key) %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> [Bool]<% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
|
|
129
|
+
<% } else { -%>
|
|
130
|
+
<%- toCamelCase(attribute.key) %>: (map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> [[String: Any]])<% if (!attribute.required) { %>?<% } %>.map { <%- toPascalCase(attribute.type) %>.from(map: $0) }<% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
|
|
131
|
+
<% } -%>
|
|
132
|
+
<% } else { -%>
|
|
133
|
+
<% if (attribute.type === 'string' || attribute.type === 'email' || attribute.type === 'datetime' || attribute.type === 'enum') { -%>
|
|
134
|
+
<%- toCamelCase(attribute.key) %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> String<% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
|
|
135
|
+
<% } else if (attribute.type === 'integer') { -%>
|
|
136
|
+
<%- toCamelCase(attribute.key) %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> Int<% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
|
|
137
|
+
<% } else if (attribute.type === 'float') { -%>
|
|
138
|
+
<%- toCamelCase(attribute.key) %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> Double<% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
|
|
139
|
+
<% } else if (attribute.type === 'boolean') { -%>
|
|
140
|
+
<%- toCamelCase(attribute.key) %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> Bool<% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
|
|
141
|
+
<% } else { -%>
|
|
142
|
+
<%- toCamelCase(attribute.key) %>: <%- toPascalCase(attribute.type) %>.from(map: map["<%- attribute.key %>"] as! [String: Any])<% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
|
|
143
|
+
<% } -%>
|
|
144
|
+
<% } -%>
|
|
145
|
+
<% } -%>
|
|
146
|
+
)
|
|
147
|
+
}
|
|
148
|
+
}`;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
getFileName(collection) {
|
|
152
|
+
return LanguageMeta.toPascalCase(collection.name) + ".swift";
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
module.exports = { Swift };
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/** @typedef {import('../attribute').Attribute} Attribute */
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
const path = require("path");
|
|
4
|
+
|
|
5
|
+
const { AttributeType } = require('../attribute');
|
|
6
|
+
const { LanguageMeta } = require("./language");
|
|
7
|
+
|
|
8
|
+
class TypeScript extends LanguageMeta {
|
|
9
|
+
getType(attribute) {
|
|
10
|
+
let type = ""
|
|
11
|
+
switch (attribute.type) {
|
|
12
|
+
case AttributeType.STRING:
|
|
13
|
+
case AttributeType.EMAIL:
|
|
14
|
+
case AttributeType.DATETIME:
|
|
15
|
+
case AttributeType.IP:
|
|
16
|
+
case AttributeType.URL:
|
|
17
|
+
type = "string";
|
|
18
|
+
if (attribute.format === AttributeType.ENUM) {
|
|
19
|
+
type = LanguageMeta.toPascalCase(attribute.key);
|
|
20
|
+
}
|
|
21
|
+
break;
|
|
22
|
+
case AttributeType.INTEGER:
|
|
23
|
+
type = "number";
|
|
24
|
+
break;
|
|
25
|
+
case AttributeType.FLOAT:
|
|
26
|
+
type = "number";
|
|
27
|
+
break;
|
|
28
|
+
case AttributeType.BOOLEAN:
|
|
29
|
+
type = "boolean";
|
|
30
|
+
break;
|
|
31
|
+
case AttributeType.RELATIONSHIP:
|
|
32
|
+
type = LanguageMeta.toPascalCase(attribute.relatedCollection);
|
|
33
|
+
if ((attribute.relationType === 'oneToMany' && attribute.side === 'parent') || (attribute.relationType === 'manyToOne' && attribute.side === 'child') || attribute.relationType === 'manyToMany') {
|
|
34
|
+
type = `${type}[]`;
|
|
35
|
+
}
|
|
36
|
+
break;
|
|
37
|
+
default:
|
|
38
|
+
throw new Error(`Unknown attribute type: ${attribute.type}`);
|
|
39
|
+
}
|
|
40
|
+
if (attribute.array) {
|
|
41
|
+
type += "[]";
|
|
42
|
+
}
|
|
43
|
+
if (!attribute.required) {
|
|
44
|
+
type += " | null";
|
|
45
|
+
}
|
|
46
|
+
return type;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
isSingleFile() {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
_getAppwriteDependency() {
|
|
54
|
+
if (fs.existsSync(path.resolve(process.cwd(), 'package.json'))) {
|
|
55
|
+
const packageJsonRaw = fs.readFileSync(path.resolve(process.cwd(), 'package.json'));
|
|
56
|
+
const packageJson = JSON.parse(packageJsonRaw.toString('utf-8'));
|
|
57
|
+
return packageJson.dependencies['node-appwrite'] ? 'node-appwrite' : 'appwrite';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (fs.existsSync(path.resolve(process.cwd(), 'deno.json'))) {
|
|
61
|
+
return "https://deno.land/x/appwrite/mod.ts";
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return "appwrite";
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
getTemplate() {
|
|
68
|
+
return `import { Models } from '${this._getAppwriteDependency()}';
|
|
69
|
+
|
|
70
|
+
<% for (const collection of collections) { -%>
|
|
71
|
+
<% for (const attribute of collection.attributes) { -%>
|
|
72
|
+
<% if (attribute.format === 'enum') { -%>
|
|
73
|
+
export enum <%- toPascalCase(attribute.key) %> {
|
|
74
|
+
<% for (const [index, element] of Object.entries(attribute.elements)) { -%>
|
|
75
|
+
<%- element.toUpperCase() %> = "<%- element %>",
|
|
76
|
+
<% } -%>
|
|
77
|
+
}
|
|
78
|
+
<% } -%>
|
|
79
|
+
<% } -%>
|
|
80
|
+
<% } -%>
|
|
81
|
+
<% for (const collection of collections) { %>
|
|
82
|
+
export type <%- toPascalCase(collection.name) %> = Models.Document & {
|
|
83
|
+
<% for (const attribute of collection.attributes) { -%>
|
|
84
|
+
<%- toCamelCase(attribute.key) %>: <%- getType(attribute) %>;
|
|
85
|
+
<% } -%>
|
|
86
|
+
}
|
|
87
|
+
<% } %>`;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
getFileName(_) {
|
|
91
|
+
return "appwrite.d.ts";
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
module.exports = { TypeScript };
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "appwrite-cli",
|
|
3
3
|
"homepage": "https://appwrite.io/support",
|
|
4
4
|
"description": "Appwrite is an open-source self-hosted backend server that abstract and simplify complex and repetitive development tasks behind a very simple REST API",
|
|
5
|
-
"version": "
|
|
5
|
+
"version": "8.0.0",
|
|
6
6
|
"license": "BSD-3-Clause",
|
|
7
7
|
"main": "index.js",
|
|
8
8
|
"bin": {
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"undici": "^5.28.2",
|
|
26
|
+
"ejs": "^3.1.9",
|
|
26
27
|
"chalk": "4.1.2",
|
|
27
28
|
"cli-progress": "^3.12.0",
|
|
28
29
|
"cli-table3": "^0.6.2",
|
package/scoop/appwrite.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://raw.githubusercontent.com/ScoopInstaller/Scoop/master/schema.json",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.0.0",
|
|
4
4
|
"description": "The Appwrite CLI is a command-line application that allows you to interact with Appwrite and perform server-side tasks using your terminal.",
|
|
5
5
|
"homepage": "https://github.com/appwrite/sdk-for-cli",
|
|
6
6
|
"license": "BSD-3-Clause",
|
|
7
7
|
"architecture": {
|
|
8
8
|
"64bit": {
|
|
9
|
-
"url": "https://github.com/appwrite/sdk-for-cli/releases/download/
|
|
9
|
+
"url": "https://github.com/appwrite/sdk-for-cli/releases/download/8.0.0/appwrite-cli-win-x64.exe",
|
|
10
10
|
"bin": [
|
|
11
11
|
[
|
|
12
12
|
"appwrite-cli-win-x64.exe",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
]
|
|
16
16
|
},
|
|
17
17
|
"arm64": {
|
|
18
|
-
"url": "https://github.com/appwrite/sdk-for-cli/releases/download/
|
|
18
|
+
"url": "https://github.com/appwrite/sdk-for-cli/releases/download/8.0.0/appwrite-cli-win-arm64.exe",
|
|
19
19
|
"bin": [
|
|
20
20
|
[
|
|
21
21
|
"appwrite-cli-win-arm64.exe",
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const pathLib = require('path');
|
|
3
|
-
const tar = require("tar");
|
|
4
|
-
const ignore = require("ignore");
|
|
5
|
-
const { promisify } = require('util');
|
|
6
|
-
const libClient = require('../client.js');
|
|
7
|
-
const { getAllFiles, showConsoleLink } = require('../utils.js');
|
|
8
|
-
const { Command } = require('commander');
|
|
9
|
-
const { sdkForProject, sdkForConsole } = require('../sdks')
|
|
10
|
-
const { parse, actionRunner, parseInteger, parseBool, commandDescriptions, success, log } = require('../parser')
|
|
11
|
-
const { localConfig, globalConfig } = require("../config");
|
|
12
|
-
const { File } = require('undici');
|
|
13
|
-
const { ReadableStream } = require('stream/web');
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* @param {fs.ReadStream} readStream
|
|
17
|
-
* @returns {ReadableStream}
|
|
18
|
-
*/
|
|
19
|
-
function convertReadStreamToReadableStream(readStream) {
|
|
20
|
-
return new ReadableStream({
|
|
21
|
-
start(controller) {
|
|
22
|
-
readStream.on("data", (chunk) => {
|
|
23
|
-
controller.enqueue(chunk);
|
|
24
|
-
});
|
|
25
|
-
readStream.on("end", () => {
|
|
26
|
-
controller.close();
|
|
27
|
-
});
|
|
28
|
-
readStream.on("error", (err) => {
|
|
29
|
-
controller.error(err);
|
|
30
|
-
});
|
|
31
|
-
},
|
|
32
|
-
cancel() {
|
|
33
|
-
readStream.destroy();
|
|
34
|
-
},
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const assistant = new Command("assistant").description(commandDescriptions['assistant'] ?? '').configureHelp({
|
|
39
|
-
helpWidth: process.stdout.columns || 80
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* @typedef {Object} AssistantChatRequestParams
|
|
44
|
-
* @property {string} prompt Prompt. A string containing questions asked to the AI assistant.
|
|
45
|
-
* @property {boolean} overrideForCli
|
|
46
|
-
* @property {boolean} parseOutput
|
|
47
|
-
* @property {libClient | undefined} sdk
|
|
48
|
-
*/
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* @param {AssistantChatRequestParams} params
|
|
52
|
-
*/
|
|
53
|
-
const assistantChat = async ({prompt,parseOutput = true, overrideForCli = false, sdk = undefined}) => {
|
|
54
|
-
let client = !sdk ? await sdkForProject() :
|
|
55
|
-
sdk;
|
|
56
|
-
let apiPath = '/console/assistant';
|
|
57
|
-
let payload = {};
|
|
58
|
-
if (typeof prompt !== 'undefined') {
|
|
59
|
-
payload['prompt'] = prompt;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
let response = undefined;
|
|
63
|
-
|
|
64
|
-
response = await client.call('post', apiPath, {
|
|
65
|
-
'content-type': 'application/json',
|
|
66
|
-
}, payload);
|
|
67
|
-
|
|
68
|
-
if (parseOutput) {
|
|
69
|
-
parse(response)
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return response;
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
assistant
|
|
77
|
-
.command(`chat`)
|
|
78
|
-
.description(`Send a prompt to the AI assistant and receive a response. This endpoint allows you to interact with Appwrite's AI assistant by sending questions or prompts and receiving helpful responses in real-time through a server-sent events stream. `)
|
|
79
|
-
.requiredOption(`--prompt <prompt>`, `Prompt. A string containing questions asked to the AI assistant.`)
|
|
80
|
-
.action(actionRunner(assistantChat))
|
|
81
|
-
|
|
82
|
-
module.exports = {
|
|
83
|
-
assistant,
|
|
84
|
-
assistantChat
|
|
85
|
-
};
|