added generator for TypeScript backend

This commit is contained in:
Igor Miňo 2025-05-28 13:05:09 +02:00
parent 9f1c5536ed
commit ab7bd57362
3 changed files with 96 additions and 2 deletions

View File

@ -29,6 +29,8 @@ class APIlite
} else { } else {
if (isset($_REQUEST['format']) && $_REQUEST['format'] == 'html') { if (isset($_REQUEST['format']) && $_REQUEST['format'] == 'html') {
$this->printHelpHTML(); $this->printHelpHTML();
} elseif (isset($_REQUEST['format']) && $_REQUEST['format'] == 'typescript') {
$this->printHelpTypescript();
} else { } else {
$this->printHelpJSON(); $this->printHelpJSON();
} }
@ -148,6 +150,7 @@ class APIlite
$this->response(array( $this->response(array(
'name' => $this->apiName, 'name' => $this->apiName,
'html_version' => $this->getCurrentUrl().'?format=html', 'html_version' => $this->getCurrentUrl().'?format=html',
'typescript_version' => $this->getCurrentUrl().'?format=typescript',
'actions' => $this->methods 'actions' => $this->methods
)); ));
} }
@ -157,6 +160,14 @@ class APIlite
include __DIR__ . '/help.tpl.php'; include __DIR__ . '/help.tpl.php';
} }
private function printHelpTypescript(): void
{
ob_clean();
header('Content-Type: application/javascript');
header('Content-Disposition: attachment; filename="' . $this->apiName . '.js"');
include __DIR__ . '/typescript.tpl.php';
}
private function getCurrentUrl(): string { private function getCurrentUrl(): string {
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ||
$_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://"; $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
@ -178,6 +189,10 @@ class APIlite
private function doAction(string $action): void private function doAction(string $action): void
{ {
if ($action == '__HELP__') {
$this->printHelpJSON();
return;
}
$method = $this->getMethod($action); $method = $this->getMethod($action);
if (is_null($method)) { if (is_null($method)) {
$this->responseERROR('Action "' . $action . '" not found'); $this->responseERROR('Action "' . $action . '" not found');

View File

@ -182,6 +182,14 @@
margin-left: 0.5rem; margin-left: 0.5rem;
} }
/* Footer */
.footer {
background-color: #F4F5F8;
padding: 2rem 0;
text-align: center;
margin-top: 3rem;
}
/* Responsive design */ /* Responsive design */
@media (max-width: 768px) { @media (max-width: 768px) {
.container { .container {
@ -253,8 +261,8 @@
<!-- Navigation Menu --> <!-- Navigation Menu -->
<nav class="nav-menu"> <nav class="nav-menu">
<div class="nav-links"> <div class="nav-links">
<a href="<?php echo $this->getCurrentUrl(); ?>?format=json">📄 JSON Documentation</a> <a href="<?php echo $this->getCurrentUrl(); ?>?format=json">🔗 JSON Documentation</a>
<a href="<?php echo $this->getCurrentUrl(); ?>">🔗 API Endpoint</a> <a href="<?php echo $this->getCurrentUrl(); ?>?format=typescript">📄 TypeScript backend script</a>
</div> </div>
</nav> </nav>
@ -303,6 +311,15 @@
</section> </section>
<?php } ?> <?php } ?>
</main> </main>
<!-- Footer -->
<footer class="footer">
<p>Generated with <a href="https://gitea.tpsoft.org/TPsoft.org/APIlite" target="_blank">APIlite</a>
by <a href="https://tpsoft.org" target="_blank">TPsoft.org</a>
&copy; <?php echo date('Y'); ?>
for <?php echo $this->apiName; ?>. All rights reserved.
</p>
</footer>
</div> </div>
</body> </body>

62
src/typescript.tpl.php Normal file
View File

@ -0,0 +1,62 @@
/**
* Generated by APIlite
* https://gitea.tpsoft.org/TPsoft.org/APIlite
*
* <?php echo date('Y-m-d H:i:s'); ?>
*/
export const backend = {
endpont: window.location.origin + "<?php echo $this->apiName; ?>.php",
/* ----------------------------------------------------
* General API call
*/
call(method, data, callback) {
var xhttp = new XMLHttpRequest();
xhttp.withCredentials = true;
xhttp.onreadystatechange = function() {
if (this.readyState == 4) {
if (this.status == 200) {
if (callback != null) callback(JSON.parse(this.responseText));
} else {
if (callback != null) callback({'status': 'ERROR', 'message': 'HTTP STATUS ' + this.status});
}
}
}
var form_data = new FormData();
Object.keys(data).forEach(key => {
let val = data[key];
if (typeof val == 'object') val = JSON.stringify(val);
form_data.append(key, val);
});
xhttp.open('POST', this.endpont + '?action=' + method);
xhttp.send(form_data);
},
callPromise(method, data) {
return new Promise((resolve, reject) => {
this.call(method, data, function(response) {
if (response.status == 'OK') {
resolve(response.data);
} else {
reject(response.msg);
}
});
})
},
/* ----------------------------------------------------
* API actions
*/
help() {
return this.callPromise('__HELP__', {});
},
<?php if (is_array($this->methods)) foreach ($this->methods as $method) {
echo "\t".$method['name'].'('.implode(', ', array_map(function($param) { return $param['name']; }, $method['params'])).') {';
echo "\n\t\treturn this.callPromise('".$method['name']."', {".implode(', ', array_map(function($param) { return $param['name'].': '.$param['name']; }, $method['params']))."});";
echo "\n\t},\n\n";
}
?>
};