Retire SDK templates.

This commit is contained in:
Greyscale 2021-05-17 00:10:04 +02:00
parent 65abcea0b8
commit d6ad164da4
24 changed files with 0 additions and 793 deletions

View file

@ -1,78 +0,0 @@
/**
{% if route.callbackProperties %}
{% for callbackProperty in route.callbackProperties %}
* @param ${{ callbackProperty.name }}
{% endfor %}
{% endif %}
* @return array
* @throws Exceptions\SDKException
**/
public function {{ route.function }}(
{% if route.callbackProperties %}
{% for callbackProperty in route.callbackProperties %}
${{ callbackProperty.name }}{% if not callbackProperty.isMandatory %} = "{{ callbackProperty.default }}"{% endif %}{% if not loop.last %},{% endif %}
{% endfor %}
{% endif %}
)
{
{% if route.callbackProperties %}
$propertyArray = [
{% for callbackProperty in route.callbackProperties %}
'{{ callbackProperty.name }}' => ${{ callbackProperty.name }},
{% endfor %}
];
{% endif %}
/** @var $response \GuzzleHttp\Psr7\Response */
{% if route.callbackProperties %}
$endpoint = $this->replaceUrlElements(
"{{ route.pattern }}",
[
{% for callbackProperty in route.callbackProperties %}
'{{ callbackProperty.name }}' => ${{ callbackProperty.name }},
{% endfor %}
]
);
{% else %}
$endpoint = "{{ route.pattern }}";
{% endif %}
$method = "{{ route.method }}";
try {
$response = $this->request(
$method,
$endpoint,
[
'headers' => [
'Accept' => 'application/json',
],
{% if route.callbackProperties %}
'body' => json_encode($propertyArray),
{% endif %}
]
);
$body = $response->getBody()->getContents();
if(json_decode($body) === null){
throw new Exceptions\SDKException("Response from API ({$endpoint}) was not expected JSON: " . var_export($body, true));
}
$body = json_decode($body, true);
return $body;
} catch (GuzzleException\ClientException $clientException) {
$body = $clientException->getResponse()->getBody()->getContents();
if (json_decode($body) === null) {
throw new Exceptions\SDKException(
"Response from API ({$endpoint}) was not expected JSON:\n" .
"Method: {$method}\n" .
"GuzzleConfig: " . var_export($this->sdkClient->getGuzzle()->getConfig(), true) . "\n".
"URL: {$endpoint}\n" .
{% if route.callbackProperties %}
"Request: " . json_encode($propertyArray, JSON_PRETTY_PRINT) . "\n\n" .
{% endif %}
var_export($body, true)
);
}
$body = json_decode($body, true);
return $body;
}
}

View file

@ -1,39 +0,0 @@
/**
* @return Models\{{ route.singular }}Model
* @throws Exceptions\SDKException
**/
public function {{ route.function }}($propertyArray)
{
/** @var $response \GuzzleHttp\Psr7\Response */
$endpoint = "{{ route.pattern }}";
$method = "{{ route.method }}";
$headers = [
'Accept' => 'application/json',
];
$response = $this->request(
$method,
$endpoint,
[
'headers' => $headers,
'body' => json_encode($propertyArray),
]
);
$body = $response->getBody()->getContents();
if(json_decode($body) === null){
throw new Exceptions\SDKException("Response from API ({$endpoint}) was not expected JSON: " . var_export($body, true));
}
$body = json_decode($body, true);
return $this->hydrate($body['{{ route.singular }}']);
}
/**
* @return Models\{{ route.singular }}Model;
*/
public function {{ route.function }}FromObject(Models\{{ route.singular }}Model ${{ route.singular }})
{
return $this->{{ route.function }}(
${{ route.singular }}->__toUpsertArray()
);
}

View file

@ -1,35 +0,0 @@
/**
* Delete a Models\{{ routes['create'].singular }}Model by ID. Returns true on success, false on failure.
* @return bool
**/
public function {{ route.function }}($id) : bool
{
/** @var $response \GuzzleHttp\Psr7\Response */
$endpoint = $this->replaceUrlElements(
"{{ route.pattern }}",
[
'id' => $id
]
);
$response = $this->request(
"{{ route.method }}",
$endpoint,
[
'headers' => [
'Accept' => 'application/json',
],
]
);
$body = $response->getBody()->getContents();
if(json_decode($body) === null){
throw new Exceptions\SDKException("Response from API ({$endpoint}) was not expected JSON: " . var_export($body, true));
}
$body = json_decode($body, true);
if($body['Status'] == 'Okay'){
return true;
}else{
return false;
}
}

View file

@ -1,79 +0,0 @@
/**
* Return a single Models\{{ routes['create'].singular }}Model by ID
*
* @return Models\{{ routes['create'].singular }}Model
*
* @throws Exceptions\ObjectNotFoundException
* @throws Exceptions\SDKException
**/
public function {{ route.function }}($id) : Models\{{ routes['create'].singular }}Model
{
/** @var $response \GuzzleHttp\Psr7\Response */
$endpoint = $this->replaceUrlElements(
"{{ route.pattern }}",
[
'id' => $id
]
);
try{
$response = $this->request(
"{{ route.method }}",
$endpoint,
[
'headers' => [
'Accept' => 'application/json',
],
]
);
$body = $response->getBody()->getContents();
if(json_decode($body) === null){
throw new Exceptions\SDKException("Response from API ({$endpoint}) was not expected JSON: " . var_export($body, true));
}
$body = json_decode($body, true);
return $this->hydrate($body['{{ route.singular }}']);
}catch(\GuzzleHttp\Exception\ClientException $clientException){
$body = $clientException->getResponse()->getBody()->getContents();
if(json_decode($body) === null){
throw new Exceptions\SDKException("Response from API ({$endpoint}) was not expected JSON and it was a " . $clientException->getResponse()->getStatusCode());
}
$json = json_decode($body, true);
if($json['Status'] == 'Fail'){
throw new Exceptions\ObjectNotFoundException($json['Reason']);
}else{
throw new Exceptions\ObjectNotFoundException("A bad thing happened: " . $body);
}
}
}
/**
* Get a single result with an optional filter.
*
* @param Filter|null $filter
*
* @return Models\{{ route.singular }}Model|null
*/
public function getFiltered(Filter $filter = null) : ?Models\{{ route.singular }}Model
{
$singular = $this->list($filter->setLimit(1));
return (is_array($singular) && count($singular) == 1)
? reset($singular)
: null;
}
/**
* Get many results with an optional filter
*
* @param Filter|null $filter
*
* @return Models\{{ route.singular }}Model|null
*/
public function getManyFiltered(Filter $filter = null) : ?array
{
$list = $this->list($filter);
return (is_array($list) && count($list) > 0)
? $list
: null;
}

View file

@ -1,47 +0,0 @@
{% for property in route.properties %}
const FIELD_{{ property|transform_studly_to_screamingsnake }} = '{{ property }}';
{% endfor %}
/**
* @param $filter Filter instance
* @return null|Models\{{ route.singular }}Model[]
* @throws Exceptions\SDKException
**/
public function {{ route.function }}(Filter $filter = null) : ?array
{
/** @var $response \GuzzleHttp\Psr7\Response */
$endpoint = "{{ route.pattern }}";
$method = "{{ route.method }}";
$headers = [
'Filter' => $filter instanceof Filter ? $filter->getHeaderJson() : null ,
'Accept' => 'application/json',
];
$response = $this->request(
$method,
$endpoint,
[
'headers' => $headers
]
);
$body = $response->getBody()->getContents();
if(json_decode($body) === null){
throw new Exceptions\SDKException("Response from API ({$endpoint}) was not expected JSON: " . var_export($body, true));
}
$body = json_decode($body, true);
if (strtolower($body['Status']) == strtolower('Okay')) {
if(!isset($body['{{ route.plural }}'])){
// @todo make exception less generic - MB
throw new Exceptions\SDKException(
"Could not find element '{{ route.plural }}' in response from API.\n" .
"Endpoint: {$endpoint}\n" .
"Method: {$method}\n" .
"Available Keys were: ['" . implode("', '", array_keys($body)) . "'].\n"
);
}
return $this->hydrate($body['{{ route.plural }}']);
}
return null;
}

View file

@ -1,29 +0,0 @@
/**
*
* @return Models\{{ routes['create'].singular }}Model|Models\{{ routes['create'].singular }}Model[]
*/
protected function hydrate($raw{{ routes['create'].singular }})
{
// if the entity is an array and is empty, return false. Nothing to hydrate.
if(is_array($raw{{ routes['create'].singular }}) && empty($raw{{ routes['create'].singular }})){
return null;
}
if(
// If the data given IS an array
is_array($raw{{ routes['create'].singular }}) &&
// And Is NOT an associative array
!(array_keys($raw{{ routes['create'].singular }}) !== range(0, count($raw{{ routes['create'].singular }}) - 1)) &&
// And is NOT an empty array...
!count($raw{{ routes['create'].singular }}) == 0
){
// Then we have to hydrate each element. Recursively. Aww yeah.
$array = [];
foreach($raw{{ routes['create'].singular }} as $index => ${{ routes['create'].singular|lower }}){
$array[$index] = $this->hydrate(${{ routes['create'].singular|lower }});
}
return $array;
}else{
return new Models\{{ routes['create'].singular }}Model($this->sdkClient, $raw{{ routes['create'].singular }});
}
}

View file

@ -1,6 +0,0 @@
<?php
namespace {{ app_namespace }}\SDK\{{ app_name }}\AccessLayer;
class {{ pack_name }}AccessLayer extends Base\Base{{ pack_name }}AccessLayer
{
}

View file

@ -1,23 +0,0 @@
<?php
namespace {{ app_namespace }}\SDK\{{ app_name }}\AccessLayer\Base;
use Gone\SDK\Common\Abstracts\AbstractAccessLayer;
use Gone\SDK\Common\Exceptions;
use {{ app_namespace }}\SDK\{{ app_name }}\Models;
use Gone\SDK\Common\Filters\Filter;
use GuzzleHttp\Exception as GuzzleException;
abstract class Base{{ pack_name }}AccessLayer extends AbstractAccessLayer
{
{% for route in routes %}
{% set test_file = "SDK/AccessLayer/" ~ "_function_" ~ route.template ~ ".php.twig" %}
{% include test_file %}
{% endfor %}
{% if routes['create'].singular %}
{% include "SDK/AccessLayer/_hydrator.php.twig" %}
{% endif %}
}

View file

@ -1,10 +0,0 @@
FROM php:7.2-cli
RUN apt-get update && apt-get install -y \
libxml2 libxml2-dev \
libpcre3-dev \
--no-install-recommends && rm -r /var/lib/apt/lists/* && \
pecl install xdebug-2.6.0 && \
docker-php-ext-enable xdebug && \
docker-php-ext-install mysqli pdo pdo_mysql soap xml json
WORKDIR /app
COPY . /app

View file

@ -1,73 +0,0 @@
<?php
namespace {{ app_namespace }}\SDK\{{ app_name }}\Models\Base;
use Gone\SDK\Common\Abstracts\AbstractModel;
use Gone\SDK\Common\Traits\PresentableTrait;
use {{ app_namespace }}\SDK\{{ app_name }}\AccessLayer\{{ pack_name }}AccessLayer;
use {{ app_namespace }}\SDK\{{ app_name }}\Models\{{ pack_name }}Model;
abstract class Base{{ pack_name }}Model extends AbstractModel
{
use PresentableTrait;
{% for property in properties %}
const FIELD_{{ property|upper }} = '{{ property|transform_studly_to_camel }}';
{% endfor %}
// Constant arrays defined by ENUMs
{% for propertyName, property in propertiesOptions %}
const OPTIONS_{{ propertyName|upper }} = ["{{ property | join('", "') | raw }}"];
{% endfor %}
{% for propertyName, property in propertiesOptions %}
{% for permittedValue in property %}
const {{ propertyName|upper }}_{{ permittedValue|upper|replace({'-':'_'}) }} = '{{ permittedValue }}';
{% endfor %}
{% endfor %}
// Properties
{% for property in properties %}
protected ${{ property }};
{% endfor %}
public function __toArray() : array
{
return [
{% for property in properties %}
"{{ property }}" => $this->get{{ property }}(),
{% endfor %}
];
}
protected function getAccessLayer() : {{ pack_name }}AccessLayer
{
return new {{ pack_name }}AccessLayer($this->sdkClient);
}
/**
* Convenience function to create/update the current model.
*/
public function save() : {{ pack_name }}Model
{
return $this->getAccessLayer()->createFromObject($this);
}
// Getters and Setters
{% for property in properties %}
public function get{{ property }}()
{
return $this->{{ property }};
}
public function set{{ property }}(${{ property }}) : {{ pack_name }}Model
{
if($this->{{ property }} != ${{ property }}){
$this->addDirtyKey('{{ property }}');
$this->{{ property }} = ${{ property }};
}
return $this;
}
{% endfor %}
}

View file

@ -1,7 +0,0 @@
<?php
namespace {{ app_namespace }}\SDK\{{ app_name }}\Models;
class {{ pack_name }}Model extends Base\Base{{ pack_name }}Model
{
}

View file

@ -1,11 +0,0 @@
/**
* @vcr unittest_{{ pack_name|lower }}_{{ route.function|lower }}.cassette
**/
public function test{{ route.function }}()
{
$this->markTestIncomplete("I need to think about how I want to autogenerate these.");
$response = $this->client->{{ scope_name }}->{{ route.function }}();
$this->assertEquals("Okay", $response->Status);
}

View file

@ -1,17 +0,0 @@
/**
* @vcr unittest_{{ pack_name|lower }}_create.cassette
**/
public function test{{ route.function|capitalize }}()
{
${{ route.singular }} = $this->client->{{ scope_name }}->{{ route.function }}([
{% for property, value in route.example %}
'{{ property }}' => {{ var_export(value) }},
{% endfor %}
]);
{% for property, value in route.example %}
$this->assertEquals({{ var_export(value) }}, ${{ route.singular }}->get{{ property }}());
{% endfor %}
return ${{ route.singular }};
}

View file

@ -1,24 +0,0 @@
/**
* @depends testGet
* @vcr unittest_{{ pack_name|lower }}_delete.cassette
**/
public function test{{ route.function|capitalize }}(${{ route.singular }})
{
$response = $this->client->{{ scope_name }}->{{ route.function }}(${{ route.singular }}->getId());
$this->assertTrue($response);
return ${{ route.singular }};
}
/**
* @depends test{{ route.function|capitalize }}
* @expectedException \Gone\SDK\Common\Exceptions\ObjectNotFoundException
* @expectedExceptionMessageRegExp /No such {{ pack_name|lower }} found with id \d+/
* @vcr unittest_{{ pack_name|lower }}_verifydeleted.cassette
**/
public function test{{ route.function|capitalize }}VerifyDeleted(${{ route.singular}})
{
$id = ${{ route.singular }}->getId();
$this->client->{{ scope_name }}->get($id);
}

View file

@ -1,15 +0,0 @@
/**
* @depends testCreate
* @vcr unittest_{{ pack_name|lower }}_get.cassette
**/
public function test{{ route.function|capitalize }}(Models\{{ route.singular }}Model ${{ route.singular }})
{
$idToGet = ${{ route.singular }}->getId();
$requested{{ route.singular }} = $this->client->{{ scope_name }}->{{ route.function }}(
$idToGet
);
$this->assertEquals(${{ route.singular }}->getId(), $requested{{ route.singular }}->getId());
return ${{ route.singular }};
}

View file

@ -1,82 +0,0 @@
/**
* @vcr unittest_{{ pack_name|lower }}_list.cassette
**/
public function test{{ route.function|capitalize }}()
{
$response = $this->client->{{ scope_name }}->{{ route.function }}();
if($response == false){
$this->markTestSkipped("There was no data returned calling {{ route.function }}() on {{ pack_name|lower }}.");
}
$element = $response[rand(0,count($response) - 1)];
$this->assertEquals('{{ app_namespace }}\SDK\{{ app_name }}\Models\{{ route.singular }}Model', get_class($element));
return $response;
}
/**
* @vcr unittest_{{ pack_name|lower }}_list.cassette
**/
public function test{{ route.function|capitalize }}LimitOne()
{
$response = $this->client->{{ scope_name }}->{{ route.function }}(
Filter::Factory()
->setLimit(1)
->setOffset(0)
);
if($response == false){
$this->markTestSkipped("There was no data returned calling {{ route.function }}() on {{ pack_name|lower }}.");
}
$element = $response[rand(0,count($response) - 1)];
$this->assertEquals('{{ app_namespace }}\SDK\{{ app_name }}\Models\{{ route.singular }}Model', get_class($element));
$this->assertEquals(1, count($response));
return $response[0];
}
/**
* @depends test{{ route.function|capitalize }}LimitOne
* @vcr unittest_{{ pack_name|lower }}_list.cassette
**/
public function test{{ route.function|capitalize }}Wheres(\{{ app_namespace }}\SDK\{{ app_name }}\Models\{{ route.singular }}Model $toFind)
{
$filter = Filter::Factory();
{% for key, value in route.example %}
if(is_string($toFind->get{{ key }}()) || is_numeric($toFind->get{{ key }}())){
$filter->addWhere('{{ key }}', $toFind->get{{ key }}(), '=');
}
{% endfor %}
$response = $this->client->{{ scope_name }}->{{ route.function }}($filter);
//\Kint::dump($response);
/** @var $element \{{ app_namespace }}\SDK\{{ app_name }}\Models\{{ route.singular }}Model */
$element = $response[rand(0,count($response) - 1)];
$this->assertEquals('{{ app_namespace }}\SDK\{{ app_name }}\Models\{{ route.singular }}Model', get_class($element));
$this->assertEquals(1, count($response));
{% for key, value in route.example %}
{% if value %}
$this->assertEquals($toFind->get{{ key }}(), $element->get{{ key }}());
{% endif %}
{% endfor %}
return $response;
}
/**
* @vcr unittest_{{ pack_name|lower }}_list.cassette
**/
public function test{{ route.function|capitalize }}OrderBy()
{
$responseAsc = $this->client->{{ scope_name }}->{{ route.function }}(
Filter::Factory()->setOrder('Id', 'ASC')
);
$responseDsc = $this->client->{{ scope_name }}->{{ route.function }}(
Filter::Factory()->setOrder('Id', 'DESC')
);
$responseAscIds = [];
foreach($responseAsc as $item){
$responseAscIds[] = $item->getId();
}
$responseDscIds = [];
foreach($responseDsc as $item){
$responseDscIds[] = $item->getId();
}
//\Kint::dump($responseAscIds, $responseDscIds);
$this->assertEquals(array_reverse($responseAscIds), $responseDscIds);
}

View file

@ -1,42 +0,0 @@
<?php
{% set priorities = [ "create", "get", "list", "delete" ] %}
namespace {{ app_namespace }}\SDK\{{ app_name }}\Test\AccessLayer;
use PHPUnit\Framework\TestCase;
use {{ app_namespace }}\SDK\{{ app_name }}\AccessLayer\{{ pack_name }}AccessLayer;
use {{ app_namespace }}\SDK\{{ app_name }}\Client as SDKClient;
use {{ app_namespace }}\SDK\{{ app_name }}\Models;
use Gone\SDK\Common\Filters\Filter;
/**
* @group generated
* @group sdk
*/
class {{ pack_name }}Test extends TestCase{
/** @var SDKClient */
private $client;
public function setUp()
{
parent::setUp();
$this->client = new SDKClient();
if(isset($_ENV['API_HOST'])){
$this->client->setBaseUrl($_ENV['API_HOST']);
}
}
{% for order in priorities %}
{% for route in routes %}
{% if route.template == order %}
{% set test_file = "SDK/Tests/AccessLayer/" ~ "_test_" ~ order ~ ".php.twig" %}
{% include test_file %}
{% endif %}
{% endfor %}
{% endfor %}
{% for route in routes %}
{% if route.template not in priorities %}
{% set test_file = "SDK/Tests/AccessLayer/" ~ "_test_" ~ route.template ~ ".php.twig" %}
{% include test_file %}
{% endif %}
{% endfor %}
}

View file

@ -1,6 +0,0 @@
<?php
require_once("vendor/autoload.php");
ini_set('memory_limit', '3000M');
\VCR\VCR::configure()
->setStorage('json')
->setMode('new_episodes');

View file

@ -1,19 +0,0 @@
<?php
namespace {{ app_namespace }}\SDK\{{ app_name }};
use Gone\SDK\Common\Abstracts\AbstractClient;
class Client extends AbstractClient
{
{% for pack in packs|keys %}
/** @var AccessLayer\{{ pack }}AccessLayer */
public ${{ pack|transform_studly_to_camel }};
{% endfor %}
public function __construct($baseUrl = "{{ default_base_url }}"){
parent::__construct($baseUrl);
{% for pack in packs|keys %}
$this->{{ pack|transform_studly_to_camel }} = new AccessLayer\{{ pack }}AccessLayer($this);
{% endfor %}
}
}

View file

@ -1,34 +0,0 @@
{
"name": "{{ app_namespace|lower }}/lib{{ app_name|lower }}",
"authors": [
{
"name": "Matthew Baggett",
"email": "matthew@baggett.me"
}, {
"name": "Segura Systems",
"email": "systems@segura.co.uk"
}
],
"license": "proprietary",
"time": "{{ release_time }}",
"require": {
"gone.io/libcommon": "dev-master"
},
"require-dev": {
"kint-php/kint": "^2.0",
"fzaninotto/Faker": "^1.8",
"phpunit/phpunit": "^7.3",
"php-vcr/phpunit-testlistener-vcr": "^3.2"
},
"autoload": {
"files": ["bootstrap.php"],
"psr-4": {
"{{ app_namespace }}\\SDK\\{{ app_name }}\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"{{ app_namespace }}\\SDK\\{{ app_name }}\\Test\\": "tests/"
}
}
}

View file

@ -1,11 +0,0 @@
version: '2.3'
services:
lib{{ app_name|lower }}:
build:
context: .
dockerfile: Dockerfile.tests
volumes:
- ./:/app
network_mode: "host"

View file

@ -1,4 +0,0 @@
.idea
vendor
build
composer.lock

View file

@ -1,42 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php"
colors="true"
stopOnFailure="false"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true">
<php>
<ini name="memory_limit" value="128M"/>
</php>
<logging>
<log type="coverage-clover" target="build/clover.xml"/>
<log type="coverage-html" target="build/"/>
</logging>
<filter>
<whitelist>
<directory suffix=".php">./src</directory>
<exclude>
<directory>./vendor</directory>
<directory>./build</directory>
</exclude>
</whitelist>
</filter>
<listeners>
<listener class="VCR\PHPUnit\TestListener\VCRTestListener" file="vendor/php-vcr/phpunit-testlistener-vcr/src/VCRTestListener.php" />
</listeners>
<testsuites>
<testsuite name="access_layer">
{% for pack in packs|keys %}
<file>tests/AccessLayer/{{ pack }}Test.php</file>
{% endfor %}
</testsuite>
<testsuite name="custom">
<directory>tests/Custom</directory>
</testsuite>
</testsuites>
</phpunit>

View file

@ -1,60 +0,0 @@
# {{ app_name }}
## Installing
Firstly, it is likely that this library is in a private repository, so to install it into your application, you will
first need to add it to your composer.json's `Repositories` block. This should look something like this.
```JSON
...
"repositories": [
{
"type": "vcs",
"url": "git@github.com:goneio/Lib{{ app_name }}.git"
},
...
],
...
```
Then, simply either install it using `composer require gone.io/lib{{ app_name|lower }}`, or by adding the following block
to your composer.json:
```JSON
...
"require": {
"{{ app_namespace|lower }}/lib{{ app_name|lower }}": "version-here",
...
},
...
```
## Usage
{% for class, class_pack in packs|sort %}
### {{ class }}
```php
use \{{ app_namespace }}\SDK\{{ app_name }}\Client as SDKClient;
use \{{ app_namespace }}\SDK\{{ app_name }}\Models;
$sdkClient = new SDKClient();
// Listing all elements
$listOf{{ class }} = $sdkClient->{{ class|transform_studly_to_camel }}->list();
// Creating a new element
$new{{ class }} = Models\{{ class }}Model::factory()
{% for property, value in class_pack['create']['example'] %}
->set{{ property }}({{ var_export(value) }}){% if loop.last %};{% endif %}
{% endfor %}
// Storing that new element
$stored{{ class }} = $sdkClient->{{ class|transform_studly_to_camel }}->createFromObject($new{{ class }});
// Getting a specific element by ID
$fetched{{ class }} = $sdkClient->{{ class|transform_studly_to_camel }}->get($new{{ class }}->getId());
// Deleting that element
$sdkClient->{{ class|transform_studly_to_camel }}->delete($fetched{{ class }}->getId());
```
{% endfor %}