-
Notifications
You must be signed in to change notification settings - Fork 0
generated_output
The tool produces up to eight files, each enabled and located independently in config.json.
All files carry a // auto-generated, DO NOT EDIT header.
One GML constructor function per OpenAPI #/components/schemas object, plus a paired
_validate() function.
/**
* @func GmApplicationConfiguration(_name, _type, _parent, _id = undefined, _description = undefined)
* @param {String} _name The application-configuration specific unique ID.
* @param {String} _type The fully-qualified Java type of ApplicationConfiguration.
* @param {Struct.GmApplication} _parent
* @param {String} [_id] The database assigned ID for the application configuration.
* @param {String} [_description]
*/
function GmApplicationConfiguration(_name, _type, _parent, _id = undefined, _description = undefined) constructor
{
name = _name;
type = _type;
parent = _parent;
id = _id;
description = _description;
}Note that the member keeps the name the spec used (parent, and userId for a spec field
userId), while the constructor argument is snake_cased with a leading underscore (_parent,
_user_id). See Naming Conventions.
Each schema also gets a standalone validator:
function GmApplicationConfiguration_validate(__inst__, __where__ = _GMFUNCTION_)
{
__where__ = $"{__where__} :: GmApplicationConfiguration_validate";
if (!is_struct(__inst__)) throw $"{__where__} :: expected Struct.GmApplicationConfiguration";
if (!is_string(__inst__[$ "name"])) throw $"{__where__} :: 'name' expected String";
if (!is_string(__inst__[$ "type"])) throw $"{__where__} :: 'type' expected String";
GmApplication_validate(__inst__[$ "parent"], $"{__where__} :: 'parent'");
if (!is_undefined(__inst__[$ "id"]))
{
if (!is_string(__inst__[$ "id"])) throw $"{__where__} :: 'id' expected String";
}
if (!is_undefined(__inst__[$ "description"]))
{
if (!is_string(__inst__[$ "description"])) throw $"{__where__} :: 'description' expected String";
}
}Required fields are always checked; optional ones only when defined. A nested schema is validated by calling its own validator, with the field name folded into the location string so a failure deep in a tree still says which field it was:
… :: GmCreateLargeObjectRequest_validate :: 'read' :: GmSubjectRequest_validate :: expected Struct.GmSubjectRequest
Validators
throwa plain string, not an exception struct. In acatchblock useis_struct(_e) ? _e.message : string(_e)— reading_e.messagedirectly will itself fail.
Schema mapping rules:
| OpenAPI type | GML type |
|---|---|
string |
String |
integer (int32 / int64) |
Real |
number (float / double) |
Real |
boolean |
Bool |
string with format: binary / byte
|
Id.Buffer |
array of T |
Array<T> |
object with named properties |
named struct constructor |
object free-form / inline |
Struct (any-map) |
string with enum
|
String, with a switch over the literals in the validator |
oneOf / anyOf are validated but not emitted as distinct GML union types: the validator tries
each option and counts the successes (oneOf requires exactly one, anyOf at least one). allOf
is not flattened — the constituent schemas are validated in turn, but no merged constructor is
generated for the composition.
One public function per OpenAPI operation.
/**
* @func gm_get_application(_name_or_id, _callback = undefined)
* Gets the metadata for a single application.
* @param {String} _name_or_id
* @param {Function} [_callback] Callback with signature (status, data, request).
*/
function gm_get_application(_name_or_id, _callback = undefined)
{
var __base_url__ = _gm_options_get_rest_url();
// argument validation
var __where__ = _GMFUNCTION_;
if (!is_string(_name_or_id)) throw $"{__where__} :: 'nameOrId' expected String";
if (!is_undefined(_callback))
{
if (!is_callable(_callback)) throw $"{__where__} :: '_callback' expected Function";
}
// build url path
var __url__ = $"{__base_url__}/application/{_gm_url_encode(_name_or_id)}";
var __security__ = [ "auth_bearer", "session_secret" ];
return _gm_create_request(__url__, undefined, "GET", undefined, undefined, undefined, __security__, undefined, _callback, _GMFUNCTION_);
}Parameter ordering: required parameters come first, then optional ones (defaulting to
undefined unless the spec provides a default value), then _body, then _content_type if the
body allows several media types, then _callback.
Parameter locations:
| Location | Handling |
|---|---|
path |
URL-encoded and interpolated into the URL string |
query |
Collected into a params struct; undefined entries are skipped |
header |
Collected into a headers struct, written into the request header map in GmRequest.send()
|
cookie |
Not a function argument — the cookie jar handles these; see Authentication & Cookies |
Request body:
When an endpoint has a body, a _body parameter is added. If the spec allows multiple
content-types, a _content_type parameter is also added (defaulting to the first supported type).
Callback signature:
function(_status, _data, _request)
// _status {Real} HTTP status code
// _data {Struct|Any} Parsed JSON response (json_parse attempted; raw string on failure)
// _request {Struct.GmRequest} The request object (supports .retry())Internal plumbing used by the generated endpoint functions. Contains:
function _gm_get_singleton(__where__) { ... }Creates obj_gm_core on first call via instance_create_depth(0, 0, 0, obj_gm_core).
All state (tokens, jar, requests, hooks) lives on this instance. You do not need to place one in
a room — see Getting Started.
gm_request_auth_set_token(_token_id, _token) // store (public — call this from game code)
_gm_request_auth_get_token(_token_id) // retrieve (private — used internally)gm_request_body_set_converter(_content_type, _function) // register (public)
_gm_request_body_get_converter(_content_type) // retrieve (private — used internally)gm_request_response_set_hook(_code, _hook) // register (public — call this from game code)
_gm_request_response_get_hook(_code) // retrieve (private — used internally)gm_cookie_set(_name, _value) // manual write
gm_cookie_get(_name) // manual read
gm_cookie_delete(_name) // remove one
gm_cookie_clear() // wipe jar_gm_url_encode(_value) // percent-encodes a value for a path segment or query stringThe internal request wrapper. Created by _gm_create_request() and stored in the
singleton's requests ds_map until the Async HTTP event resolves it.
function GmRequest(_url, _params, _method, _headers, _body, _content_type, _security, _cookies, _callback, __where__) constructor
// Public API:
request.send() // fire (or re-fire) the HTTP request → returns request id
request.retry() // alias for send()
request.get_callback() // return the stored callback function
request.attempts // integer, increments on each send/retry_gm_create_request() takes the same ten arguments and returns request.send() directly, which is
what every generated endpoint returns.
Initialises the singleton's state:
type_converters = {};
type_converters[$ "*/*"] = function(__body__) { return __body__; };
type_converters[$ "application/json"] = function(__body__) { return json_stringify(__body__, false, ...); };
type_converters[$ "application/x-www-form-urlencoded"] = function(__body__) { return __body__; };
type_converters[$ "text/plain"] = function(__body__) { return string(__body__); };
type_converters[$ "multipart/form-data"] = function(__body__, __header__) { ... };
auth_tokens = {}; // scheme name → token string
cookie_jar = {}; // cookie name → value
requests = ds_map_create(); // request id → GmRequest
response_hooks = ds_map_create(); // HTTP status code → hook functionThe application/json converter uses a replacer to strip undefined struct fields
before stringifying, so optional unset parameters are omitted from the JSON payload.
The multipart/form-data converter iterates struct fields and builds a MIME multipart body, setting
the Content-Type boundary automatically. A field is treated as binary when it is a live buffer
(is_handle(v) && buffer_exists(v)); everything else is written as a text part.
Two known limitations of the multipart converter. Binary fields are base64-encoded with
Content-Transfer-Encoding: base64rather than written as raw bytes, which many servers ignore. And a struct-valued field is interpolated with GML's debug formatting rather than serialised as JSON. Both are open items.
var __async_id__ = async_load[? "id"];
var __request__ = requests[? __async_id__];
if (is_undefined(__request__)) {
exit;
}
var __status__ = async_load[? "status"];
// status 1 means "in progress" — wait for the terminal event.
if (__status__ == 1) exit;
if (_gm_options_is_debug()) {
// async_load is a ds_map, which json_stringify cannot serialise.
show_debug_message("HTTP: " + json_encode(async_load));
}
var __code__ = async_load[? "http_status"];
var __data__ = async_load[? "result"];
// response_headers is a ds_map, not a struct.
var __headers__ = async_load[? "response_headers"];
if (!is_undefined(__headers__) && ds_exists(__headers__, ds_type_map)) {
var __set_cookie__ = string_trim(__headers__[? "Set-Cookie"] ?? "");
if (string_length(__set_cookie__) > 0) {
_gm_cookie_capture(__set_cookie__);
}
}
try {
__data__ = json_parse(__data__);
}
catch (__ex__) { /* body is not JSON; hand it back untouched */ };
var __hook__ = response_hooks[? __code__];
if (is_callable(__hook__) && __hook__(__code__, __data__, __request__) == true) {
ds_map_delete(requests, __async_id__);
exit;
}
var __callback__ = __request__.get_callback();
if (is_callable(__callback__)) {
__callback__(__code__, __data__, __request__);
}
ds_map_delete(requests, __async_id__);ds_map_destroy(requests);
ds_map_destroy(response_hooks);gm-ext-format documentation stubs consumed by the gm-ext updateDocs pipeline. Enable them with
docs.schemas and docs.functions in config.json — they are off by default.
schemas_codegen.js uses @struct_partial / @struct_end blocks and documents the struct's
members:
/**
* @struct_partial GmAdvancedInventoryItemQuantityAdjustment
* @member {String} userId The User whose inventory to modify.
* @member {Real} quantityDelta The delta to be applied to the inventory item quantity
* @member {Real} [priority] The priority slot for the item.
* @struct_end
*/
function_codegen.js uses @func_partial / @func_end blocks with @event callback members for
the callback signature, and documents the endpoint's arguments with @param.
Do not hand-edit these files — regenerate them whenever the spec changes.
Hooks intercept responses before the per-request callback fires. Return true to consume
the event and suppress the callback:
// Automatically refresh token on 401 and retry
gm_request_response_set_hook(401, function(_code, _data, _request) {
_refresh_my_token();
_request.retry();
return true; // suppress original callback
});Register a converter for a content-type not covered by the defaults:
gm_request_body_set_converter("application/xml", function(_body, _header) {
// return a string or a buffer
return my_xml_encode(_body);
});The converter receives the body value and the ds_map header so it can set (or override)
Content-Type — for example the built-in multipart/form-data converter appends the
boundary to the header value.
_<prefix>_request_body_get_converter resolves in two steps:
- an exact match on the content-type string;
- failing that, any
+jsonsubtype falls back to theapplication/jsonconverter.
So application/merge-patch+json, application/hal+json and application/problem+json serialise as
JSON without needing registration — while still going out under their own Content-Type, because
that is what the server dispatches on. Registering one explicitly still wins, so a single subtype can
be given custom handling.
Media types are matched literally: parameters are not understood.
application/json; charset=utf-8will not resolve, and a body declared only under that type is dropped at generation time with a warning. Declare the bare type in the spec. This is deliberate rather than an oversight — stripping parameters generally would also stripmultipart/form-data; boundary=…, where the parameter carries real meaning.
GameMaker