From 8dbee050081c6600f63eb0edaca82d753c750c7a Mon Sep 17 00:00:00 2001
From: Partik SIngh
Date: Sun, 27 Aug 2023 12:51:17 +0530
Subject: [PATCH 1/6] Some changes
Signed-off-by: Partik SIngh
---
.../Linode/compute/linode-kubernetes.js | 242 +++++++++---------
.../Linode/database/linode-RDBMS.js | 97 +++++++
.../Linode/database/linode-noSql.js | 103 --------
.../Linode/storage/linode-storageBucket.js | 186 +++++++-------
generator/node-cloud.yml | 14 +-
generator/package.json | 1 +
generator/transformers/linode/transformer.ts | 6 -
7 files changed, 312 insertions(+), 337 deletions(-)
create mode 100644 generator/generatedClasses/Linode/database/linode-RDBMS.js
delete mode 100644 generator/generatedClasses/Linode/database/linode-noSql.js
diff --git a/generator/generatedClasses/Linode/compute/linode-kubernetes.js b/generator/generatedClasses/Linode/compute/linode-kubernetes.js
index 0656b2c6..39be1982 100644
--- a/generator/generatedClasses/Linode/compute/linode-kubernetes.js
+++ b/generator/generatedClasses/Linode/compute/linode-kubernetes.js
@@ -1,130 +1,122 @@
/*This is an auto generated class, please do not change.*/
/**
- * Class to create a KubernetesLinodeClass object
- * @category Linode
- */
+ * Class to create a KubernetesLinodeClass object
+ * @category Linode
+ */
class Linode_Kubernetes {
- /**
- *
- * @param {module} do Linode SDK
- * @param {object} options SDK options
- */
- constructor(linodeSdk, linodeToken) {
- this._linode = linodeSdk;
- this._linodeToken = linodeToken;
- this._linode.setToken(this._linodeToken);
- }
- /**
- * Trigers the getKubernetesClusters function of KubernetesLinodeClass
- * @param {Params} params - Data required for getKubernetesClusters
- * @param {Filter} filters - Data required for getKubernetesClusters
- * @returns {Promise}
- */
- getAllClusters(params = undefined, filters = undefined) {
- return new Promise((resolve, reject) => {
- this._linode
- .getKubernetesClusters(params, filters)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the createKubernetesCluster function of KubernetesLinodeClass
- * @param {CreateKubeClusterPayload} data - Data required for createKubernetesCluster
- * @returns {Promise}
- */
- create(data) {
- return new Promise((resolve, reject) => {
- this._linode
- .createKubernetesCluster(data)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the deleteKubernetesCluster function of KubernetesLinodeClass
- * @param {NumberKeyword} clusterID - Data required for deleteKubernetesCluster
- * @returns {Promise}
- */
- delete(clusterID) {
- return new Promise((resolve, reject) => {
- this._linode
- .deleteKubernetesCluster(clusterID)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the getNodePools function of KubernetesLinodeClass
- * @param {NumberKeyword} clusterID - Data required for getNodePools
- * @param {Params} params - Data required for getNodePools
- * @param {Filter} filters - Data required for getNodePools
- * @returns {Promise}
- */
- getNodePools(clusterID, params = undefined, filters = undefined) {
- return new Promise((resolve, reject) => {
- this._linode
- .getNodePools(clusterID, params, filters)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the getNodePool function of KubernetesLinodeClass
- * @param {NumberKeyword} clusterID - Data required for getNodePool
- * @param {NumberKeyword} nodePoolID - Data required for getNodePool
- * @returns {Promise}
- */
- getNodePool(clusterID, nodePoolID) {
- return new Promise((resolve, reject) => {
- this._linode
- .getNodePool(clusterID, nodePoolID)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the createNodePool function of KubernetesLinodeClass
- * @param {NumberKeyword} clusterID - Data required for createNodePool
- * @param {CreateNodePoolData} data - Data required for createNodePool
- * @returns {Promise}
- */
- createNodePool(clusterID, data) {
- return new Promise((resolve, reject) => {
- this._linode
- .createNodePool(clusterID, data)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the updateNodePool function of KubernetesLinodeClass
- * @param {NumberKeyword} clusterID - Data required for updateNodePool
- * @param {NumberKeyword} nodePoolID - Data required for updateNodePool
- * @param {Partial} data - Data required for updateNodePool
- * @returns {Promise}
- */
- updateNodePool(clusterID, nodePoolID, data) {
- return new Promise((resolve, reject) => {
- this._linode
- .updateNodePool(clusterID, nodePoolID, data)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the deleteNodePool function of KubernetesLinodeClass
- * @param {NumberKeyword} clusterID - Data required for deleteNodePool
- * @param {NumberKeyword} nodePoolID - Data required for deleteNodePool
- * @returns {Promise}
- */
- deleteNodePool(clusterID, nodePoolID) {
- return new Promise((resolve, reject) => {
- this._linode
- .deleteNodePool(clusterID, nodePoolID)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
+ /**
+ *
+ * @param {module} do Linode SDK
+ * @param {object} options SDK options
+ */
+ constructor(linodeSdk, linodeToken) {
+ this._linode = linodeSdk;
+ this._linodeToken = linodeToken;
+ this._linode.setToken(this._linodeToken);
+ }
+ /**
+ * Trigers the getKubernetesClusters function of KubernetesLinodeClass
+ * @param {Params} params - Data required for getKubernetesClusters
+ * @param {Filter} filters - Data required for getKubernetesClusters
+ * @returns {Promise}
+ */
+ getAllClusters(params = undefined, filters = undefined) {
+ return new Promise((resolve, reject) => {
+ this._linode.getKubernetesClusters(params, filters)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the createKubernetesCluster function of KubernetesLinodeClass
+ * @param {CreateKubeClusterPayload} data - Data required for createKubernetesCluster
+ * @returns {Promise}
+ */
+ create(data) {
+ return new Promise((resolve, reject) => {
+ this._linode.createKubernetesCluster(data)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the deleteKubernetesCluster function of KubernetesLinodeClass
+ * @param {NumberKeyword} clusterID - Data required for deleteKubernetesCluster
+ * @returns {Promise}
+ */
+ delete(clusterID) {
+ return new Promise((resolve, reject) => {
+ this._linode.deleteKubernetesCluster(clusterID)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the getNodePools function of KubernetesLinodeClass
+ * @param {NumberKeyword} clusterID - Data required for getNodePools
+ * @param {Params} params - Data required for getNodePools
+ * @param {Filter} filters - Data required for getNodePools
+ * @returns {Promise}
+ */
+ getNodePools(clusterID, params = undefined, filters = undefined) {
+ return new Promise((resolve, reject) => {
+ this._linode.getNodePools(clusterID, params, filters)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the getNodePool function of KubernetesLinodeClass
+ * @param {NumberKeyword} clusterID - Data required for getNodePool
+ * @param {NumberKeyword} nodePoolID - Data required for getNodePool
+ * @returns {Promise}
+ */
+ getNodePool(clusterID, nodePoolID) {
+ return new Promise((resolve, reject) => {
+ this._linode.getNodePool(clusterID, nodePoolID)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the createNodePool function of KubernetesLinodeClass
+ * @param {NumberKeyword} clusterID - Data required for createNodePool
+ * @param {CreateNodePoolData} data - Data required for createNodePool
+ * @returns {Promise}
+ */
+ createNodePool(clusterID, data) {
+ return new Promise((resolve, reject) => {
+ this._linode.createNodePool(clusterID, data)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the updateNodePool function of KubernetesLinodeClass
+ * @param {NumberKeyword} clusterID - Data required for updateNodePool
+ * @param {NumberKeyword} nodePoolID - Data required for updateNodePool
+ * @param {Partial} data - Data required for updateNodePool
+ * @returns {Promise}
+ */
+ updateNodePool(clusterID, nodePoolID, data) {
+ return new Promise((resolve, reject) => {
+ this._linode.updateNodePool(clusterID, nodePoolID, data)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the deleteNodePool function of KubernetesLinodeClass
+ * @param {NumberKeyword} clusterID - Data required for deleteNodePool
+ * @param {NumberKeyword} nodePoolID - Data required for deleteNodePool
+ * @returns {Promise}
+ */
+ deleteNodePool(clusterID, nodePoolID) {
+ return new Promise((resolve, reject) => {
+ this._linode.deleteNodePool(clusterID, nodePoolID)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
}
module.exports = Linode_Kubernetes;
diff --git a/generator/generatedClasses/Linode/database/linode-RDBMS.js b/generator/generatedClasses/Linode/database/linode-RDBMS.js
new file mode 100644
index 00000000..1e5e80d6
--- /dev/null
+++ b/generator/generatedClasses/Linode/database/linode-RDBMS.js
@@ -0,0 +1,97 @@
+/*This is an auto generated class, please do not change.*/
+/**
+ * Class to create a RDBMSLinodeClass object
+ * @category Linode
+ */
+class Linode_RDBMS {
+ /**
+ *
+ * @param {module} do Linode SDK
+ * @param {object} options SDK options
+ */
+ constructor(linodeSdk, linodeToken) {
+ this._linode = linodeSdk;
+ this._linodeToken = linodeToken;
+ this._linode.setToken(this._linodeToken);
+ }
+ /**
+ * Trigers the getDatabases function of RDBMSLinodeClass
+ * @param {Params} params - Data required for getDatabases
+ * @param {Filter} filter - Data required for getDatabases
+ * @returns {Promise}
+ */
+ getDatabases(params = undefined, filter = undefined) {
+ return new Promise((resolve, reject) => {
+ this._linode.getDatabases(params, filter)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the getDatabaseEngines function of RDBMSLinodeClass
+ * @param {Params} params - Data required for getDatabaseEngines
+ * @param {Filter} filter - Data required for getDatabaseEngines
+ * @returns {Promise}
+ */
+ getDatabaseEngines(params = undefined, filter = undefined) {
+ return new Promise((resolve, reject) => {
+ this._linode.getDatabaseEngines(params, filter)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the createDatabase function of RDBMSLinodeClass
+ * @param {UnionType} engine - Data required for createDatabase
+ * @param {CreateDatabasePayload} data - Data required for createDatabase
+ * @returns {Promise}
+ */
+ createDatabase(engine, data) {
+ return new Promise((resolve, reject) => {
+ this._linode.createDatabase(engine, data)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the getEngineDatabase function of RDBMSLinodeClass
+ * @param {Engine} engine - Data required for getEngineDatabase
+ * @param {NumberKeyword} databaseID - Data required for getEngineDatabase
+ * @returns {Promise}
+ */
+ getEngineDatabase(engine, databaseID) {
+ return new Promise((resolve, reject) => {
+ this._linode.getEngineDatabase(engine, databaseID)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the updateDatabase function of RDBMSLinodeClass
+ * @param {Engine} engine - Data required for updateDatabase
+ * @param {NumberKeyword} databaseID - Data required for updateDatabase
+ * @param {UpdateDatabasePayload} data - Data required for updateDatabase
+ * @returns {Promise}
+ */
+ updateDatabase(engine, databaseID, data) {
+ return new Promise((resolve, reject) => {
+ this._linode.updateDatabase(engine, databaseID, data)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the deleteDatabase function of RDBMSLinodeClass
+ * @param {Engine} engine - Data required for deleteDatabase
+ * @param {NumberKeyword} databaseID - Data required for deleteDatabase
+ * @returns {Promise}
+ */
+ deleteDatabase(engine, databaseID) {
+ return new Promise((resolve, reject) => {
+ this._linode.deleteDatabase(engine, databaseID)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+}
+module.exports = Linode_RDBMS;
diff --git a/generator/generatedClasses/Linode/database/linode-noSql.js b/generator/generatedClasses/Linode/database/linode-noSql.js
deleted file mode 100644
index 666420ce..00000000
--- a/generator/generatedClasses/Linode/database/linode-noSql.js
+++ /dev/null
@@ -1,103 +0,0 @@
-/*This is an auto generated class, please do not change.*/
-/**
- * Class to create a NoSqlLinodeClass object
- * @category Linode
- */
-class Linode_NoSql {
- /**
- *
- * @param {module} do Linode SDK
- * @param {object} options SDK options
- */
- constructor(linodeSdk, linodeToken) {
- this._linode = linodeSdk;
- this._linodeToken = linodeToken;
- this._linode.setToken(this._linodeToken);
- }
- /**
- * Trigers the getDatabases function of NoSqlLinodeClass
- * @param {Params} params - Data required for getDatabases
- * @param {Filter} filter - Data required for getDatabases
- * @returns {Promise}
- */
- getDatabases(params = undefined, filter = undefined) {
- return new Promise((resolve, reject) => {
- this._linode
- .getDatabases(params, filter)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the getDatabaseEngines function of NoSqlLinodeClass
- * @param {Params} params - Data required for getDatabaseEngines
- * @param {Filter} filter - Data required for getDatabaseEngines
- * @returns {Promise}
- */
- getDatabaseEngines(params = undefined, filter = undefined) {
- return new Promise((resolve, reject) => {
- this._linode
- .getDatabaseEngines(params, filter)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the createDatabase function of NoSqlLinodeClass
- * @param {UnionType} engine - Data required for createDatabase
- * @param {CreateDatabasePayload} data - Data required for createDatabase
- * @returns {Promise}
- */
- createDatabase(engine, data) {
- return new Promise((resolve, reject) => {
- this._linode
- .createDatabase(engine, data)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the getEngineDatabase function of NoSqlLinodeClass
- * @param {Engine} engine - Data required for getEngineDatabase
- * @param {NumberKeyword} databaseID - Data required for getEngineDatabase
- * @returns {Promise}
- */
- getEngineDatabase(engine, databaseID) {
- return new Promise((resolve, reject) => {
- this._linode
- .getEngineDatabase(engine, databaseID)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the updateDatabase function of NoSqlLinodeClass
- * @param {Engine} engine - Data required for updateDatabase
- * @param {NumberKeyword} databaseID - Data required for updateDatabase
- * @param {UpdateDatabasePayload} data - Data required for updateDatabase
- * @returns {Promise}
- */
- updateDatabase(engine, databaseID, data) {
- return new Promise((resolve, reject) => {
- this._linode
- .updateDatabase(engine, databaseID, data)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the deleteDatabase function of NoSqlLinodeClass
- * @param {Engine} engine - Data required for deleteDatabase
- * @param {NumberKeyword} databaseID - Data required for deleteDatabase
- * @returns {Promise}
- */
- deleteDatabase(engine, databaseID) {
- return new Promise((resolve, reject) => {
- this._linode
- .deleteDatabase(engine, databaseID)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
-}
-module.exports = Linode_NoSql;
diff --git a/generator/generatedClasses/Linode/storage/linode-storageBucket.js b/generator/generatedClasses/Linode/storage/linode-storageBucket.js
index 5b3b0741..a2990dd9 100644
--- a/generator/generatedClasses/Linode/storage/linode-storageBucket.js
+++ b/generator/generatedClasses/Linode/storage/linode-storageBucket.js
@@ -1,101 +1,95 @@
/*This is an auto generated class, please do not change.*/
/**
- * Class to create a StorageBucketLinodeClass object
- * @category Linode
- */
+ * Class to create a StorageBucketLinodeClass object
+ * @category Linode
+ */
class Linode_StorageBucket {
- /**
- *
- * @param {module} do Linode SDK
- * @param {object} options SDK options
- */
- constructor(linodeSdk, linodeToken) {
- this._linode = linodeSdk;
- this._linodeToken = linodeToken;
- this._linode.setToken(this._linodeToken);
- }
- /**
- * Trigers the getBucket function of StorageBucketLinodeClass
- * @param {StringKeyword} clusterId - Data required for getBucket
- * @param {StringKeyword} bucketName - Data required for getBucket
- * @returns {Promise}
- */
- get(clusterId, bucketName) {
- return new Promise((resolve, reject) => {
- this._linode
- .getBucket(clusterId, bucketName)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the getBuckets function of StorageBucketLinodeClass
- * @param {Params} params - Data required for getBuckets
- * @param {Filter} filters - Data required for getBuckets
- * @returns {Promise}
- */
- list(params = undefined, filters = undefined) {
- return new Promise((resolve, reject) => {
- this._linode
- .getBuckets(params, filters)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the createBucket function of StorageBucketLinodeClass
- * @param {ObjectStorageBucketRequestPayload} data - Data required for createBucket
- * @returns {Promise}
- */
- create(data) {
- return new Promise((resolve, reject) => {
- this._linode
- .createBucket(data)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the deleteBucket function of StorageBucketLinodeClass
- * @param {ObjectStorageDeleteBucketRequestPayload} {cluster,label} - Data required for deleteBucket
- * @returns {Promise}
- */
- delete({ cluster, label }) {
- return new Promise((resolve, reject) => {
- this._linode
- .deleteBucket({ cluster, label })
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the getBucketAccess function of StorageBucketLinodeClass
- * @param {StringKeyword} clusterId - Data required for getBucketAccess
- * @param {StringKeyword} bucketName - Data required for getBucketAccess
- * @returns {Promise}
- */
- getBucketAccess(clusterId, bucketName) {
- return new Promise((resolve, reject) => {
- this._linode
- .getBucketAccess(clusterId, bucketName)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the updateBucketAccess function of StorageBucketLinodeClass
- * @param {StringKeyword} clusterId - Data required for updateBucketAccess
- * @param {StringKeyword} bucketName - Data required for updateBucketAccess
- * @param {ObjectStorageBucketAccessRequest} data - Data required for updateBucketAccess
- * @returns {Promise}
- */
- updateBucketAccess(clusterId, bucketName, data) {
- return new Promise((resolve, reject) => {
- this._linode
- .updateBucketAccess(clusterId, bucketName, data)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
+ /**
+ *
+ * @param {module} do Linode SDK
+ * @param {object} options SDK options
+ */
+ constructor(linodeSdk, linodeToken) {
+ this._linode = linodeSdk;
+ this._linodeToken = linodeToken;
+ this._linode.setToken(this._linodeToken);
+ }
+ /**
+ * Trigers the getBucket function of StorageBucketLinodeClass
+ * @param {StringKeyword} clusterId - Data required for getBucket
+ * @param {StringKeyword} bucketName - Data required for getBucket
+ * @returns {Promise}
+ */
+ get(clusterId, bucketName) {
+ return new Promise((resolve, reject) => {
+ this._linode.getBucket(clusterId, bucketName)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the getBuckets function of StorageBucketLinodeClass
+ * @param {Params} params - Data required for getBuckets
+ * @param {Filter} filters - Data required for getBuckets
+ * @returns {Promise}
+ */
+ list(params = undefined, filters = undefined) {
+ return new Promise((resolve, reject) => {
+ this._linode.getBuckets(params, filters)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the createBucket function of StorageBucketLinodeClass
+ * @param {ObjectStorageBucketRequestPayload} data - Data required for createBucket
+ * @returns {Promise}
+ */
+ create(data) {
+ return new Promise((resolve, reject) => {
+ this._linode.createBucket(data)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the deleteBucket function of StorageBucketLinodeClass
+ * @param {ObjectStorageDeleteBucketRequestPayload} {cluster,label} - Data required for deleteBucket
+ * @returns {Promise}
+ */
+ delete({ cluster, label }) {
+ return new Promise((resolve, reject) => {
+ this._linode.deleteBucket({ cluster, label })
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the getBucketAccess function of StorageBucketLinodeClass
+ * @param {StringKeyword} clusterId - Data required for getBucketAccess
+ * @param {StringKeyword} bucketName - Data required for getBucketAccess
+ * @returns {Promise}
+ */
+ getBucketAccess(clusterId, bucketName) {
+ return new Promise((resolve, reject) => {
+ this._linode.getBucketAccess(clusterId, bucketName)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the updateBucketAccess function of StorageBucketLinodeClass
+ * @param {StringKeyword} clusterId - Data required for updateBucketAccess
+ * @param {StringKeyword} bucketName - Data required for updateBucketAccess
+ * @param {ObjectStorageBucketAccessRequest} data - Data required for updateBucketAccess
+ * @returns {Promise}
+ */
+ updateBucketAccess(clusterId, bucketName, data) {
+ return new Promise((resolve, reject) => {
+ this._linode.updateBucketAccess(clusterId, bucketName, data)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
}
module.exports = Linode_StorageBucket;
diff --git a/generator/node-cloud.yml b/generator/node-cloud.yml
index 59e812c2..1dccca6b 100644
--- a/generator/node-cloud.yml
+++ b/generator/node-cloud.yml
@@ -265,6 +265,13 @@ RDBMS:
startDBSystem: mysql startDbSystem DbSystemClient
stopDBSystem: mysql stopDbSystem DbSystemClient
updateDBSystem: mysql updateDbSystem DbSystemClient
+ Linode:
+ createDatabase: databases databases.d.ts createDatabase
+ updateDatabase: databases databases.d.ts updateDatabase
+ deleteDatabase: databases databases.d.ts deleteDatabase
+ getDatabases: databases databases.d.ts getDatabases
+ getDatabaseEngines: databases databases.d.ts getDatabaseEngines
+ getEngineDatabase: databases databases.d.ts getEngineDatabase
NoSql:
AWS:
@@ -299,13 +306,6 @@ NoSql:
deleteRow: nosql deleteRow
getRow: nosql getRow
updateRow: nosql updateRow
- Linode:
- createDatabase: databases databases.d.ts createDatabase
- updateDatabase: databases databases.d.ts updateDatabase
- deleteDatabase: databases databases.d.ts deleteDatabase
- getDatabases: databases databases.d.ts getDatabases
- getDatabaseEngines: databases databases.d.ts getDatabaseEngines
- getEngineDatabase: databases databases.d.ts getEngineDatabase
DNS:
AWS:
diff --git a/generator/package.json b/generator/package.json
index 51f6a8a6..8f6f595c 100644
--- a/generator/package.json
+++ b/generator/package.json
@@ -31,6 +31,7 @@
"@google-cloud/pubsub": "^2.1.0",
"@google-cloud/storage": "^5.1.1",
"@google-cloud/translate": "^6.0.0",
+ "@linode/api-v4": "^0.97.0",
"aws-sdk": "^2.686.0",
"config": "^1.26.1",
"do-wrapper": "^4.5.1",
diff --git a/generator/transformers/linode/transformer.ts b/generator/transformers/linode/transformer.ts
index 01b5e973..300bd38b 100644
--- a/generator/transformers/linode/transformer.ts
+++ b/generator/transformers/linode/transformer.ts
@@ -75,12 +75,6 @@ export async function transform(
return ts.visitNode(rootNode, visit);
};
- // const addIdentifiers = (
- // context: ts.TransformationContext
- // ) => (rootNode: T) => {
- // let count = 0;
- // };
-
const addIdentifiers = (
context: ts.TransformationContext
) => (rootNode: T) => {
From 037e679f940ce3364edc10328703e5152e8af565 Mon Sep 17 00:00:00 2001
From: Partik SIngh
Date: Sun, 27 Aug 2023 12:54:03 +0530
Subject: [PATCH 2/6] Some changes
Signed-off-by: Partik SIngh
---
.../Linode/compute/linode-kubernetes.js | 242 +++++++++---------
.../Linode/database/linode-RDBMS.js | 190 +++++++-------
.../Linode/storage/linode-storageBucket.js | 186 +++++++-------
generator/transformers/aws/transformer.ts | 6 +-
generator/transformers/azure/transformer.ts | 6 +-
generator/transformers/do/transformer.ts | 6 +-
.../googleCloud/clientBasedTransformer.ts | 6 +-
generator/transformers/linode/transformer.ts | 6 +-
generator/transformers/oracle/transformer.ts | 6 +-
9 files changed, 337 insertions(+), 317 deletions(-)
diff --git a/generator/generatedClasses/Linode/compute/linode-kubernetes.js b/generator/generatedClasses/Linode/compute/linode-kubernetes.js
index 39be1982..0656b2c6 100644
--- a/generator/generatedClasses/Linode/compute/linode-kubernetes.js
+++ b/generator/generatedClasses/Linode/compute/linode-kubernetes.js
@@ -1,122 +1,130 @@
/*This is an auto generated class, please do not change.*/
/**
- * Class to create a KubernetesLinodeClass object
- * @category Linode
- */
+ * Class to create a KubernetesLinodeClass object
+ * @category Linode
+ */
class Linode_Kubernetes {
- /**
- *
- * @param {module} do Linode SDK
- * @param {object} options SDK options
- */
- constructor(linodeSdk, linodeToken) {
- this._linode = linodeSdk;
- this._linodeToken = linodeToken;
- this._linode.setToken(this._linodeToken);
- }
- /**
- * Trigers the getKubernetesClusters function of KubernetesLinodeClass
- * @param {Params} params - Data required for getKubernetesClusters
- * @param {Filter} filters - Data required for getKubernetesClusters
- * @returns {Promise}
- */
- getAllClusters(params = undefined, filters = undefined) {
- return new Promise((resolve, reject) => {
- this._linode.getKubernetesClusters(params, filters)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the createKubernetesCluster function of KubernetesLinodeClass
- * @param {CreateKubeClusterPayload} data - Data required for createKubernetesCluster
- * @returns {Promise}
- */
- create(data) {
- return new Promise((resolve, reject) => {
- this._linode.createKubernetesCluster(data)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the deleteKubernetesCluster function of KubernetesLinodeClass
- * @param {NumberKeyword} clusterID - Data required for deleteKubernetesCluster
- * @returns {Promise}
- */
- delete(clusterID) {
- return new Promise((resolve, reject) => {
- this._linode.deleteKubernetesCluster(clusterID)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the getNodePools function of KubernetesLinodeClass
- * @param {NumberKeyword} clusterID - Data required for getNodePools
- * @param {Params} params - Data required for getNodePools
- * @param {Filter} filters - Data required for getNodePools
- * @returns {Promise}
- */
- getNodePools(clusterID, params = undefined, filters = undefined) {
- return new Promise((resolve, reject) => {
- this._linode.getNodePools(clusterID, params, filters)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the getNodePool function of KubernetesLinodeClass
- * @param {NumberKeyword} clusterID - Data required for getNodePool
- * @param {NumberKeyword} nodePoolID - Data required for getNodePool
- * @returns {Promise}
- */
- getNodePool(clusterID, nodePoolID) {
- return new Promise((resolve, reject) => {
- this._linode.getNodePool(clusterID, nodePoolID)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the createNodePool function of KubernetesLinodeClass
- * @param {NumberKeyword} clusterID - Data required for createNodePool
- * @param {CreateNodePoolData} data - Data required for createNodePool
- * @returns {Promise}
- */
- createNodePool(clusterID, data) {
- return new Promise((resolve, reject) => {
- this._linode.createNodePool(clusterID, data)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the updateNodePool function of KubernetesLinodeClass
- * @param {NumberKeyword} clusterID - Data required for updateNodePool
- * @param {NumberKeyword} nodePoolID - Data required for updateNodePool
- * @param {Partial} data - Data required for updateNodePool
- * @returns {Promise}
- */
- updateNodePool(clusterID, nodePoolID, data) {
- return new Promise((resolve, reject) => {
- this._linode.updateNodePool(clusterID, nodePoolID, data)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the deleteNodePool function of KubernetesLinodeClass
- * @param {NumberKeyword} clusterID - Data required for deleteNodePool
- * @param {NumberKeyword} nodePoolID - Data required for deleteNodePool
- * @returns {Promise}
- */
- deleteNodePool(clusterID, nodePoolID) {
- return new Promise((resolve, reject) => {
- this._linode.deleteNodePool(clusterID, nodePoolID)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
+ /**
+ *
+ * @param {module} do Linode SDK
+ * @param {object} options SDK options
+ */
+ constructor(linodeSdk, linodeToken) {
+ this._linode = linodeSdk;
+ this._linodeToken = linodeToken;
+ this._linode.setToken(this._linodeToken);
+ }
+ /**
+ * Trigers the getKubernetesClusters function of KubernetesLinodeClass
+ * @param {Params} params - Data required for getKubernetesClusters
+ * @param {Filter} filters - Data required for getKubernetesClusters
+ * @returns {Promise}
+ */
+ getAllClusters(params = undefined, filters = undefined) {
+ return new Promise((resolve, reject) => {
+ this._linode
+ .getKubernetesClusters(params, filters)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the createKubernetesCluster function of KubernetesLinodeClass
+ * @param {CreateKubeClusterPayload} data - Data required for createKubernetesCluster
+ * @returns {Promise}
+ */
+ create(data) {
+ return new Promise((resolve, reject) => {
+ this._linode
+ .createKubernetesCluster(data)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the deleteKubernetesCluster function of KubernetesLinodeClass
+ * @param {NumberKeyword} clusterID - Data required for deleteKubernetesCluster
+ * @returns {Promise}
+ */
+ delete(clusterID) {
+ return new Promise((resolve, reject) => {
+ this._linode
+ .deleteKubernetesCluster(clusterID)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the getNodePools function of KubernetesLinodeClass
+ * @param {NumberKeyword} clusterID - Data required for getNodePools
+ * @param {Params} params - Data required for getNodePools
+ * @param {Filter} filters - Data required for getNodePools
+ * @returns {Promise}
+ */
+ getNodePools(clusterID, params = undefined, filters = undefined) {
+ return new Promise((resolve, reject) => {
+ this._linode
+ .getNodePools(clusterID, params, filters)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the getNodePool function of KubernetesLinodeClass
+ * @param {NumberKeyword} clusterID - Data required for getNodePool
+ * @param {NumberKeyword} nodePoolID - Data required for getNodePool
+ * @returns {Promise}
+ */
+ getNodePool(clusterID, nodePoolID) {
+ return new Promise((resolve, reject) => {
+ this._linode
+ .getNodePool(clusterID, nodePoolID)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the createNodePool function of KubernetesLinodeClass
+ * @param {NumberKeyword} clusterID - Data required for createNodePool
+ * @param {CreateNodePoolData} data - Data required for createNodePool
+ * @returns {Promise}
+ */
+ createNodePool(clusterID, data) {
+ return new Promise((resolve, reject) => {
+ this._linode
+ .createNodePool(clusterID, data)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the updateNodePool function of KubernetesLinodeClass
+ * @param {NumberKeyword} clusterID - Data required for updateNodePool
+ * @param {NumberKeyword} nodePoolID - Data required for updateNodePool
+ * @param {Partial} data - Data required for updateNodePool
+ * @returns {Promise}
+ */
+ updateNodePool(clusterID, nodePoolID, data) {
+ return new Promise((resolve, reject) => {
+ this._linode
+ .updateNodePool(clusterID, nodePoolID, data)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the deleteNodePool function of KubernetesLinodeClass
+ * @param {NumberKeyword} clusterID - Data required for deleteNodePool
+ * @param {NumberKeyword} nodePoolID - Data required for deleteNodePool
+ * @returns {Promise}
+ */
+ deleteNodePool(clusterID, nodePoolID) {
+ return new Promise((resolve, reject) => {
+ this._linode
+ .deleteNodePool(clusterID, nodePoolID)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
}
module.exports = Linode_Kubernetes;
diff --git a/generator/generatedClasses/Linode/database/linode-RDBMS.js b/generator/generatedClasses/Linode/database/linode-RDBMS.js
index 1e5e80d6..6dc5e55e 100644
--- a/generator/generatedClasses/Linode/database/linode-RDBMS.js
+++ b/generator/generatedClasses/Linode/database/linode-RDBMS.js
@@ -1,97 +1,103 @@
/*This is an auto generated class, please do not change.*/
/**
- * Class to create a RDBMSLinodeClass object
- * @category Linode
- */
+ * Class to create a RDBMSLinodeClass object
+ * @category Linode
+ */
class Linode_RDBMS {
- /**
- *
- * @param {module} do Linode SDK
- * @param {object} options SDK options
- */
- constructor(linodeSdk, linodeToken) {
- this._linode = linodeSdk;
- this._linodeToken = linodeToken;
- this._linode.setToken(this._linodeToken);
- }
- /**
- * Trigers the getDatabases function of RDBMSLinodeClass
- * @param {Params} params - Data required for getDatabases
- * @param {Filter} filter - Data required for getDatabases
- * @returns {Promise}
- */
- getDatabases(params = undefined, filter = undefined) {
- return new Promise((resolve, reject) => {
- this._linode.getDatabases(params, filter)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the getDatabaseEngines function of RDBMSLinodeClass
- * @param {Params} params - Data required for getDatabaseEngines
- * @param {Filter} filter - Data required for getDatabaseEngines
- * @returns {Promise}
- */
- getDatabaseEngines(params = undefined, filter = undefined) {
- return new Promise((resolve, reject) => {
- this._linode.getDatabaseEngines(params, filter)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the createDatabase function of RDBMSLinodeClass
- * @param {UnionType} engine - Data required for createDatabase
- * @param {CreateDatabasePayload} data - Data required for createDatabase
- * @returns {Promise}
- */
- createDatabase(engine, data) {
- return new Promise((resolve, reject) => {
- this._linode.createDatabase(engine, data)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the getEngineDatabase function of RDBMSLinodeClass
- * @param {Engine} engine - Data required for getEngineDatabase
- * @param {NumberKeyword} databaseID - Data required for getEngineDatabase
- * @returns {Promise}
- */
- getEngineDatabase(engine, databaseID) {
- return new Promise((resolve, reject) => {
- this._linode.getEngineDatabase(engine, databaseID)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the updateDatabase function of RDBMSLinodeClass
- * @param {Engine} engine - Data required for updateDatabase
- * @param {NumberKeyword} databaseID - Data required for updateDatabase
- * @param {UpdateDatabasePayload} data - Data required for updateDatabase
- * @returns {Promise}
- */
- updateDatabase(engine, databaseID, data) {
- return new Promise((resolve, reject) => {
- this._linode.updateDatabase(engine, databaseID, data)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the deleteDatabase function of RDBMSLinodeClass
- * @param {Engine} engine - Data required for deleteDatabase
- * @param {NumberKeyword} databaseID - Data required for deleteDatabase
- * @returns {Promise}
- */
- deleteDatabase(engine, databaseID) {
- return new Promise((resolve, reject) => {
- this._linode.deleteDatabase(engine, databaseID)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
+ /**
+ *
+ * @param {module} do Linode SDK
+ * @param {object} options SDK options
+ */
+ constructor(linodeSdk, linodeToken) {
+ this._linode = linodeSdk;
+ this._linodeToken = linodeToken;
+ this._linode.setToken(this._linodeToken);
+ }
+ /**
+ * Trigers the getDatabases function of RDBMSLinodeClass
+ * @param {Params} params - Data required for getDatabases
+ * @param {Filter} filter - Data required for getDatabases
+ * @returns {Promise}
+ */
+ getDatabases(params = undefined, filter = undefined) {
+ return new Promise((resolve, reject) => {
+ this._linode
+ .getDatabases(params, filter)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the getDatabaseEngines function of RDBMSLinodeClass
+ * @param {Params} params - Data required for getDatabaseEngines
+ * @param {Filter} filter - Data required for getDatabaseEngines
+ * @returns {Promise}
+ */
+ getDatabaseEngines(params = undefined, filter = undefined) {
+ return new Promise((resolve, reject) => {
+ this._linode
+ .getDatabaseEngines(params, filter)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the createDatabase function of RDBMSLinodeClass
+ * @param {UnionType} engine - Data required for createDatabase
+ * @param {CreateDatabasePayload} data - Data required for createDatabase
+ * @returns {Promise}
+ */
+ createDatabase(engine, data) {
+ return new Promise((resolve, reject) => {
+ this._linode
+ .createDatabase(engine, data)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the getEngineDatabase function of RDBMSLinodeClass
+ * @param {Engine} engine - Data required for getEngineDatabase
+ * @param {NumberKeyword} databaseID - Data required for getEngineDatabase
+ * @returns {Promise}
+ */
+ getEngineDatabase(engine, databaseID) {
+ return new Promise((resolve, reject) => {
+ this._linode
+ .getEngineDatabase(engine, databaseID)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the updateDatabase function of RDBMSLinodeClass
+ * @param {Engine} engine - Data required for updateDatabase
+ * @param {NumberKeyword} databaseID - Data required for updateDatabase
+ * @param {UpdateDatabasePayload} data - Data required for updateDatabase
+ * @returns {Promise}
+ */
+ updateDatabase(engine, databaseID, data) {
+ return new Promise((resolve, reject) => {
+ this._linode
+ .updateDatabase(engine, databaseID, data)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the deleteDatabase function of RDBMSLinodeClass
+ * @param {Engine} engine - Data required for deleteDatabase
+ * @param {NumberKeyword} databaseID - Data required for deleteDatabase
+ * @returns {Promise}
+ */
+ deleteDatabase(engine, databaseID) {
+ return new Promise((resolve, reject) => {
+ this._linode
+ .deleteDatabase(engine, databaseID)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
}
module.exports = Linode_RDBMS;
diff --git a/generator/generatedClasses/Linode/storage/linode-storageBucket.js b/generator/generatedClasses/Linode/storage/linode-storageBucket.js
index a2990dd9..5b3b0741 100644
--- a/generator/generatedClasses/Linode/storage/linode-storageBucket.js
+++ b/generator/generatedClasses/Linode/storage/linode-storageBucket.js
@@ -1,95 +1,101 @@
/*This is an auto generated class, please do not change.*/
/**
- * Class to create a StorageBucketLinodeClass object
- * @category Linode
- */
+ * Class to create a StorageBucketLinodeClass object
+ * @category Linode
+ */
class Linode_StorageBucket {
- /**
- *
- * @param {module} do Linode SDK
- * @param {object} options SDK options
- */
- constructor(linodeSdk, linodeToken) {
- this._linode = linodeSdk;
- this._linodeToken = linodeToken;
- this._linode.setToken(this._linodeToken);
- }
- /**
- * Trigers the getBucket function of StorageBucketLinodeClass
- * @param {StringKeyword} clusterId - Data required for getBucket
- * @param {StringKeyword} bucketName - Data required for getBucket
- * @returns {Promise}
- */
- get(clusterId, bucketName) {
- return new Promise((resolve, reject) => {
- this._linode.getBucket(clusterId, bucketName)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the getBuckets function of StorageBucketLinodeClass
- * @param {Params} params - Data required for getBuckets
- * @param {Filter} filters - Data required for getBuckets
- * @returns {Promise}
- */
- list(params = undefined, filters = undefined) {
- return new Promise((resolve, reject) => {
- this._linode.getBuckets(params, filters)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the createBucket function of StorageBucketLinodeClass
- * @param {ObjectStorageBucketRequestPayload} data - Data required for createBucket
- * @returns {Promise}
- */
- create(data) {
- return new Promise((resolve, reject) => {
- this._linode.createBucket(data)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the deleteBucket function of StorageBucketLinodeClass
- * @param {ObjectStorageDeleteBucketRequestPayload} {cluster,label} - Data required for deleteBucket
- * @returns {Promise}
- */
- delete({ cluster, label }) {
- return new Promise((resolve, reject) => {
- this._linode.deleteBucket({ cluster, label })
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the getBucketAccess function of StorageBucketLinodeClass
- * @param {StringKeyword} clusterId - Data required for getBucketAccess
- * @param {StringKeyword} bucketName - Data required for getBucketAccess
- * @returns {Promise}
- */
- getBucketAccess(clusterId, bucketName) {
- return new Promise((resolve, reject) => {
- this._linode.getBucketAccess(clusterId, bucketName)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
- /**
- * Trigers the updateBucketAccess function of StorageBucketLinodeClass
- * @param {StringKeyword} clusterId - Data required for updateBucketAccess
- * @param {StringKeyword} bucketName - Data required for updateBucketAccess
- * @param {ObjectStorageBucketAccessRequest} data - Data required for updateBucketAccess
- * @returns {Promise}
- */
- updateBucketAccess(clusterId, bucketName, data) {
- return new Promise((resolve, reject) => {
- this._linode.updateBucketAccess(clusterId, bucketName, data)
- .then(data => resolve(data))
- .catch(err => reject(err));
- });
- }
+ /**
+ *
+ * @param {module} do Linode SDK
+ * @param {object} options SDK options
+ */
+ constructor(linodeSdk, linodeToken) {
+ this._linode = linodeSdk;
+ this._linodeToken = linodeToken;
+ this._linode.setToken(this._linodeToken);
+ }
+ /**
+ * Trigers the getBucket function of StorageBucketLinodeClass
+ * @param {StringKeyword} clusterId - Data required for getBucket
+ * @param {StringKeyword} bucketName - Data required for getBucket
+ * @returns {Promise}
+ */
+ get(clusterId, bucketName) {
+ return new Promise((resolve, reject) => {
+ this._linode
+ .getBucket(clusterId, bucketName)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the getBuckets function of StorageBucketLinodeClass
+ * @param {Params} params - Data required for getBuckets
+ * @param {Filter} filters - Data required for getBuckets
+ * @returns {Promise}
+ */
+ list(params = undefined, filters = undefined) {
+ return new Promise((resolve, reject) => {
+ this._linode
+ .getBuckets(params, filters)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the createBucket function of StorageBucketLinodeClass
+ * @param {ObjectStorageBucketRequestPayload} data - Data required for createBucket
+ * @returns {Promise}
+ */
+ create(data) {
+ return new Promise((resolve, reject) => {
+ this._linode
+ .createBucket(data)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the deleteBucket function of StorageBucketLinodeClass
+ * @param {ObjectStorageDeleteBucketRequestPayload} {cluster,label} - Data required for deleteBucket
+ * @returns {Promise}
+ */
+ delete({ cluster, label }) {
+ return new Promise((resolve, reject) => {
+ this._linode
+ .deleteBucket({ cluster, label })
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the getBucketAccess function of StorageBucketLinodeClass
+ * @param {StringKeyword} clusterId - Data required for getBucketAccess
+ * @param {StringKeyword} bucketName - Data required for getBucketAccess
+ * @returns {Promise}
+ */
+ getBucketAccess(clusterId, bucketName) {
+ return new Promise((resolve, reject) => {
+ this._linode
+ .getBucketAccess(clusterId, bucketName)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
+ /**
+ * Trigers the updateBucketAccess function of StorageBucketLinodeClass
+ * @param {StringKeyword} clusterId - Data required for updateBucketAccess
+ * @param {StringKeyword} bucketName - Data required for updateBucketAccess
+ * @param {ObjectStorageBucketAccessRequest} data - Data required for updateBucketAccess
+ * @returns {Promise}
+ */
+ updateBucketAccess(clusterId, bucketName, data) {
+ return new Promise((resolve, reject) => {
+ this._linode
+ .updateBucketAccess(clusterId, bucketName, data)
+ .then(data => resolve(data))
+ .catch(err => reject(err));
+ });
+ }
}
module.exports = Linode_StorageBucket;
diff --git a/generator/transformers/aws/transformer.ts b/generator/transformers/aws/transformer.ts
index 30f44614..ed063fe9 100644
--- a/generator/transformers/aws/transformer.ts
+++ b/generator/transformers/aws/transformer.ts
@@ -152,9 +152,9 @@ export async function transform(
ts.isIdentifier(childNode) &&
childNode.text === 'SDKFunctionName'
) {
- const args = classData.functions[
- count
- ].params.map(param => ts.createIdentifier(param.name));
+ const args = classData.functions[count].params.map(
+ param => ts.createIdentifier(param.name)
+ );
node.arguments = args.concat(node.arguments);
}
});
diff --git a/generator/transformers/azure/transformer.ts b/generator/transformers/azure/transformer.ts
index 24b0a4d9..e27a4ef6 100644
--- a/generator/transformers/azure/transformer.ts
+++ b/generator/transformers/azure/transformer.ts
@@ -187,9 +187,9 @@ export async function transform(
ts.isIdentifier(childNode) &&
childNode.text === 'SDKFunctionName'
) {
- const args = classData.functions[
- count
- ].params.map(param => ts.createIdentifier(param.name));
+ const args = classData.functions[count].params.map(
+ param => ts.createIdentifier(param.name)
+ );
node.arguments = args;
}
});
diff --git a/generator/transformers/do/transformer.ts b/generator/transformers/do/transformer.ts
index 15b7b45a..115ed946 100644
--- a/generator/transformers/do/transformer.ts
+++ b/generator/transformers/do/transformer.ts
@@ -167,9 +167,9 @@ export async function transform(
ts.isIdentifier(childNode) &&
childNode.text === 'SDKFunctionName'
) {
- const args = classData.functions[
- count
- ].params.map(param => ts.createIdentifier(param.name));
+ const args = classData.functions[count].params.map(
+ param => ts.createIdentifier(param.name)
+ );
node.arguments = args.concat(node.arguments);
}
});
diff --git a/generator/transformers/googleCloud/clientBasedTransformer.ts b/generator/transformers/googleCloud/clientBasedTransformer.ts
index fbfdbe48..b2819e53 100644
--- a/generator/transformers/googleCloud/clientBasedTransformer.ts
+++ b/generator/transformers/googleCloud/clientBasedTransformer.ts
@@ -217,9 +217,9 @@ export async function clientBasedTransform(
ts.isIdentifier(childNode) &&
childNode.text === 'SDKFunctionName'
) {
- const args = classData.functions[
- count
- ].params.map(param => ts.createIdentifier(param.name));
+ const args = classData.functions[count].params.map(
+ param => ts.createIdentifier(param.name)
+ );
node.arguments = args;
}
});
diff --git a/generator/transformers/linode/transformer.ts b/generator/transformers/linode/transformer.ts
index 300bd38b..cf3e6c2b 100644
--- a/generator/transformers/linode/transformer.ts
+++ b/generator/transformers/linode/transformer.ts
@@ -132,9 +132,9 @@ export async function transform(
ts.isIdentifier(childNode) &&
childNode.text === 'SDKFunctionName'
) {
- const args = classData.functions[
- count
- ].params.map(param => ts.createIdentifier(param.name));
+ const args = classData.functions[count].params.map(
+ param => ts.createIdentifier(param.name)
+ );
node.arguments = args.concat(node.arguments);
}
});
diff --git a/generator/transformers/oracle/transformer.ts b/generator/transformers/oracle/transformer.ts
index 1d5bf81c..d01a42d9 100644
--- a/generator/transformers/oracle/transformer.ts
+++ b/generator/transformers/oracle/transformer.ts
@@ -159,9 +159,9 @@ export async function transform(
ts.isIdentifier(childNode) &&
childNode.text === 'SDKFunctionName'
) {
- const args = classData.functions[
- count
- ].params.map(param => ts.createIdentifier(param.name));
+ const args = classData.functions[count].params.map(
+ param => ts.createIdentifier(param.name)
+ );
node.arguments = args.concat(node.arguments);
}
});
From 5c4196a66f6e2f85f0958f79d59f1f7c2e351fa5 Mon Sep 17 00:00:00 2001
From: Partik SIngh
Date: Sun, 27 Aug 2023 18:36:20 +0530
Subject: [PATCH 3/6] Final changes
Signed-off-by: Partik SIngh
---
generator/README.md | 36 +++++++++++++++++++++++++++++++++++-
1 file changed, 35 insertions(+), 1 deletion(-)
diff --git a/generator/README.md b/generator/README.md
index d5d70d46..39a7ac6e 100644
--- a/generator/README.md
+++ b/generator/README.md
@@ -94,9 +94,43 @@ DO:
+- Oracle
+```
+Oracle:
+ create: containerengine createCluster
+```
+
+
+
+
+
+```
+Oracle:
+ createKey: keymanagement createKey KmsManagementClient
+```
+
+
+
+
+
+- Linode
+
+```
+Linode:
+ create: kubernetes kubernetes.d.ts createKubernetesCluster
+
+
+```
+
+
+
+
+
+
## Code parsers
-This is the simplest part of the code generation tool. The SDK files are read from the relevant SDKs as specified in the `node-cloud.yml` file. Afterwards, it is converted to an **Abstract Syntax Tree**. Finally, the class declaration Node of that **Abstract Syntax Tree** is returned. This retured Node is another **Abstract Syntax Tree** since a class declaration itself is another **Abstract Syntax Tree**.
+This is the simplest part of the code generation tool. The SDK files are read from the relevant SDKs as specified in the `node-cloud.yml` file. Afterwards, it is converted to an **Abstract Syntax Tree**. Finally, the class declaration Node of that **Abstract Syntax Tree** is returned in case of SDKs which are class based,for SDKs like Linode which are function based we collect the FirstStatement nodes in an array which represent the exported arrow function declaration. This retured Node is another **Abstract Syntax Tree** since a class declaration itself is another **Abstract Syntax Tree**.
+
## Data extraction functions
From d92b98654efef1e63b271a61593fbbd6004a2e5c Mon Sep 17 00:00:00 2001
From: Partik SIngh
Date: Sun, 27 Aug 2023 20:04:36 +0530
Subject: [PATCH 4/6] Used Readme
Signed-off-by: Partik SIngh
---
README.md | 239 ++++++++++--------
.../generator/high_level_diagrams/linode.png | Bin 0 -> 55152 bytes
.../high_level_diagrams/linode_diagram.png | Bin 0 -> 170882 bytes
.../generator/high_level_diagrams/oracle.png | Bin 0 -> 44370 bytes
.../generator/high_level_diagrams/oracle2.png | Bin 0 -> 52948 bytes
.../high_level_diagrams/oracle_diagram.png | Bin 0 -> 172020 bytes
.../high_level_diagrams/oracle_diagram2.png | Bin 0 -> 198394 bytes
examples/compute/linode-ks.js | 25 +-
examples/database/linode-sql.js | 9 +-
examples/images/linode-images.js | 70 +++++
examples/network/linode-dns.js | 6 +-
examples/network/linode-lb.js | 74 +-----
examples/storage/linode-objectStorage.js | 62 +++++
generator/README.md | 28 +-
.../compute/linode-kubernetes.js | 36 ++-
.../{linode-noSql.js => linode-RDBMS.js} | 25 +-
packages/linode-plugin/linode.js | 18 +-
.../storage/linode-storageBucket.js | 101 ++++++++
18 files changed, 458 insertions(+), 235 deletions(-)
create mode 100644 assets/generator/high_level_diagrams/linode.png
create mode 100644 assets/generator/high_level_diagrams/linode_diagram.png
create mode 100644 assets/generator/high_level_diagrams/oracle.png
create mode 100644 assets/generator/high_level_diagrams/oracle2.png
create mode 100644 assets/generator/high_level_diagrams/oracle_diagram.png
create mode 100644 assets/generator/high_level_diagrams/oracle_diagram2.png
create mode 100644 examples/images/linode-images.js
create mode 100644 examples/storage/linode-objectStorage.js
rename packages/linode-plugin/database/{linode-noSql.js => linode-RDBMS.js} (80%)
create mode 100644 packages/linode-plugin/storage/linode-storageBucket.js
diff --git a/README.md b/README.md
index 34788296..5a7832ad 100644
--- a/README.md
+++ b/README.md
@@ -19,18 +19,18 @@
Table of Content
-- [Introduction](#introduction)
-- [Supported Service Providers](#-supported-service-providers)
-- [Getting Started](#getting-started)
- - [NodeCloud Plugins](#nodecloud-plugins)
- - [Example](#example)
-- [Overriding Providers](#overriding-providers)
-- [Service Types](#-service-types)
-- [Development setup](#-development-setup)
-- [Important Notes for Developers](#important-notes-for-developers-)
-- [Test Changes](#test-changes)
-- [NodeCloud Code Generation tool](#nodecloud-code-generation-tool)
-- [License](#-license)
+- [Introduction](#introduction)
+- [Supported Service Providers](#-supported-service-providers)
+- [Getting Started](#getting-started)
+ - [NodeCloud Plugins](#nodecloud-plugins)
+ - [Example](#example)
+- [Overriding Providers](#overriding-providers)
+- [Service Types](#-service-types)
+- [Development setup](#-development-setup)
+- [Important Notes for Developers](#important-notes-for-developers-)
+- [Test Changes](#test-changes)
+- [NodeCloud Code Generation tool](#nodecloud-code-generation-tool)
+- [License](#-license)
# Introduction
@@ -38,18 +38,20 @@ Table of Content
NodeCloud will be useful to you if:
-- you work on a project which uses multiple cloud providers
-- you are looking for an abstract cloud API which can switch between cloud providers with fewer code changes
-- you are an open-source enthusiast who is into cloud engineering or code generation
-- you want to improve your skills in NodeJS, Typescript and cloud service providers
+- you work on a project which uses multiple cloud providers
+- you are looking for an abstract cloud API which can switch between cloud providers with fewer code changes
+- you are an open-source enthusiast who is into cloud engineering or code generation
+- you want to improve your skills in NodeJS, Typescript and cloud service providers
## 📘 Supported Service Providers
-- Amazon Web Services (AWS)
-- Azure
-- Google Cloud Platform (GCP)
-- DigitalOcean
-- AliCloud
+- Amazon Web Services (AWS)
+- Azure
+- Google Cloud Platform (GCP)
+- DigitalOcean
+- AliCloud
+- Oracle
+- Linode
_📢 if your required cloud provider plugin is not listed here, we'd love your help to add it :)_
@@ -71,13 +73,15 @@ Once `@nodecloud/common` is installed, you need to install the plugins to intera
### NodeCloud Plugins
-| Plugin | Installation |
-| -------------------- | --------------------------------------------------------------------- |
-| AWS plugin | `yarn add @nodecloud/aws-plugin` or `npm i @nodecloud/aws-plugin` |
-| Azure plugin | `yarn add @nodecloud/gcp-plugin` or `npm i @nodecloud/gcp-plugin` |
-| Google Cloud plugin | `yarn add @nodecloud/azure-plugin` or `npm i @nodecloud/azure-plugin` | |
-| Digital Ocean plugin | `yarn add @nodecloud/do-plugin` or `npm i @nodecloud/do-plugin` |
-| Alibaba plugin | `yarn add nodecloud-ali-plugin` or `npm i nodecloud-ali-plugin` |
+| Plugin | Installation |
+| -------------------- | ----------------------------------------------------------------------- |
+| AWS plugin | `yarn add @nodecloud/aws-plugin` or `npm i @nodecloud/aws-plugin` |
+| Azure plugin | `yarn add @nodecloud/gcp-plugin` or `npm i @nodecloud/gcp-plugin` |
+| Google Cloud plugin | `yarn add @nodecloud/azure-plugin` or `npm i @nodecloud/azure-plugin` | |
+| Digital Ocean plugin | `yarn add @nodecloud/do-plugin` or `npm i @nodecloud/do-plugin` |
+| Alibaba plugin | `yarn add nodecloud-ali-plugin` or `npm i nodecloud-ali-plugin` |
+| Oracle plugin | `yarn add @nodecloud-oracle-plugin` or `npm i @nodecloud-oracle-plugin` |
+| Linode plugin | `yarn add @nodecloud-linode-plugin` or `npm i @nodecloud-linode-plugin` |
**3️⃣ Create the NodeCloud config file**
@@ -95,37 +99,49 @@ This config file can contain an array of objects for all providers and all will
### Example
```js
-const nodeCloudAwsPlugin = require("@nodecloud/aws-plugin");
-const nodeCloudGcpPlugin = require("@nodecloud/gcp-plugin");
-const nodeCloudAzurePlugin = require("@nodecloud/azure-plugin");
-const nodeCloudDoPlugin = require("@nodecloud/do-plugin");
+const nodeCloudAwsPlugin = require('@nodecloud/aws-plugin');
+const nodeCloudGcpPlugin = require('@nodecloud/gcp-plugin');
+const nodeCloudAzurePlugin = require('@nodecloud/azure-plugin');
+const nodeCloudDoPlugin = require('@nodecloud/do-plugin');
+const nodeCloudOraclePlugin = require('@nodecloud/oracle-plugin');
+const nodeCloudLinodePlugin = require('@nodecloud/linode-plugin');
const providers = [
- {
- name: "aws",
- tag: "aws",
- plugin: nodeCloudAwsPlugin,
- configPath: "C:\\Users\\Rajitha\\opensource\\aws_cred.json"
- },
- {
- name: "google",
- tag: "google",
- plugin: nodeCloudGcpPlugin,
- configPath: {
- projectId: "astral-hold-276807",
- keyFilename: "C:\\Users\\Rajitha\\opensource\\gcp_cred.json"
- }
- },
- {
- name: "azure",
- tag: "azure",
- plugin: nodeCloudAzurePlugin
- },
- {
- name: "digitalocean",
- tag: "do",
- plugin: nodeCloudDoPlugin
- }
+ {
+ name: 'aws',
+ tag: 'aws',
+ plugin: nodeCloudAwsPlugin,
+ configPath: 'C:\\Users\\Rajitha\\opensource\\aws_cred.json',
+ },
+ {
+ name: 'google',
+ tag: 'google',
+ plugin: nodeCloudGcpPlugin,
+ configPath: {
+ projectId: 'astral-hold-276807',
+ keyFilename: 'C:\\Users\\Rajitha\\opensource\\gcp_cred.json',
+ },
+ },
+ {
+ name: 'azure',
+ tag: 'azure',
+ plugin: nodeCloudAzurePlugin,
+ },
+ {
+ name: 'digitalocean',
+ tag: 'do',
+ plugin: nodeCloudDoPlugin,
+ },
+ {
+ name: 'oracle',
+ tag: 'oracle',
+ plugin: nodeCloudOraclePlugin,
+ },
+ {
+ name: 'linode',
+ tag: 'linode',
+ plugin: nodeCloudLinodePlugin,
+ },
];
module.exports = providers;
```
@@ -137,52 +153,52 @@ Congratulations! You just configured NodeCloud in your project. Let's start with
The below code is an example of usage in AWS.
```js
-const nc = require("@nodecloud/common"); // NodeCloud common module
+const nc = require('@nodecloud/common'); // NodeCloud common module
const optionsProvider = {
- overrideProviders: false
+ overrideProviders: false,
};
const ncProviders = nc.getProviders(optionsProvider);
const options = {
- apiVersion: "2017-11-01"
+ apiVersion: '2017-11-01',
};
const computeModule = ncProviders.aws.compute(options);
function launchInstance() {
- const instanceParams = {
- ImageId: "ami-07ebfd5b3428b6f4d", // Image of Ubuntu Server 18.04 LTS
- InstanceType: "t2.micro",
- KeyName: "nodeCloud", // key name of Key pair
- MinCount: 1,
- MaxCount: 1
- };
-
- // create AWS EC2 instance
- computeModule
- .create(instanceParams)
- .then(res => {
- console.log(`All done ! ${res}`);
- })
- .catch(err => {
- console.log(`Oops something happened ${err}`);
- });
+ const instanceParams = {
+ ImageId: 'ami-07ebfd5b3428b6f4d', // Image of Ubuntu Server 18.04 LTS
+ InstanceType: 't2.micro',
+ KeyName: 'nodeCloud', // key name of Key pair
+ MinCount: 1,
+ MaxCount: 1,
+ };
+
+ // create AWS EC2 instance
+ computeModule
+ .create(instanceParams)
+ .then(res => {
+ console.log(`All done ! ${res}`);
+ })
+ .catch(err => {
+ console.log(`Oops something happened ${err}`);
+ });
}
function stopInstance() {
- const params = {
- InstanceIds: ["i-0928af5c626f85da9"],
- DryRun: false
- };
-
- // stop AWS EC2 instance
- computeModule
- .stop(params)
- .then(res => {
- console.log(res);
- })
- .catch(err => {
- console.log(err);
- });
+ const params = {
+ InstanceIds: ['i-0928af5c626f85da9'],
+ DryRun: false,
+ };
+
+ // stop AWS EC2 instance
+ computeModule
+ .stop(params)
+ .then(res => {
+ console.log(res);
+ })
+ .catch(err => {
+ console.log(err);
+ });
}
```
@@ -191,32 +207,35 @@ function stopInstance() {
NodeCloud officially supports AWS, GCP, Azure, DigitalOcean and AliCloud. If you want to use a community-driven plugin override the providers' list as follows.
```js
-const nodeCloud = require("nodecloud");
+const nodeCloud = require('nodecloud');
const options = {
- overrideProviders: true
+ overrideProviders: true,
};
const ncProviders = nodeCloud.getProviders(options);
```
## 📟 Service Types
-| Service Category | Service | AWS | GCP | Azure | DigitalOcean | AliCloud |
-| ----------------------- | ----------------------------------- | :-----------------------------------: | :-------------------------------: | :---------------------------------------------------------------------: | :---------------------------------------: | :---------------------------------------------------: |
-| Compute | IaaS | EC2 | Compute Engine | Virtual Machine | Droplets | ECS |
-| | Faas | AWS Lambda\* | Cloud Functions\* | Azure Functions\* | - | Function Compute\* |
-| | Containers | ECS, EKS | Google Kubernetes Engine | AKS, Azure Service Fabric\* | DO Kubernetes | Container Service*, Container Service for Kubernetes* |
-| | Containers (without infrastructure) | AWS Fargate\* | Cloud Run\* | - | - | ECI\* |
-| | Paas | AWS Elastic Beanstalk | App Engine\* | App Service | - | Simple Application Server\* |
-| Storage | Object Storage | S3 | Cloud Storage | Azure Blob Storage | Spaces\* | Bucket (OSS) |
-| | Block Storage | EBS | Persistent Disks | Disk Storage | Volumes | NAS\* |
-| Networking | Load Balancer | ELB | Cloud Load Balancing\* | Azure Load Balancer | DO Load Balancer | SLB |
-| | Peering/Dedicated Interconnect | Direct Connect | Cloud Interconnect\* | ExpressRoute\* | - | Express Connect\* |
-| | DNS | Route53 | Google Domains, Cloud DNS | Azure DNS | DO DNS | Alibaba Cloud DNS\* |
-| Databases | RDBMS | RDS, Amazon Aurora*, Amazon Redshift* | Cloud SQL\*, Cloud Spanner | SQL Database, Azure Database for MySQL*, Azure Database for PostgreSQL* | Managed Databases(PostgreSQL\* and MySQL) | ApsaraDB (MySQL, MariaDB TX, SQL Server, PostgreSQL) |
-| | NoSQL: key-value | DynamoDB | Cloud Firestore, Cloud Bigtable\* | Table Storage | Managed Databases(Redis)\* | ApsaraDB for Redis\* |
-| | NoSQL: indexed | Amazon SimpleDB\* | Cloud Firestore | Cosmos DB | - | ApsaraDB for MongoDB\* |
-| Security/ Authorization | Identity Access Management | AWS IAM | Cloud IAM\* | Azure Active Directory*, Azure Role Based Access Control* | - | Resource Access Management\* |
-| Management | Key Management | AWS-KMS | - | - | Do-Keys | - |
+| Service Category | Service | AWS | GCP | Azure | DigitalOcean | AliCloud | Linode | Oracle |
+| ----------------------- | ----------------------------------- | :-----------------------------------: | :-------------------------------: | :---------------------------------------------------------------------: | :---------------------------------------: | :---------------------------------------------------: | :---------------------------: | :-------------------: |
+| Compute | IaaS | EC2 | Compute Engine | Virtual Machine | Droplets | ECS | Linodes | OCI ContainerInstance |
+| | Faas | AWS Lambda\* | Cloud Functions\* | Azure Functions\* | - | Function Compute\* | - | - |
+| | Containers | ECS, EKS | Google Kubernetes Engine | AKS, Azure Service Fabric\* | DO Kubernetes | Container Service*, Container Service for Kubernetes* | LKS | OCI ContainerEngine |
+| | Containers (without infrastructure) | AWS Fargate\* | Cloud Run\* | - | - | ECI\* | - | - |
+| | Paas | AWS Elastic Beanstalk | App Engine\* | App Service | - | Simple Application Server\* | - | - |
+| Storage | Object Storage | S3 | Cloud Storage | Azure Blob Storage | Spaces\* | Bucket (OSS) | Object Storage | OCI Object Storage |
+| | Block Storage | EBS | Persistent Disks | Disk Storage | Volumes | NAS\* | - | OCI Volume |
+| Networking | Load Balancer | ELB | Cloud Load Balancing\* | Azure Load Balancer | DO Load Balancer | SLB | Node Balancer | OCI LoadBalancer |
+| | Peering/Dedicated Interconnect | Direct Connect | Cloud Interconnect\* | ExpressRoute\* | - | Express Connect\* | - | - |
+| | DNS | Route53 | Google Domains, Cloud DNS | Azure DNS | DO DNS | Alibaba Cloud DNS\* | Domains | OCI DNS |
+| Databases | RDBMS | RDS, Amazon Aurora*, Amazon Redshift* | Cloud SQL\*, Cloud Spanner | SQL Database, Azure Database for MySQL*, Azure Database for PostgreSQL* | Managed Databases(PostgreSQL\* and MySQL) | ApsaraDB (MySQL, MariaDB TX, SQL Server, PostgreSQL) | Database(Postgres and Myssql) | OCI Mysql |
+| | NoSQL: key-value | DynamoDB | Cloud Firestore, Cloud Bigtable\* | Table Storage | Managed Databases(Redis)\* | ApsaraDB for Redis\* | - | OCI MOngoDb |
+| | NoSQL: indexed | Amazon SimpleDB\* | Cloud Firestore | Cosmos DB | - | ApsaraDB for MongoDB\* | - | - |
+| Security/ Authorization | Identity Access Management | AWS IAM | Cloud IAM\* | Azure Active Directory*, Azure Role Based Access Control* | - | Resource Access Management\* | - | - |
+| Management | Key Management | AWS-KMS | - | - | Do-Keys | - | Monitoring | OCI KeyManagement |
+| Firewalls | Firewalls | - | - | - | - | - | Firewalls | - |
+| Images | Images | - | - | - | - | - | Images | - |
+| Blockchain | Blockchain | - | - | - | - | - | - | OCI Blockchain |
\*yet to be implemented
diff --git a/assets/generator/high_level_diagrams/linode.png b/assets/generator/high_level_diagrams/linode.png
new file mode 100644
index 0000000000000000000000000000000000000000..e3cb3c3360acdc949443fde3b8586efbb955f650
GIT binary patch
literal 55152
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
M>fI^2{qXt!0kiT4Gynhq
literal 0
HcmV?d00001
diff --git a/assets/generator/high_level_diagrams/linode_diagram.png b/assets/generator/high_level_diagrams/linode_diagram.png
new file mode 100644
index 0000000000000000000000000000000000000000..a5b56c142c5759d883e36b3de9dc7b8b68396b6b
GIT binary patch
literal 170882
zcmc$_c|6qX|3BPz(h2F5D20-gz3jV6$ev~FL-w7**oQj8k&r!m_N`M`{%vi@*
zhZ2LaGng^Buc>pspY!?We%z1y@w@NuJUWNbG_LpczFx1_bDQudn#%NNS&H|cJ<#(>Tb{D>o-p#8CtM9b^(pP-2@n0K
zJe|DNr3J6(%Fa%^`5_eF{^;zLzBdXD3b#UZ(7k`W{SOPy~a%9BouLSV3M)uLg|9a^|
zyMJDJ?AWK5e@LDD&(m{n`mg-w*|Vqrr&gyRkkrHK^~ZnS`bEt}>HoXS`Tt{$wsOlS
z{$9}xWYe!HBy(bX{9O5kW5-_Xp8Vfm-Pbwyx;BA-RtOfl?qyl<|NKDwf3t(VVW4Jy
zJsMTb5H;%_CMFX%^ua3E1E2n{uZ|9soA;>VKPv=Zahl8juS@Fx&&MeWd++MK27x
z2t=kpS0^XwFRIklG5jyAPMF>6Uws4@XdVDl3Ac8~?v>vRc9&!gd-4a4@qaFTExx+C
zx=rBtG2B_+Vy8{ge5P+^m-8TaDPpCZUFMp$Sn3pZGBi|5lC`w2Dah9bvPBzVY-R-E
zV=~}~c_Nk?*JT}#a)j7G@>rG#!{dV`_2Vf9M8@@NN1JXf{AV+wS+4|?uHB;CJ^!CR
z)EL$%*K+tR^RQ-cal33kaJx$xA$y0?5JbuBwiXgh8+u}nI3m{s5qtOl%=*Z7F51!2
zPhak+u~n_-wUU)8XKc5%uuv+h!l<;UtVqYos>xI{tX^tdL}XM@*{O%%qdHpNT>gCY
z)(ri>`mGOxZ)2b@JdlKEzNI2o3^56RrK+krJT_34H+M;N7~3?$;yPKs-@1Ramn82$
zzc;#