1
- import { METHODS } from "http" ;
2
1
import { URL } from "url" ;
3
2
import { readFile } from "fs/promises" ;
4
3
import path from "path" ;
5
4
import * as Router from "find-my-way-ts" ;
6
5
import { Model , Request } from "./metamodel" ;
7
6
7
+ const isBrowser = typeof window !== "undefined" ;
8
+ const httpMethods = [ "HEAD" , "GET" , "POST" , "PUT" , "PATCH" , "DELETE" ] ;
8
9
export type JSONValue = string | number | boolean | JSONArray | JSONObject ;
9
10
interface JSONArray extends Array < JSONValue > { }
10
11
interface JSONObject {
@@ -47,7 +48,7 @@ type ESRoute = {
47
48
request : Request ;
48
49
} ;
49
50
50
- const router = Router . make < ESRoute > ( {
51
+ let router = Router . make < ESRoute > ( {
51
52
ignoreTrailingSlash : true ,
52
53
maxParamLength : 1000 ,
53
54
} ) ;
@@ -62,7 +63,7 @@ export function splitSource(source: string): string[] {
62
63
let prev = 0 ;
63
64
while ( index < len ) {
64
65
// Beginning of a new command, we should find the method and proceede to the url.
65
- for ( const method of METHODS ) {
66
+ for ( const method of httpMethods ) {
66
67
if ( source . slice ( index , len ) . startsWith ( method ) ) {
67
68
index += method . length ;
68
69
break ;
@@ -80,7 +81,7 @@ export function splitSource(source: string): string[] {
80
81
if ( index == len ) return ;
81
82
let brackets = 0 ;
82
83
// If we found an http method, then we have found a new command.
83
- for ( const method of METHODS ) {
84
+ for ( const method of httpMethods ) {
84
85
if ( source . slice ( index , len ) . startsWith ( method ) ) {
85
86
return ;
86
87
}
@@ -90,7 +91,7 @@ export function splitSource(source: string): string[] {
90
91
// If we find an open curly bracket, we should also find the closing one
91
92
// before to checking for the http method.
92
93
if ( source [ index ] == "{" ) {
93
- for ( ; ; ) {
94
+ for ( ; index < len ; ) {
94
95
if ( source [ index ] == "{" ) {
95
96
brackets += 1 ;
96
97
} else if ( source [ index ] == "}" ) {
@@ -131,7 +132,7 @@ function parseCommand(source: string, options: ParseOptions) {
131
132
const len = source . length ;
132
133
let index = 0 ;
133
134
// identify the method
134
- for ( const method of METHODS ) {
135
+ for ( const method of httpMethods ) {
135
136
if ( source . slice ( index , len ) . startsWith ( method ) ) {
136
137
data . method = method ;
137
138
index += method . length ;
@@ -264,16 +265,28 @@ function parseCommand(source: string, options: ParseOptions) {
264
265
* function directly, but it can be used to load a different version of the
265
266
* specification than the one bundled with this package.
266
267
*
267
- * @param filename The path to the schema.json file to load.
268
+ * @param filename_or_object The path to the schema.json file to load, or an
269
+ * object with a loaded schema.
268
270
*/
269
- export async function loadSchema ( filename : string ) {
271
+ export async function loadSchema ( filename_or_object : string | object ) {
272
+ let spec : Model ;
273
+
274
+ if ( typeof filename_or_object === "string" ) {
275
+ spec = JSON . parse (
276
+ await readFile ( filename_or_object , { encoding : "utf-8" } ) ,
277
+ ) as Model ;
278
+ } else {
279
+ spec = filename_or_object as Model ;
280
+ }
281
+
270
282
if ( router . find ( "GET" , "/" ) != undefined ) {
271
- throw Error ( "A schema has already been loaded" ) ;
283
+ // start from a clean router
284
+ router = Router . make < ESRoute > ( {
285
+ ignoreTrailingSlash : true ,
286
+ maxParamLength : 1000 ,
287
+ } ) ;
272
288
}
273
289
274
- const spec = JSON . parse (
275
- await readFile ( filename , { encoding : "utf-8" } ) ,
276
- ) as Model ;
277
290
for ( const endpoint of spec . endpoints ) {
278
291
for ( const url of endpoint . urls ) {
279
292
const { path, methods } = url ;
@@ -323,8 +336,12 @@ async function getAPI(
323
336
endpointPath : string ,
324
337
) : Promise < Router . FindResult < ESRoute > > {
325
338
if ( router . find ( "GET" , "/" ) == undefined ) {
326
- // load the Elasticsearch spec
327
- await loadSchema ( path . join ( __dirname , "./schema.json" ) ) ;
339
+ if ( ! isBrowser ) {
340
+ // load the Elasticsearch spec
341
+ await loadSchema ( path . join ( __dirname , "./schema.json" ) ) ;
342
+ } else {
343
+ throw new Error ( "Specification is missing" ) ;
344
+ }
328
345
}
329
346
330
347
const formattedPath = endpointPath . startsWith ( "/" )
0 commit comments