@tuyau/core 1.0.0-beta.11 → 1.0.0-beta.12

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.
@@ -43,10 +43,21 @@ function buildTreeStructure(routes) {
43
43
  const segment = stringHelpers.camelCase(segments[i]);
44
44
  const isLast = i === segments.length - 1;
45
45
  if (isLast) {
46
- current.set(segment, { routeName: route.name, route });
46
+ if (current.has(segment) && current.get(segment) instanceof Map) {
47
+ current.get(segment).set("$self", { routeName: route.name, route });
48
+ } else {
49
+ current.set(segment, { routeName: route.name, route });
50
+ }
47
51
  } else {
48
52
  if (!current.has(segment)) {
49
53
  current.set(segment, /* @__PURE__ */ new Map());
54
+ } else {
55
+ const existing = current.get(segment);
56
+ if (!(existing instanceof Map)) {
57
+ const newMap = /* @__PURE__ */ new Map();
58
+ newMap.set("$self", existing);
59
+ current.set(segment, newMap);
60
+ }
50
61
  }
51
62
  current = current.get(segment);
52
63
  }
@@ -58,10 +69,18 @@ function generateTreeInterface(tree, indent = 2) {
58
69
  const spaces = " ".repeat(indent);
59
70
  const lines = [];
60
71
  for (const [key, value] of tree) {
72
+ if (key === "$self") continue;
61
73
  if (value instanceof Map) {
62
- lines.push(`${spaces}${key}: {`);
63
- lines.push(generateTreeInterface(value, indent + 2));
64
- lines.push(`${spaces}}`);
74
+ const selfRoute = value.get("$self");
75
+ if (selfRoute) {
76
+ lines.push(`${spaces}${key}: typeof routes['${selfRoute.routeName}'] & {`);
77
+ lines.push(generateTreeInterface(value, indent + 2));
78
+ lines.push(`${spaces}}`);
79
+ } else {
80
+ lines.push(`${spaces}${key}: {`);
81
+ lines.push(generateTreeInterface(value, indent + 2));
82
+ lines.push(`${spaces}}`);
83
+ }
65
84
  } else {
66
85
  lines.push(`${spaces}${key}: typeof routes['${value.routeName}']`);
67
86
  }
@@ -119,13 +119,17 @@ type ResponseOf<E extends SchemaEndpoint> = E['types']['response'];
119
119
  * Function type for calling an endpoint
120
120
  */
121
121
  type EndpointFn<E extends SchemaEndpoint> = (args: RequestArgs<E>) => Promise<E['types']['response']>;
122
+ /**
123
+ * Function type for an endpoint with inlined args
124
+ */
125
+ type EndpointFnInline<E extends AdonisEndpoint> = (args: ParamsArg<E['types']['params']> & QueryArg<E['types']['query']> & BodyArg<E['types']['body']> & BaseRequestOptions) => Promise<E['types']['response']>;
122
126
  /**
123
127
  * Transforms a pre-computed ApiDefinition tree into callable endpoint functions
124
128
  * This recursively converts each endpoint in the tree to a callable function
125
- * Fully inlined for maximum performance
129
+ * Handles intersection types where a node is both an endpoint AND has children
126
130
  */
127
131
  type TransformApiDefinition<T> = {
128
- [K in keyof T]: T[K] extends AdonisEndpoint ? (args: ParamsArg<T[K]['types']['params']> & QueryArg<T[K]['types']['query']> & BodyArg<T[K]['types']['body']> & BaseRequestOptions) => Promise<T[K]['types']['response']> : TransformApiDefinition<T[K]>;
132
+ [K in keyof T]: T[K] extends AdonisEndpoint ? EndpointFnInline<T[K]> & TransformApiDefinition<Omit<T[K], keyof AdonisEndpoint>> : TransformApiDefinition<T[K]>;
129
133
  };
130
134
  /**
131
135
  * Filters endpoints by HTTP method
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tuyau/core",
3
3
  "type": "module",
4
- "version": "1.0.0-beta.11",
4
+ "version": "1.0.0-beta.12",
5
5
  "description": "E2E typesafe client for AdonisJS",
6
6
  "author": "Julien Ripouteau <julien@ripouteau.com>",
7
7
  "license": "MIT",