ts-procedures 5.12.0 → 5.14.0

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.
Files changed (27) hide show
  1. package/agent_config/claude-code/agents/ts-procedures-architect.md +0 -1
  2. package/agent_config/claude-code/skills/ts-procedures/anti-patterns.md +0 -25
  3. package/agent_config/claude-code/skills/ts-procedures/api-reference.md +25 -5
  4. package/agent_config/claude-code/skills/ts-procedures/patterns.md +1 -1
  5. package/agent_config/claude-code/skills/ts-procedures-scaffold/templates/hono-api.md +1 -1
  6. package/agent_config/copilot/copilot-instructions.md +1 -2
  7. package/agent_config/cursor/cursorrules +1 -2
  8. package/build/codegen/e2e.test.js +6 -6
  9. package/build/codegen/e2e.test.js.map +1 -1
  10. package/build/codegen/emit-index.js +6 -3
  11. package/build/codegen/emit-index.js.map +1 -1
  12. package/build/codegen/emit-index.test.js +16 -16
  13. package/build/codegen/emit-index.test.js.map +1 -1
  14. package/build/codegen/pipeline.test.js +2 -2
  15. package/build/codegen/pipeline.test.js.map +1 -1
  16. package/build/implementations/http/hono-api/index.d.ts +15 -3
  17. package/build/implementations/http/hono-api/index.js +3 -32
  18. package/build/implementations/http/hono-api/index.js.map +1 -1
  19. package/build/implementations/http/hono-api/index.test.js +6 -6
  20. package/build/implementations/http/hono-api/index.test.js.map +1 -1
  21. package/package.json +2 -3
  22. package/src/codegen/e2e.test.ts +6 -6
  23. package/src/codegen/emit-index.test.ts +16 -16
  24. package/src/codegen/emit-index.ts +7 -3
  25. package/src/codegen/pipeline.test.ts +2 -2
  26. package/src/implementations/http/hono-api/index.test.ts +6 -6
  27. package/src/implementations/http/hono-api/index.ts +17 -36
@@ -19,22 +19,7 @@ export type { APIConfig, APIHttpRouteDoc, APIInput, HttpMethod }
19
19
 
20
20
  export type QueryParser = (queryString: string) => Record<string, unknown>
21
21
 
22
- /** Lazy-loaded qs module (optional peer dependency) */
23
- let _qsModule: { parse: (str: string, opts?: any) => any } | false | undefined
24
-
25
- async function loadQs(): Promise<{ parse: (str: string, opts?: any) => any } | undefined> {
26
- if (_qsModule === undefined) {
27
- try {
28
- const mod = await import('qs')
29
- _qsModule = mod.default ?? mod
30
- } catch {
31
- _qsModule = false
32
- }
33
- }
34
- return _qsModule || undefined
35
- }
36
-
37
- /** Fallback query parser using native URLSearchParams */
22
+ /** Default query parser using native URLSearchParams. */
38
23
  function parseQueryNative(queryString: string): Record<string, unknown> {
39
24
  const searchParams = new URLSearchParams(queryString)
40
25
  const result: Record<string, unknown> = {}
@@ -45,21 +30,6 @@ function parseQueryNative(queryString: string): Record<string, unknown> {
45
30
  return result
46
31
  }
47
32
 
48
- /**
49
- * Resolves the query parser once. Called during build() so handlers use a sync parser.
50
- * Priority: custom queryParser > qs (optional peer dep) > native URLSearchParams
51
- */
52
- async function resolveQueryParser(custom?: QueryParser): Promise<QueryParser> {
53
- if (custom) return custom
54
-
55
- const qs = await loadQs()
56
- if (qs) {
57
- return (raw: string) => qs.parse(raw) as Record<string, unknown>
58
- }
59
-
60
- return parseQueryNative
61
- }
62
-
63
33
  /** Extract path parameter names from a route pattern (e.g., '/users/:id' → ['id']) */
64
34
  function extractPathParamNames(path: string): string[] {
65
35
  const matches = path.match(/:([a-zA-Z_][a-zA-Z0-9_]*)/g)
@@ -104,7 +74,20 @@ export type HonoAPIAppBuilderConfig = {
104
74
  pathPrefix?: string
105
75
  /**
106
76
  * Custom query string parser. Receives the raw query string (without '?').
107
- * Default: uses `qs` (optional peer dependency) if available, otherwise native URLSearchParams.
77
+ *
78
+ * Default: native `URLSearchParams`. The default handles:
79
+ * - flat keys: `?page=2&limit=10` → `{ page: '2', limit: '10' }`
80
+ * - repeated keys: `?tag=a&tag=b` → `{ tag: ['a', 'b'] }`
81
+ *
82
+ * The default does NOT parse any of these — the bracket/dot syntax is kept
83
+ * as part of the literal key name, not interpreted:
84
+ * - bracket objects: `?user[name]=John` → `{ 'user[name]': 'John' }`
85
+ * - bracket arrays: `?tags[]=a&tags[]=b` → `{ 'tags[]': ['a', 'b'] }`
86
+ * - dot paths: `?user.name=John` → `{ 'user.name': 'John' }`
87
+ * - comma-split arrays: `?tags=a,b,c` → `{ tags: 'a,b,c' }`
88
+ *
89
+ * For any of the above, install `qs` and opt in explicitly:
90
+ * `queryParser: (raw) => qs.parse(raw) as Record<string, unknown>`
108
91
  */
109
92
  queryParser?: QueryParser
110
93
  onRequestStart?: (c: Context) => void
@@ -216,11 +199,9 @@ export class HonoAPIAppBuilder {
216
199
 
217
200
  /**
218
201
  * Builds and returns the Hono application with registered API routes.
219
- * Async because it resolves the query parser (qs optional peer dep) once at build time.
220
202
  */
221
- async build(): Promise<Hono> {
222
- // Resolve query parser once so handlers use it synchronously
223
- const queryParser = await resolveQueryParser(this.config?.queryParser)
203
+ build(): Hono {
204
+ const queryParser = this.config?.queryParser ?? parseQueryNative
224
205
 
225
206
  this.factories.forEach(({ factory, factoryContext, extendProcedureDoc }) => {
226
207
  factory.getProcedures().map((procedure: TProcedureRegistration<any, APIConfig>) => {