galbe 0.8.0 → 0.9.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.
@@ -31,17 +31,17 @@ const fmtRes = (r, p = false) => {
31
31
  if (typeof r === 'object') {
32
32
  try {
33
33
  let resp = fmtObject(r, p, 2)
34
- return process.stdout.write(`${resp}\n`)
34
+ return Bun.write(Bun.stdout, `${resp}\n`)
35
35
  } catch (err) {
36
36
  console.error(err)
37
- return process.stdout.write(`${r}\n`)
37
+ return Bun.write(Bun.stdout, `${r}\n`)
38
38
  }
39
39
  }
40
- if (!p) return process.stdout.write(`${r}\n`)
41
- if (typeof r === 'boolean') return process.stdout.write(`${ansi(p, '38;2;255;128;0', r)}\n`)
42
- if (typeof r === 'number') return process.stdout.write(`${ansi(p, '38;2;10;180;220', r)}\n`)
43
- if (typeof r === 'string') return process.stdout.write(`${ansi(p, '38;2;125;170;0', r)}\n`)
44
- return process.stdout.write(`${r}\n`)
40
+ if (!p) return Bun.write(Bun.stdout, `${r}\n`)
41
+ if (typeof r === 'boolean') return Bun.write(Bun.stdout, `${ansi(p, '38;2;255;128;0', r)}\n`)
42
+ if (typeof r === 'number') return Bun.write(Bun.stdout, `${ansi(p, '38;2;10;180;220', r)}\n`)
43
+ if (typeof r === 'string') return Bun.write(Bun.stdout, `${ansi(p, '38;2;125;170;0', r)}\n`)
44
+ return Bun.write(Bun.stdout, `${r}\n`)
45
45
  }
46
46
 
47
47
  const fetchApi = async (method, path, props) => {
@@ -84,9 +84,9 @@ const fetchApi = async (method, path, props) => {
84
84
  let isJson = res.headers.get('content-type') === 'application/json'
85
85
  if (isJson) fmtRes(await res.json(), format.has('p'))
86
86
  else if (res.headers.get('content-type')?.match(/^text\//)) fmtRes(await res.text(), format.has('p'))
87
- else process.stdout.write(await res.arrayBuffer())
87
+ else Bun.write(Bun.stdout, await res.arrayBuffer())
88
88
  }
89
- if (format.has('t')) process.stdout.write(`${(endTime / 1_000_000).toFixed(2)}ms\n`)
89
+ if (format.has('t')) Bun.write(Bun.stdout, `${(endTime / 1_000_000).toFixed(2)}ms\n`)
90
90
  process.exit(res.ok ? 0 : 1)
91
91
  }
92
92
 
@@ -100,7 +100,7 @@ const formatDefault = def =>
100
100
  : def ?? 'undefined';
101
101
 
102
102
  result = commands.map(c=>{
103
- let args = c.arguments.map(a=>`.argument("${a.name}", "${a.description || a.name+' argument' || ''}")`)
103
+ let args = c.arguments.map(a=>`.argument("${a.name}", "${JSON.stringify(a.description).slice(1,-1) || a.name+' argument' || ''}")`)
104
104
  let optionsBase = [
105
105
  {name: '%format', short:'%f', type: '[string]', description: 'response format [\'s\',\'h\',\'b\',\'t\',\'p\']', default:["s","b","p"]},
106
106
  {name: '%header', short:'%h', type: '<string...>', description: 'request header formated as headerName=headerValue', default:[]},
@@ -108,12 +108,12 @@ result = commands.map(c=>{
108
108
  {name: '%body', short:'%b', type: '<string>', description: 'request body', default:''},
109
109
  {name: '%bodyFile', short:'%bf', type: '<path>', description: 'request body file', default:''}
110
110
  ]
111
- let options = [...optionsBase,...(c.options||[])].map(o=>`.addOption(new Option("-${o.short}, --${o.name} ${o.type}", "${o.description}").default(${formatDefault(o.default)}))`)
112
- let action = `.action(async (${c.arguments.map(a=>`${a.name},`)} props) => {
111
+ let options = [...optionsBase,...(c.options||[])].map(o=>`.addOption(new Option("-${o.short}, --${o.name} ${o.type}", "${JSON.stringify(o.description).slice(1,-1)}").default(${formatDefault(o.default)}))`)
112
+ let action = `.action(async (${c.arguments.map(a=>`${a.name},`).join('')} props) => {
113
113
  ${c.action ? ';('+c.action.toString()+')(props)' : ''}
114
114
  return await fetchApi("${c.route.method.toUpperCase()}",\`${c.route.pathT}\`, props)
115
115
  })`
116
- return `program.command("${c.name}").description("${c.description}")${args.join('')}${options.join('')}${action}`
116
+ return `program.command("${c.name}").description("${JSON.stringify(c.description).slice(1,-1)}")${args.join('')}${options.join('')}${action}`
117
117
  })
118
118
  %*/
119
119
 
@@ -6,8 +6,8 @@ export type GalbeClientConfig = {
6
6
  export const Kind = Symbol.for('json.string')
7
7
  type Json<T> = { T: T }
8
8
 
9
- interface GR<S extends number = number, B = any, OKS extends number = OKStatusCode> {
10
- status: S
9
+ interface GR<S extends number | 'default' = 'default', B = any, OKS extends number = OKStatusCode> {
10
+ status: Exclude<S, "default">
11
11
  ok: S extends OKS ? true : false
12
12
  redirected: boolean
13
13
  statusText: string
@@ -18,16 +18,16 @@ interface GR<S extends number = number, B = any, OKS extends number = OKStatusCo
18
18
  stream?: ST
19
19
  ) => B extends Uint8Array
20
20
  ? ST extends true
21
- ? Promise<AsyncGenerator<Uint8Array, void, unknown>>
22
- : B extends Json<infer T>
23
- ? Promise<T>
24
- : Promise<B>
21
+ ? Promise<AsyncGenerator<Uint8Array, void, unknown>>
22
+ : B extends Json<infer T>
23
+ ? Promise<T>
24
+ : Promise<B>
25
25
  : B extends string
26
26
  ? ST extends true
27
- ? Promise<AsyncGenerator<string, void, unknown>>
28
- : B extends Json<infer T>
29
- ? Promise<T>
30
- : Promise<B>
27
+ ? Promise<AsyncGenerator<string, void, unknown>>
28
+ : B extends Json<infer T>
29
+ ? Promise<T>
30
+ : Promise<B>
31
31
  : B extends Json<infer T>
32
32
  ? Promise<T>
33
33
  : Promise<B>
@@ -35,9 +35,9 @@ interface GR<S extends number = number, B = any, OKS extends number = OKStatusCo
35
35
 
36
36
  export type OKStatusCode = 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 226
37
37
  // prettier-ignore
38
- export type HttpStatusCode = 100|101|102|103|OKStatusCode|300|301|302|303|304|305|307|308|400|401|402|403|404|405|406|407|408|409|410|411|412|413|414|415|416|417|418|421|422|423|424|426|428|429|431|451|500|501|502|503|504|505|506|507|508|510|511
38
+ export type HttpStatusCode = 100 | 101 | 102 | 103 | OKStatusCode | 300 | 301 | 302 | 303 | 304 | 305 | 307 | 308 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 421 | 422 | 423 | 424 | 426 | 428 | 429 | 431 | 451 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511
39
39
  type PGR<
40
- S extends number = number,
40
+ S extends number | 'default' = 'default',
41
41
  B = any,
42
42
  O extends number = 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 226
43
43
  > = Promise<GR<S, B, O>>
@@ -54,9 +54,15 @@ const DEFAULT_HEADERS = {
54
54
  'user-agent': 'Galbe//*%(()=>version)()%*/'
55
55
  }
56
56
 
57
+ // Typescript types
58
+ /*%
59
+ Object.entries(types).map(([tk, t])=>{
60
+ return `export type ${tk} = ${t}`
61
+ })
62
+ %*/
63
+
57
64
  export default class GalbeClient {
58
65
  config?: GalbeClientConfig
59
-
60
66
  /*%
61
67
  Object.entries(routes).map(([method, list])=>{
62
68
  return`${method} = {\n${list.map( r => {
@@ -66,7 +72,7 @@ export default class GalbeClient {
66
72
  ''
67
73
  let oks = Object.keys(r.schemas?.response||{}).filter(s=>s>=200&&s<300)
68
74
  let responses = Object.keys(r.schemas?.response||{}).length ?
69
- `${Object.entries(r.schemas.response).map(([k,v])=>`PGR<${k},${v}${oks?.length?`,${oks.join('|')}`:''}>`).join('|')}|PGR<Exclude<HttpStatusCode,${Object.keys(r.schemas.response).join('|')}>,any${oks?.length?`,${oks.join('|')}`:''}>`:
75
+ `${Object.entries(r.schemas.response).filter(([s,_])=>s!=='"default"').map(([k,v])=>`PGR<${k},${v}${oks?.length?`,${oks.join('|')}`:''}>`).join('|')}|PGR<Exclude<HttpStatusCode,${Object.keys(r.schemas.response).filter(s=>s!=='"default"').join('|')}>,${'"default"' in r.schemas.response ? r.schemas.response['"default"'] : 'any'}${oks?.length?`,${oks.join('|')}`:''}>`:
70
76
  `PGR<HttpStatusCode,any${oks?.length?`,${oks.join('|')}`:',any'}>`
71
77
  return ` '${r.path}':(${p.length?p.map(([k,v])=>`${k}:${v.type}`).join(',')+', ':''}options:RequestOptions${schemas}={})=>this.fetch(\`${r.pathT}\`,{...options,method:'${r.method.toUpperCase()}'}) as ${responses}`
72
78
  }).join(',\n')}\n}`
@@ -155,9 +161,13 @@ export default class GalbeClient {
155
161
  ''
156
162
  let oks = Object.keys(r.schemas?.response||{}).filter(s=>s>=200&&s<300)
157
163
  let responses = Object.keys(r.schemas?.response||{}).length ?
158
- `${Object.entries(r.schemas.response).map(([k,v])=>`PGR<${k},${v}${oks?.length?`,${oks.join('|')}`:''}>`).join('|')}|PGR<Exclude<HttpStatusCode,${Object.keys(r.schemas.response).join('|')}>,any${oks?.length?`,${oks.join('|')}`:''}>`:
164
+ `${Object.entries(r.schemas.response).filter(([s,_])=>s!=='"default"').map(([k,v])=>`PGR<${k},${v}${oks?.length?`,${oks.join('|')}`:''}>`).join('|')}|PGR<Exclude<HttpStatusCode,${Object.keys(r.schemas.response).filter(s=>s!=='"default"').join('|')}>,${'"default"' in r.schemas.response ? r.schemas.response['"default"'] : 'any'}${oks?.length?`,${oks.join('|')}`:''}>`:
159
165
  `PGR<HttpStatusCode,any${oks?.length?`,${oks.join('|')}`:',any'}>`
160
- return `${r.alias}(${p.length ? p.map(([k,v])=>`${k}: ${v.type}`).join(', ')+', ':''}options: RequestOptions${schemas} = {}){return this.fetch(\`${r.pathT}\`, {...options, method: '${r.method.toUpperCase()}'}) as ${responses}}\n`
166
+ let summary = r.summary ? ` * ${r.summary || ''}\n *\n` : ''
167
+ let description = r.description ? ` * ${r.description.replace(/\n/g,'\n * ')}` : ''
168
+ let params = Object.entries(r.schema.params || {}).map( ([k,v])=>`\n * @param ${k} - ${v.description?.replace(/\n/g,'\n ')}` ).join('')
169
+ let query = Object.entries(r.schema.query || {}).map( ([k,v])=>`\n * @param options.query.${k} - ${v.description?.replace(/\n/g,'\n ')}` ).join('')
170
+ return `/**\n${summary}${description}\n *${params}${query}\n *\/\n ${r.alias}(${p.length ? p.map(([k,v])=>`${k}: ${v.type}`).join(', ')+', ':''}options: RequestOptions${schemas} = {}){return this.fetch(\`${r.pathT}\`, {...options, method: '${r.method.toUpperCase()}'}) as ${responses}}\n`
161
171
  }).join(' ')
162
172
  })
163
173
  %*/
package/bin/util.ts CHANGED
@@ -2,7 +2,7 @@ import { relative } from 'path'
2
2
  import { watch } from 'chokidar'
3
3
  import { Galbe, Route } from '../src'
4
4
  import { logRoute, walkRoutes } from '../src/util'
5
- import { RouteMeta, defineRoutes } from '../src/routes'
5
+ import { GalbeProxy, RouteMeta, defineRoutes } from '../src/routes'
6
6
 
7
7
  export { default as pckg } from '../package.json'
8
8
 
@@ -22,7 +22,7 @@ export const silentExec = async (fn: () => any) => {
22
22
  let consoleMock = Object.fromEntries(
23
23
  Object.entries(console)
24
24
  .filter(([_, v]) => typeof v === 'function')
25
- .map(([k, _]) => [k, () => {}])
25
+ .map(([k, _]) => [k, () => { }])
26
26
  )
27
27
  const _console = console
28
28
  const _processStdoutWrite = process.stdout.write
@@ -30,9 +30,9 @@ export const silentExec = async (fn: () => any) => {
30
30
  //@ts-ignore
31
31
  global.console = consoleMock
32
32
  //@ts-ignore
33
- process.stdout.write = function () {}
33
+ process.stdout.write = function () { }
34
34
  //@ts-ignore
35
- process.stderr.write = function () {}
35
+ process.stderr.write = function () { }
36
36
  const r = await fn()
37
37
  global.console = _console
38
38
  process.stdout.write = _processStdoutWrite
@@ -65,29 +65,32 @@ export const instanciateRoutes = async (g: Galbe) => {
65
65
  hasMainRoutes = true
66
66
  logRoute(r)
67
67
  })
68
- if (hasMainRoutes) process.stdout.write('\n')
68
+ if (hasMainRoutes) Bun.write(Bun.stdout, '\n')
69
69
  // Route Files Analysis
70
70
  let routes: Record<string, { route?: Route; meta?: RouteMeta; error?: any }[]> = {}
71
71
  let errors: Record<string, any> = {}
72
- await defineRoutes({ routes: g?.config?.routes }, g, ({ type, route, error, filepath, meta }) => {
72
+
73
+ const proxy = new GalbeProxy(g, ({ type, route, error, filepath, meta }) => {
74
+ if (meta?.ignore || meta?.hide) return
73
75
  if (!filepath) return
74
76
  if (!(filepath in routes)) routes[filepath] = []
75
77
  if (type === 'add' && route && filepath) routes[filepath].push({ route, meta })
76
78
  if (type === 'error') errors[filepath] = error
77
79
  })
80
+ await defineRoutes({ routes: g?.config?.routes }, proxy)
78
81
  for (let [fp, e] of Object.entries(routes)) {
79
82
  console.log(`\x1b\[0;36m ${relative(CWD, fp)}\x1b[0m`)
80
83
  let maxPathLength = e.reduce((p, c) => {
81
84
  return Math.max(p, c.route?.path.length || 0)
82
85
  }, 0)
83
86
  for (let r of e) {
84
- if (r.route) logRoute(r.route, r.meta, { maxPathLength })
87
+ if (r.route && !r.meta?.ignore && !r.meta?.hide) logRoute(r.route, r.meta, { maxPathLength })
85
88
  }
86
89
  if (errors?.[fp]) {
87
90
  console.log(`\x1b\[0;31m Error:\x1b[0m`)
88
91
  console.log(errors?.[fp])
89
92
  }
90
- process.stdout.write('\n')
93
+ console.log("")
91
94
  }
92
95
  console.log('\x1b[1;30m\x1b[32mdone\x1b[0m\n')
93
96
  }