@celerity-sdk/core 0.2.1 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -3
- package/dist/index.cjs +90 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -3
- package/dist/index.d.ts +33 -3
- package/dist/index.js +89 -8
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.d.cts
CHANGED
|
@@ -382,6 +382,25 @@ declare class GatewayTimeoutException extends HttpException {
|
|
|
382
382
|
constructor(message?: string, details?: unknown);
|
|
383
383
|
}
|
|
384
384
|
|
|
385
|
+
/**
|
|
386
|
+
* Resolve a handler ID as a module reference by dynamically importing
|
|
387
|
+
* the module and matching the exported function against the registry.
|
|
388
|
+
*
|
|
389
|
+
* Resolution strategy:
|
|
390
|
+
* 1. If the ID contains a dot, try splitting at the last dot into
|
|
391
|
+
* `moduleName.exportName` (named export).
|
|
392
|
+
* 2. Fallback: treat the full ID as a module name with a default export.
|
|
393
|
+
* This handles no-dot refs (e.g. "myModule") and dotted module names
|
|
394
|
+
* (e.g. "app.module" from app.module.js) where the named export split failed.
|
|
395
|
+
*
|
|
396
|
+
* Supported formats:
|
|
397
|
+
* - `"handlers.hello"` — named export `hello` from module `handlers`
|
|
398
|
+
* - `"handlers"` — default export from module `handlers`
|
|
399
|
+
* - `"app.module"` — dotted module name: tries named export split first,
|
|
400
|
+
* falls back to default export from module `app.module`
|
|
401
|
+
*/
|
|
402
|
+
declare function resolveHandlerByModuleRef(handlerId: string, registry: HandlerRegistry, baseDir: string): Promise<ResolvedHandler | null>;
|
|
403
|
+
|
|
385
404
|
declare const CONTROLLER_METADATA: unique symbol;
|
|
386
405
|
declare const HTTP_METHOD_METADATA: unique symbol;
|
|
387
406
|
declare const ROUTE_PATH_METADATA: unique symbol;
|
|
@@ -416,8 +435,19 @@ type RuntimeBootstrapResult = {
|
|
|
416
435
|
container: Container;
|
|
417
436
|
/** Create a runtime-compatible handler callback for a specific route. */
|
|
418
437
|
createRouteCallback(path: string, method: string): RuntimeCallback | null;
|
|
419
|
-
/**
|
|
420
|
-
|
|
438
|
+
/**
|
|
439
|
+
* Create a runtime-compatible handler callback by handler ID.
|
|
440
|
+
* First tries a direct registry lookup. If that fails, resolves the handler ID
|
|
441
|
+
* as a module reference by dynamically importing the module and matching the
|
|
442
|
+
* exported function against the registry.
|
|
443
|
+
*
|
|
444
|
+
* Supported formats:
|
|
445
|
+
* - `"handlers.hello"` — named export `hello` from module `handlers`
|
|
446
|
+
* - `"handlers"` — default export from module `handlers`
|
|
447
|
+
* - `"app.module"` — dotted module name: tries named export split first,
|
|
448
|
+
* falls back to default export from module `app.module`
|
|
449
|
+
*/
|
|
450
|
+
createRouteCallbackById(handlerId: string, codeLocation?: string): Promise<RuntimeCallback | null>;
|
|
421
451
|
};
|
|
422
452
|
/**
|
|
423
453
|
* Bootstrap the user's module and return an object with per-route callback creation.
|
|
@@ -435,4 +465,4 @@ type StartRuntimeOptions = {
|
|
|
435
465
|
*/
|
|
436
466
|
declare function startRuntime(options?: StartRuntimeOptions): Promise<void>;
|
|
437
467
|
|
|
438
|
-
export { APP_CONFIG, Action, Auth, BadGatewayException, BadRequestException, Body, type BootstrapResult, CONTROLLER_METADATA, CUSTOM_METADATA, CelerityApplication, CelerityFactory, ConflictException, Container, Controller, type ControllerMetadata, Cookies, type CreateOptions, Delete, ForbiddenException, GUARD_CUSTOM_METADATA, GUARD_PROTECTEDBY_METADATA, GatewayTimeoutException, Get, GoneException, Guard, HTTP_METHOD_METADATA, HandlerMetadataStore, HandlerRegistry, Head, Headers, HttpException, type HttpHandlerConfig, type HttpHandlerContext, type HttpHandlerRequest, INJECT_METADATA, Inject, Injectable, InternalServerErrorException, LAYER_METADATA, MODULE_METADATA, MethodNotAllowedException, type MockRequestOptions, Module, type ModuleGraph, type ModuleNode, NotAcceptableException, NotFoundException, NotImplementedException, Options, PUBLIC_METADATA, Param, type ParamMetadata, type ParamType, Patch, type PipelineOptions, Post, ProtectedBy, Public, Put, Query, ROUTE_PATH_METADATA, RUNTIME_APP, Req, RequestId, type ResolvedHandler, type RuntimeBootstrapResult, type ServerlessAdapter, ServerlessApplication, type ServerlessHandler, ServiceUnavailableException, SetMetadata, type StartRuntimeOptions, TestingApplication, TooManyRequestsException, UnauthorizedException, UnprocessableEntityException, UseLayer, UseLayers, type ValidationSchemas, bootstrap, bootstrapForRuntime, buildModuleGraph, createDefaultSystemLayers, createHttpHandler, discoverModule, disposeLayers, executeHandlerPipeline, flattenMultiValueRecord, getClassDependencyTokens, getProviderDependencyTokens, httpDelete, httpGet, httpPatch, httpPost, httpPut, mapRuntimeRequest, mapToRuntimeResponse, mockRequest, registerModuleGraph, runLayerPipeline, startRuntime, tokenToString, validate };
|
|
468
|
+
export { APP_CONFIG, Action, Auth, BadGatewayException, BadRequestException, Body, type BootstrapResult, CONTROLLER_METADATA, CUSTOM_METADATA, CelerityApplication, CelerityFactory, ConflictException, Container, Controller, type ControllerMetadata, Cookies, type CreateOptions, Delete, ForbiddenException, GUARD_CUSTOM_METADATA, GUARD_PROTECTEDBY_METADATA, GatewayTimeoutException, Get, GoneException, Guard, HTTP_METHOD_METADATA, HandlerMetadataStore, HandlerRegistry, Head, Headers, HttpException, type HttpHandlerConfig, type HttpHandlerContext, type HttpHandlerRequest, INJECT_METADATA, Inject, Injectable, InternalServerErrorException, LAYER_METADATA, MODULE_METADATA, MethodNotAllowedException, type MockRequestOptions, Module, type ModuleGraph, type ModuleNode, NotAcceptableException, NotFoundException, NotImplementedException, Options, PUBLIC_METADATA, Param, type ParamMetadata, type ParamType, Patch, type PipelineOptions, Post, ProtectedBy, Public, Put, Query, ROUTE_PATH_METADATA, RUNTIME_APP, Req, RequestId, type ResolvedHandler, type RuntimeBootstrapResult, type ServerlessAdapter, ServerlessApplication, type ServerlessHandler, ServiceUnavailableException, SetMetadata, type StartRuntimeOptions, TestingApplication, TooManyRequestsException, UnauthorizedException, UnprocessableEntityException, UseLayer, UseLayers, type ValidationSchemas, bootstrap, bootstrapForRuntime, buildModuleGraph, createDefaultSystemLayers, createHttpHandler, discoverModule, disposeLayers, executeHandlerPipeline, flattenMultiValueRecord, getClassDependencyTokens, getProviderDependencyTokens, httpDelete, httpGet, httpPatch, httpPost, httpPut, mapRuntimeRequest, mapToRuntimeResponse, mockRequest, registerModuleGraph, resolveHandlerByModuleRef, runLayerPipeline, startRuntime, tokenToString, validate };
|
package/dist/index.d.ts
CHANGED
|
@@ -382,6 +382,25 @@ declare class GatewayTimeoutException extends HttpException {
|
|
|
382
382
|
constructor(message?: string, details?: unknown);
|
|
383
383
|
}
|
|
384
384
|
|
|
385
|
+
/**
|
|
386
|
+
* Resolve a handler ID as a module reference by dynamically importing
|
|
387
|
+
* the module and matching the exported function against the registry.
|
|
388
|
+
*
|
|
389
|
+
* Resolution strategy:
|
|
390
|
+
* 1. If the ID contains a dot, try splitting at the last dot into
|
|
391
|
+
* `moduleName.exportName` (named export).
|
|
392
|
+
* 2. Fallback: treat the full ID as a module name with a default export.
|
|
393
|
+
* This handles no-dot refs (e.g. "myModule") and dotted module names
|
|
394
|
+
* (e.g. "app.module" from app.module.js) where the named export split failed.
|
|
395
|
+
*
|
|
396
|
+
* Supported formats:
|
|
397
|
+
* - `"handlers.hello"` — named export `hello` from module `handlers`
|
|
398
|
+
* - `"handlers"` — default export from module `handlers`
|
|
399
|
+
* - `"app.module"` — dotted module name: tries named export split first,
|
|
400
|
+
* falls back to default export from module `app.module`
|
|
401
|
+
*/
|
|
402
|
+
declare function resolveHandlerByModuleRef(handlerId: string, registry: HandlerRegistry, baseDir: string): Promise<ResolvedHandler | null>;
|
|
403
|
+
|
|
385
404
|
declare const CONTROLLER_METADATA: unique symbol;
|
|
386
405
|
declare const HTTP_METHOD_METADATA: unique symbol;
|
|
387
406
|
declare const ROUTE_PATH_METADATA: unique symbol;
|
|
@@ -416,8 +435,19 @@ type RuntimeBootstrapResult = {
|
|
|
416
435
|
container: Container;
|
|
417
436
|
/** Create a runtime-compatible handler callback for a specific route. */
|
|
418
437
|
createRouteCallback(path: string, method: string): RuntimeCallback | null;
|
|
419
|
-
/**
|
|
420
|
-
|
|
438
|
+
/**
|
|
439
|
+
* Create a runtime-compatible handler callback by handler ID.
|
|
440
|
+
* First tries a direct registry lookup. If that fails, resolves the handler ID
|
|
441
|
+
* as a module reference by dynamically importing the module and matching the
|
|
442
|
+
* exported function against the registry.
|
|
443
|
+
*
|
|
444
|
+
* Supported formats:
|
|
445
|
+
* - `"handlers.hello"` — named export `hello` from module `handlers`
|
|
446
|
+
* - `"handlers"` — default export from module `handlers`
|
|
447
|
+
* - `"app.module"` — dotted module name: tries named export split first,
|
|
448
|
+
* falls back to default export from module `app.module`
|
|
449
|
+
*/
|
|
450
|
+
createRouteCallbackById(handlerId: string, codeLocation?: string): Promise<RuntimeCallback | null>;
|
|
421
451
|
};
|
|
422
452
|
/**
|
|
423
453
|
* Bootstrap the user's module and return an object with per-route callback creation.
|
|
@@ -435,4 +465,4 @@ type StartRuntimeOptions = {
|
|
|
435
465
|
*/
|
|
436
466
|
declare function startRuntime(options?: StartRuntimeOptions): Promise<void>;
|
|
437
467
|
|
|
438
|
-
export { APP_CONFIG, Action, Auth, BadGatewayException, BadRequestException, Body, type BootstrapResult, CONTROLLER_METADATA, CUSTOM_METADATA, CelerityApplication, CelerityFactory, ConflictException, Container, Controller, type ControllerMetadata, Cookies, type CreateOptions, Delete, ForbiddenException, GUARD_CUSTOM_METADATA, GUARD_PROTECTEDBY_METADATA, GatewayTimeoutException, Get, GoneException, Guard, HTTP_METHOD_METADATA, HandlerMetadataStore, HandlerRegistry, Head, Headers, HttpException, type HttpHandlerConfig, type HttpHandlerContext, type HttpHandlerRequest, INJECT_METADATA, Inject, Injectable, InternalServerErrorException, LAYER_METADATA, MODULE_METADATA, MethodNotAllowedException, type MockRequestOptions, Module, type ModuleGraph, type ModuleNode, NotAcceptableException, NotFoundException, NotImplementedException, Options, PUBLIC_METADATA, Param, type ParamMetadata, type ParamType, Patch, type PipelineOptions, Post, ProtectedBy, Public, Put, Query, ROUTE_PATH_METADATA, RUNTIME_APP, Req, RequestId, type ResolvedHandler, type RuntimeBootstrapResult, type ServerlessAdapter, ServerlessApplication, type ServerlessHandler, ServiceUnavailableException, SetMetadata, type StartRuntimeOptions, TestingApplication, TooManyRequestsException, UnauthorizedException, UnprocessableEntityException, UseLayer, UseLayers, type ValidationSchemas, bootstrap, bootstrapForRuntime, buildModuleGraph, createDefaultSystemLayers, createHttpHandler, discoverModule, disposeLayers, executeHandlerPipeline, flattenMultiValueRecord, getClassDependencyTokens, getProviderDependencyTokens, httpDelete, httpGet, httpPatch, httpPost, httpPut, mapRuntimeRequest, mapToRuntimeResponse, mockRequest, registerModuleGraph, runLayerPipeline, startRuntime, tokenToString, validate };
|
|
468
|
+
export { APP_CONFIG, Action, Auth, BadGatewayException, BadRequestException, Body, type BootstrapResult, CONTROLLER_METADATA, CUSTOM_METADATA, CelerityApplication, CelerityFactory, ConflictException, Container, Controller, type ControllerMetadata, Cookies, type CreateOptions, Delete, ForbiddenException, GUARD_CUSTOM_METADATA, GUARD_PROTECTEDBY_METADATA, GatewayTimeoutException, Get, GoneException, Guard, HTTP_METHOD_METADATA, HandlerMetadataStore, HandlerRegistry, Head, Headers, HttpException, type HttpHandlerConfig, type HttpHandlerContext, type HttpHandlerRequest, INJECT_METADATA, Inject, Injectable, InternalServerErrorException, LAYER_METADATA, MODULE_METADATA, MethodNotAllowedException, type MockRequestOptions, Module, type ModuleGraph, type ModuleNode, NotAcceptableException, NotFoundException, NotImplementedException, Options, PUBLIC_METADATA, Param, type ParamMetadata, type ParamType, Patch, type PipelineOptions, Post, ProtectedBy, Public, Put, Query, ROUTE_PATH_METADATA, RUNTIME_APP, Req, RequestId, type ResolvedHandler, type RuntimeBootstrapResult, type ServerlessAdapter, ServerlessApplication, type ServerlessHandler, ServiceUnavailableException, SetMetadata, type StartRuntimeOptions, TestingApplication, TooManyRequestsException, UnauthorizedException, UnprocessableEntityException, UseLayer, UseLayers, type ValidationSchemas, bootstrap, bootstrapForRuntime, buildModuleGraph, createDefaultSystemLayers, createHttpHandler, discoverModule, disposeLayers, executeHandlerPipeline, flattenMultiValueRecord, getClassDependencyTokens, getProviderDependencyTokens, httpDelete, httpGet, httpPatch, httpPost, httpPut, mapRuntimeRequest, mapToRuntimeResponse, mockRequest, registerModuleGraph, resolveHandlerByModuleRef, runLayerPipeline, startRuntime, tokenToString, validate };
|
package/dist/index.js
CHANGED
|
@@ -1689,23 +1689,96 @@ function httpDelete(path, handlerOrOptions, maybeHandler) {
|
|
|
1689
1689
|
}
|
|
1690
1690
|
__name(httpDelete, "httpDelete");
|
|
1691
1691
|
|
|
1692
|
-
// src/
|
|
1692
|
+
// src/handlers/module-resolver.ts
|
|
1693
1693
|
import { resolve } from "path";
|
|
1694
1694
|
import createDebug9 from "debug";
|
|
1695
|
-
var debug9 = createDebug9("celerity:core:
|
|
1695
|
+
var debug9 = createDebug9("celerity:core:module-resolver");
|
|
1696
|
+
async function resolveHandlerByModuleRef(handlerId, registry, baseDir) {
|
|
1697
|
+
const lastDot = handlerId.lastIndexOf(".");
|
|
1698
|
+
if (lastDot > 0) {
|
|
1699
|
+
const moduleName = handlerId.slice(0, lastDot);
|
|
1700
|
+
const exportName = handlerId.slice(lastDot + 1);
|
|
1701
|
+
const result = await tryResolveExport(baseDir, moduleName, exportName, handlerId, registry);
|
|
1702
|
+
if (result) return result;
|
|
1703
|
+
}
|
|
1704
|
+
return tryResolveExport(baseDir, handlerId, "default", handlerId, registry);
|
|
1705
|
+
}
|
|
1706
|
+
__name(resolveHandlerByModuleRef, "resolveHandlerByModuleRef");
|
|
1707
|
+
async function tryResolveExport(baseDir, moduleName, exportName, handlerId, registry) {
|
|
1708
|
+
const handlerModulePath = resolve(baseDir, moduleName);
|
|
1709
|
+
let mod;
|
|
1710
|
+
try {
|
|
1711
|
+
mod = await import(handlerModulePath);
|
|
1712
|
+
} catch {
|
|
1713
|
+
try {
|
|
1714
|
+
mod = await import(`${handlerModulePath}.js`);
|
|
1715
|
+
} catch {
|
|
1716
|
+
return null;
|
|
1717
|
+
}
|
|
1718
|
+
}
|
|
1719
|
+
const exported = mod[exportName];
|
|
1720
|
+
if (!exported) return null;
|
|
1721
|
+
const isFnDef = typeof exported === "object" && exported !== null && exported.__celerity_handler;
|
|
1722
|
+
const handlerFn = isFnDef ? exported.handler : exported;
|
|
1723
|
+
if (typeof handlerFn !== "function") return null;
|
|
1724
|
+
const match = registry.getAllHandlers().find((h) => h.handlerFn === handlerFn);
|
|
1725
|
+
if (match) {
|
|
1726
|
+
match.id = handlerId;
|
|
1727
|
+
debug9("matched '%s' to registry handler", handlerId);
|
|
1728
|
+
return match;
|
|
1729
|
+
}
|
|
1730
|
+
debug9("'%s' not in registry, wrapping directly", handlerId);
|
|
1731
|
+
return buildResolvedFromExport(handlerId, handlerFn, isFnDef ? exported : null);
|
|
1732
|
+
}
|
|
1733
|
+
__name(tryResolveExport, "tryResolveExport");
|
|
1734
|
+
function buildResolvedFromExport(handlerId, handlerFn, fnDef) {
|
|
1735
|
+
if (fnDef) {
|
|
1736
|
+
const meta = fnDef.metadata;
|
|
1737
|
+
return {
|
|
1738
|
+
id: handlerId,
|
|
1739
|
+
protectedBy: [],
|
|
1740
|
+
layers: [
|
|
1741
|
+
...meta.layers ?? []
|
|
1742
|
+
],
|
|
1743
|
+
isPublic: false,
|
|
1744
|
+
paramMetadata: [],
|
|
1745
|
+
customMetadata: meta.customMetadata ?? {},
|
|
1746
|
+
handlerFn,
|
|
1747
|
+
isFunctionHandler: true,
|
|
1748
|
+
injectTokens: meta.inject ?? []
|
|
1749
|
+
};
|
|
1750
|
+
}
|
|
1751
|
+
return {
|
|
1752
|
+
id: handlerId,
|
|
1753
|
+
protectedBy: [],
|
|
1754
|
+
layers: [],
|
|
1755
|
+
isPublic: false,
|
|
1756
|
+
paramMetadata: [],
|
|
1757
|
+
customMetadata: {},
|
|
1758
|
+
handlerFn,
|
|
1759
|
+
isFunctionHandler: true,
|
|
1760
|
+
injectTokens: []
|
|
1761
|
+
};
|
|
1762
|
+
}
|
|
1763
|
+
__name(buildResolvedFromExport, "buildResolvedFromExport");
|
|
1764
|
+
|
|
1765
|
+
// src/bootstrap/discovery.ts
|
|
1766
|
+
import { resolve as resolve2 } from "path";
|
|
1767
|
+
import createDebug10 from "debug";
|
|
1768
|
+
var debug10 = createDebug10("celerity:core:bootstrap");
|
|
1696
1769
|
async function discoverModule(modulePath) {
|
|
1697
1770
|
const resolved = modulePath ?? process.env.CELERITY_MODULE_PATH;
|
|
1698
1771
|
if (!resolved) {
|
|
1699
1772
|
throw new Error("Cannot discover module: set CELERITY_MODULE_PATH environment variable or pass modulePath");
|
|
1700
1773
|
}
|
|
1701
|
-
const absolutePath =
|
|
1702
|
-
|
|
1774
|
+
const absolutePath = resolve2(resolved);
|
|
1775
|
+
debug10("discoverModule: importing %s", absolutePath);
|
|
1703
1776
|
const imported = await import(absolutePath);
|
|
1704
1777
|
const rootModule = imported.default ?? findModuleExport(imported);
|
|
1705
1778
|
if (!rootModule || typeof rootModule !== "function") {
|
|
1706
1779
|
throw new Error(`No module class found in "${resolved}"`);
|
|
1707
1780
|
}
|
|
1708
|
-
|
|
1781
|
+
debug10("discoverModule: found %s", rootModule.name);
|
|
1709
1782
|
return rootModule;
|
|
1710
1783
|
}
|
|
1711
1784
|
__name(discoverModule, "discoverModule");
|
|
@@ -1761,8 +1834,11 @@ function mapToRuntimeResponse(response) {
|
|
|
1761
1834
|
__name(mapToRuntimeResponse, "mapToRuntimeResponse");
|
|
1762
1835
|
|
|
1763
1836
|
// src/bootstrap/runtime-entry.ts
|
|
1837
|
+
import { resolve as resolve3, dirname } from "path";
|
|
1764
1838
|
async function bootstrapForRuntime(modulePath, systemLayers) {
|
|
1765
1839
|
const layers = systemLayers ?? await createDefaultSystemLayers();
|
|
1840
|
+
const resolvedModulePath = modulePath ?? process.env.CELERITY_MODULE_PATH;
|
|
1841
|
+
const moduleDir = resolvedModulePath ? dirname(resolve3(resolvedModulePath)) : process.cwd();
|
|
1766
1842
|
const rootModule = await discoverModule(modulePath);
|
|
1767
1843
|
const { container, registry } = await bootstrap(rootModule);
|
|
1768
1844
|
function buildCallback(handler) {
|
|
@@ -1783,8 +1859,12 @@ async function bootstrapForRuntime(modulePath, systemLayers) {
|
|
|
1783
1859
|
createRouteCallback(path, method) {
|
|
1784
1860
|
return buildCallback(registry.getHandler(path, method));
|
|
1785
1861
|
},
|
|
1786
|
-
createRouteCallbackById(handlerId) {
|
|
1787
|
-
|
|
1862
|
+
async createRouteCallbackById(handlerId, codeLocation) {
|
|
1863
|
+
const fromRegistry = registry.getHandlerById(handlerId);
|
|
1864
|
+
if (fromRegistry) return buildCallback(fromRegistry);
|
|
1865
|
+
const baseDir = codeLocation ? resolve3(codeLocation) : moduleDir;
|
|
1866
|
+
const resolved = await resolveHandlerByModuleRef(handlerId, registry, baseDir);
|
|
1867
|
+
return resolved ? buildCallback(resolved) : null;
|
|
1788
1868
|
}
|
|
1789
1869
|
};
|
|
1790
1870
|
}
|
|
@@ -1799,7 +1879,7 @@ async function startRuntime(options) {
|
|
|
1799
1879
|
const appConfig = app.setup();
|
|
1800
1880
|
const result = await bootstrapForRuntime();
|
|
1801
1881
|
for (const def of appConfig.api?.http?.handlers ?? []) {
|
|
1802
|
-
const callback = result.createRouteCallback(def.path, def.method) ?? result.createRouteCallbackById(def.handler);
|
|
1882
|
+
const callback = result.createRouteCallback(def.path, def.method) ?? await result.createRouteCallbackById(def.handler, def.location);
|
|
1803
1883
|
if (callback) {
|
|
1804
1884
|
app.registerHttpHandler(def.path, def.method, def.timeout, callback);
|
|
1805
1885
|
}
|
|
@@ -1889,6 +1969,7 @@ export {
|
|
|
1889
1969
|
mapToRuntimeResponse,
|
|
1890
1970
|
mockRequest,
|
|
1891
1971
|
registerModuleGraph,
|
|
1972
|
+
resolveHandlerByModuleRef,
|
|
1892
1973
|
runLayerPipeline,
|
|
1893
1974
|
startRuntime,
|
|
1894
1975
|
tokenToString,
|