separated JavaScript and TypeScript export,
added AGENTS.md for AI bot
This commit is contained in:
@ -39,6 +39,9 @@ class APIlite
|
||||
if (in_array('--html', $switches)) {
|
||||
$format = 'html';
|
||||
}
|
||||
if (in_array('--javascript', $switches) || in_array('--js', $switches)) {
|
||||
$format = 'javascript';
|
||||
}
|
||||
if (in_array('--typescript', $switches)) {
|
||||
$format = 'typescript';
|
||||
}
|
||||
@ -47,6 +50,10 @@ class APIlite
|
||||
case 'html':
|
||||
$this->printHelpHTML();
|
||||
break;
|
||||
case 'javascript':
|
||||
case 'js':
|
||||
$this->printHelpJavascript();
|
||||
break;
|
||||
case 'typescript':
|
||||
$this->printHelpTypescript();
|
||||
break;
|
||||
@ -189,6 +196,7 @@ class APIlite
|
||||
$this->response(array(
|
||||
'name' => $this->apiName,
|
||||
'html_version' => $this->getCurrentUrl().'?format=html',
|
||||
'javascript_version' => $this->getCurrentUrl().'?format=javascript',
|
||||
'typescript_version' => $this->getCurrentUrl().'?format=typescript',
|
||||
'actions' => $this->methods
|
||||
));
|
||||
@ -199,20 +207,36 @@ class APIlite
|
||||
include __DIR__ . '/help.tpl.php';
|
||||
}
|
||||
|
||||
private function printHelpTypescript(): void
|
||||
private function printHelpJavascript(): void
|
||||
{
|
||||
ob_clean();
|
||||
header('Content-Type: application/javascript');
|
||||
header('Content-Disposition: attachment; filename="' . $this->apiName . '.js"');
|
||||
include __DIR__ . '/javascript.tpl.php';
|
||||
}
|
||||
|
||||
private function printHelpTypescript(): void
|
||||
{
|
||||
ob_clean();
|
||||
header('Content-Type: application/typescript');
|
||||
header('Content-Disposition: attachment; filename="' . $this->apiName . '.ts"');
|
||||
include __DIR__ . '/typescript.tpl.php';
|
||||
}
|
||||
|
||||
private function getCurrentUrl(): string {
|
||||
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ||
|
||||
$_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
|
||||
$host = $_SERVER['HTTP_HOST'];
|
||||
$uri = $_SERVER['REQUEST_URI'];
|
||||
$https = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off';
|
||||
$serverPort = isset($_SERVER['SERVER_PORT']) ? (int) $_SERVER['SERVER_PORT'] : null;
|
||||
$protocol = ($https || $serverPort === 443) ? 'https://' : 'http://';
|
||||
$host = $_SERVER['HTTP_HOST'] ?? 'localhost';
|
||||
$uri = $_SERVER['REQUEST_URI'] ?? ($_SERVER['SCRIPT_NAME'] ?? '/');
|
||||
$path = parse_url($uri, PHP_URL_PATH);
|
||||
if (!is_string($path) || $path === '') {
|
||||
$path = '/';
|
||||
}
|
||||
$path = str_replace('\\', '/', $path);
|
||||
if (substr($path, 0, 1) !== '/') {
|
||||
$path = '/' . ltrim($path, '/');
|
||||
}
|
||||
return $protocol . $host . $path;
|
||||
}
|
||||
|
||||
|
||||
@ -396,6 +396,7 @@
|
||||
<nav class="nav-menu">
|
||||
<div class="nav-links">
|
||||
<a href="<?php echo $this->getCurrentUrl(); ?>?format=json">🔗 JSON Documentation</a>
|
||||
<a href="<?php echo $this->getCurrentUrl(); ?>?format=javascript">📄 JavaScript backend script</a>
|
||||
<a href="<?php echo $this->getCurrentUrl(); ?>?format=typescript">📄 TypeScript backend script</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
69
src/javascript.tpl.php
Normal file
69
src/javascript.tpl.php
Normal file
@ -0,0 +1,69 @@
|
||||
/**
|
||||
* Generated by APIlite
|
||||
* https://gitea.tpsoft.org/TPsoft.org/APIlite
|
||||
*
|
||||
* <?php echo date('Y-m-d H:i:s'); ?>
|
||||
*/
|
||||
|
||||
class <?php echo $this->apiName; ?> {
|
||||
endpoint = <?php echo sprintf(substr($this->endpoint, 0, 4) == 'http' ? '"%s"' : '%s', $this->endpoint); ?>;
|
||||
|
||||
/* ----------------------------------------------------
|
||||
* 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', 'msg': 'HTTP STATUS ' + this.status});
|
||||
}
|
||||
}
|
||||
}
|
||||
var form_data = new FormData();
|
||||
Object.keys(data).forEach(key => {
|
||||
let val = data[key];
|
||||
if (typeof val === 'undefined') return;
|
||||
if (typeof val == 'object') val = JSON.stringify(val);
|
||||
form_data.append(key, val);
|
||||
});
|
||||
xhttp.open('POST', this.endpoint + '?action=' + method);
|
||||
xhttp.send(form_data);
|
||||
}
|
||||
|
||||
callPromise(method, data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.call(method, data, function(response) {
|
||||
if (method === '__HELP__') {
|
||||
resolve(response);
|
||||
return;
|
||||
}
|
||||
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";
|
||||
}
|
||||
?>
|
||||
|
||||
};
|
||||
|
||||
export default new <?php echo $this->apiName; ?>();
|
||||
@ -1,3 +1,39 @@
|
||||
<?php
|
||||
$mapType = function (?string $type): string {
|
||||
if (!is_string($type) || $type === '') {
|
||||
return 'unknown';
|
||||
}
|
||||
|
||||
$type = strtolower(ltrim($type, '\\'));
|
||||
|
||||
return match ($type) {
|
||||
'int', 'integer', 'float', 'double' => 'number',
|
||||
'string' => 'string',
|
||||
'bool', 'boolean' => 'boolean',
|
||||
'array', 'iterable' => 'unknown[]',
|
||||
'object', 'stdclass' => 'Record<string, unknown>',
|
||||
'mixed', 'resource' => 'unknown',
|
||||
'null', 'void' => 'null',
|
||||
'scalar' => 'string | number | boolean',
|
||||
'callable', 'closure' => '(...args: unknown[]) => unknown',
|
||||
'never' => 'never',
|
||||
default => 'unknown',
|
||||
};
|
||||
};
|
||||
|
||||
$mapUnionType = function (mixed $type) use ($mapType): string {
|
||||
if (is_array($type)) {
|
||||
$parts = array();
|
||||
foreach ($type as $singleType) {
|
||||
$parts[] = $mapType(is_string($singleType) ? $singleType : null);
|
||||
}
|
||||
$parts = array_values(array_unique($parts));
|
||||
return empty($parts) ? 'unknown' : implode(' | ', $parts);
|
||||
}
|
||||
|
||||
return $mapType(is_string($type) ? $type : null);
|
||||
};
|
||||
?>
|
||||
/**
|
||||
* Generated by APIlite
|
||||
* https://gitea.tpsoft.org/TPsoft.org/APIlite
|
||||
@ -5,64 +41,117 @@
|
||||
* <?php echo date('Y-m-d H:i:s'); ?>
|
||||
*/
|
||||
|
||||
class <?php echo $this->apiName; ?> {
|
||||
endpoint = <?php echo sprintf(substr($this->endpoint, 0, 4) == 'http' ? '"%s"' : '%s', $this->endpoint); ?>;
|
||||
export interface APIliteActionResponse<T> {
|
||||
status: 'OK';
|
||||
data: T;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------
|
||||
* General API call
|
||||
*/
|
||||
call(method, data, callback) {
|
||||
var xhttp = new XMLHttpRequest();
|
||||
export interface APIliteErrorResponse {
|
||||
status: 'ERROR';
|
||||
msg: string;
|
||||
}
|
||||
|
||||
export interface APIliteMethodParam {
|
||||
name: string;
|
||||
type: string | null;
|
||||
optional: boolean;
|
||||
default: unknown;
|
||||
doc: string | null;
|
||||
}
|
||||
|
||||
export interface APIliteMethodDoc {
|
||||
name: string;
|
||||
doc: string | null;
|
||||
description: string | null;
|
||||
params: APIliteMethodParam[];
|
||||
return: string | string[] | null;
|
||||
}
|
||||
|
||||
export interface APIliteHelpResponse {
|
||||
name: string;
|
||||
html_version: string;
|
||||
javascript_version: string;
|
||||
typescript_version: string;
|
||||
actions: APIliteMethodDoc[];
|
||||
}
|
||||
|
||||
class <?php echo $this->apiName; ?> {
|
||||
endpoint: string = <?php echo sprintf(substr($this->endpoint, 0, 4) == 'http' ? '"%s"' : '%s', $this->endpoint); ?>;
|
||||
|
||||
private call(
|
||||
method: string,
|
||||
data: Record<string, unknown>,
|
||||
callback: (response: APIliteHelpResponse | APIliteActionResponse<unknown> | APIliteErrorResponse) => void
|
||||
): void {
|
||||
const 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));
|
||||
if (this.readyState === 4) {
|
||||
if (this.status === 200) {
|
||||
const response = JSON.parse(this.responseText) as APIliteHelpResponse | APIliteActionResponse<unknown> | APIliteErrorResponse;
|
||||
callback(response);
|
||||
} else {
|
||||
if (callback != null) callback({'status': 'ERROR', 'message': 'HTTP STATUS ' + this.status});
|
||||
callback({ status: 'ERROR', msg: '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);
|
||||
};
|
||||
|
||||
const formData = new FormData();
|
||||
Object.keys(data).forEach((key) => {
|
||||
const rawValue = data[key];
|
||||
if (typeof rawValue === 'undefined') {
|
||||
return;
|
||||
}
|
||||
let value: string | Blob;
|
||||
if (rawValue instanceof Blob) {
|
||||
value = rawValue;
|
||||
} else if (typeof rawValue === 'object' && rawValue !== null) {
|
||||
value = JSON.stringify(rawValue);
|
||||
} else {
|
||||
value = String(rawValue);
|
||||
}
|
||||
formData.append(key, value);
|
||||
});
|
||||
|
||||
xhttp.open('POST', this.endpoint + '?action=' + method);
|
||||
xhttp.send(form_data);
|
||||
xhttp.send(formData);
|
||||
}
|
||||
|
||||
callPromise(method, data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.call(method, data, function(response) {
|
||||
if (method == '__HELP__') {
|
||||
resolve(response);
|
||||
private callPromise<T>(method: string, data: Record<string, unknown>): Promise<T> {
|
||||
return new Promise<T>((resolve, reject) => {
|
||||
this.call(method, data, (response) => {
|
||||
if (method === '__HELP__') {
|
||||
resolve(response as T);
|
||||
return;
|
||||
}
|
||||
if (response.status == 'OK') {
|
||||
resolve(response.data);
|
||||
} else {
|
||||
reject(response.msg);
|
||||
if (response.status === 'OK') {
|
||||
resolve(response.data as T);
|
||||
return;
|
||||
}
|
||||
reject(response.msg);
|
||||
});
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------
|
||||
* API actions
|
||||
*/
|
||||
help() {
|
||||
return this.callPromise('__HELP__', {});
|
||||
help(): Promise<APIliteHelpResponse> {
|
||||
return this.callPromise<APIliteHelpResponse>('__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";
|
||||
$paramsSignature = array();
|
||||
$paramsPayload = array();
|
||||
foreach ($method['params'] as $param) {
|
||||
$paramType = $mapType($param['type']);
|
||||
$paramsSignature[] = $param['name'] . ($param['optional'] ? '?' : '') . ': ' . $paramType;
|
||||
$paramsPayload[] = $param['name'];
|
||||
}
|
||||
$returnType = $mapUnionType($method['return']);
|
||||
?>
|
||||
<?php echo $method['name']; ?>(<?php echo implode(', ', $paramsSignature); ?>): Promise<APIliteActionResponse<<?php echo $returnType; ?>>> {
|
||||
return this.callPromise<APIliteActionResponse<<?php echo $returnType; ?>>>('<?php echo $method['name']; ?>', { <?php echo implode(', ', $paramsPayload); ?> });
|
||||
}
|
||||
|
||||
};
|
||||
<?php } ?>
|
||||
}
|
||||
|
||||
export default new <?php echo $this->apiName; ?>();
|
||||
|
||||
Reference in New Issue
Block a user