@kubb/ast 5.0.0-beta.53 → 5.0.0-beta.54

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.
@@ -2005,12 +2005,21 @@ type DedupePlan = {
2005
2005
  * Maps a structural signature to the canonical schema that represents it.
2006
2006
  */
2007
2007
  canonicalBySignature: Map<string, DedupeCanonical>;
2008
+ /**
2009
+ * Maps the name of a top-level schema that duplicates a canonical one to that canonical, so
2010
+ * references to the duplicate can be repointed at the first schema with the same content.
2011
+ */
2012
+ aliasNames: Map<string, DedupeCanonical>;
2008
2013
  /**
2009
2014
  * New top-level schema definitions created for inline shapes that had no existing
2010
2015
  * named component. Nested duplicates inside each definition are already collapsed.
2011
2016
  */
2012
2017
  hoisted: Array<SchemaNode>;
2013
2018
  };
2019
+ /**
2020
+ * The lookups {@link applyDedupe} needs from a {@link DedupePlan}.
2021
+ */
2022
+ type DedupeLookups = Pick<DedupePlan, 'canonicalBySignature' | 'aliasNames'>;
2014
2023
  /**
2015
2024
  * Options that inject the naming and candidate policy into {@link buildDedupePlan}.
2016
2025
  * The mechanics (grouping, counting, rewriting) live here. The policy lives in the caller.
@@ -2041,25 +2050,29 @@ type BuildDedupePlanOptions = {
2041
2050
  /**
2042
2051
  * Rewrites a node, replacing every candidate sub-schema whose signature has a canonical
2043
2052
  * target with a `ref` to that target. Replacing a node with a `ref` prunes its subtree,
2044
- * so nested duplicates inside a replaced shape are not visited again.
2053
+ * so nested duplicates inside a replaced shape are not visited again. A `ref` that points
2054
+ * at a duplicate top-level schema (see `aliasNames`) is repointed at the first schema with
2055
+ * the same content.
2045
2056
  *
2046
2057
  * Pass `skipRootMatch` when rewriting a canonical definition so its own root is not
2047
2058
  * turned into a reference to itself. Nested duplicates are still collapsed.
2048
2059
  *
2049
2060
  * @example
2050
2061
  * ```ts
2051
- * const next = applyDedupe(operationNode, plan.canonicalBySignature)
2062
+ * const next = applyDedupe(operationNode, plan)
2052
2063
  * ```
2053
2064
  */
2054
- declare function applyDedupe(node: SchemaNode, canonicalBySignature: ReadonlyMap<string, DedupeCanonical>, skipRootMatch?: boolean): SchemaNode;
2055
- declare function applyDedupe(node: OperationNode, canonicalBySignature: ReadonlyMap<string, DedupeCanonical>, skipRootMatch?: boolean): OperationNode;
2065
+ declare function applyDedupe(node: SchemaNode, plan: DedupeLookups, skipRootMatch?: boolean): SchemaNode;
2066
+ declare function applyDedupe(node: OperationNode, plan: DedupeLookups, skipRootMatch?: boolean): OperationNode;
2056
2067
  /**
2057
2068
  * Scans a forest of schema and operation nodes and produces a {@link DedupePlan}.
2058
2069
  *
2059
2070
  * A shape that occurs at least `minOccurrences` times is deduplicated: if any occurrence
2060
- * is a named top-level schema, that name becomes the canonical (so other top-level duplicates
2061
- * and inline copies turn into references to it). Otherwise a new definition is hoisted using
2062
- * `nameFor`. The plan is then applied per node with {@link applyDedupe}.
2071
+ * is a named top-level schema, the first one becomes the canonical (so other top-level
2072
+ * duplicates and inline copies turn into references to it). Every other top-level name with
2073
+ * the same content is recorded in `aliasNames`, so refs to it can be repointed at the
2074
+ * canonical. Otherwise a new definition is hoisted using `nameFor`. The plan is then applied
2075
+ * per node with {@link applyDedupe}.
2063
2076
  *
2064
2077
  * @example
2065
2078
  * ```ts
@@ -3571,5 +3584,5 @@ declare function containsCircularRef(node: SchemaNode | undefined, {
3571
3584
  excludeName?: string;
3572
3585
  }): boolean;
3573
3586
  //#endregion
3574
- export { SchemaDialect as $, httpMethods as $t, createFunctionParameter as A, IntersectionSchemaNode as At, createProperty as B, TimeSchemaNode as Bt, UserFileNode as C, FileNode as Ct, createExport as D, DateSchemaNode as Dt, createConst as E, ArraySchemaNode as Et, createOperation as F, ScalarSchemaType as Ft, createText as G, CodeNode as Gt, createSchema as H, UrlSchemaNode as Ht, createOutput as I, SchemaNode as It, update as J, JSDocNode as Jt, createType as K, ConstNode as Kt, createParameter as L, SchemaNodeByType as Lt, createImport as M, ObjectSchemaNode as Mt, createInput as N, PrimitiveSchemaType as Nt, createFile as O, DatetimeSchemaNode as Ot, createJsx as P, RefSchemaNode as Pt, dispatch as Q, NodeKind as Qt, createParameterGroup as R, SchemaType as Rt, DistributiveOmit as S, ExportNode as St, createBreak as T, SourceNode as Tt, createSource as U, PropertyNode as Ut, createResponse as V, UnionSchemaNode as Vt, createStreamInput as W, ArrowFunctionNode as Wt, ParserOptions as X, TextNode as Xt, InferSchemaNode as Y, JsxNode as Yt, DispatchRule as Z, TypeNode as Zt, Printer as _, FunctionParamNode as _t, createDiscriminantNode as a, InputMeta as at, createPrinterFactory as b, ParameterGroupNode as bt, findCircularSchemas as c, OutputNode as ct, ParentOf as d, OperationNode as dt, schemaTypes as en, defineSchemaDialect as et, Visitor as f, ResponseNode as ft, walk as g, FunctionNodeType as gt, transform as h, ParameterNode as ht, containsCircularRef as i, Node as it, createFunctionParameters as j, NumberSchemaNode as jt, createFunction as k, EnumSchemaNode as kt, isStringType as l, HttpMethod as lt, collect as m, ParameterLocation as mt, caseParams as n, applyDedupe as nt, createOperationParams as o, InputNode as ot, VisitorContext as p, StatusCode as pt, syncOptionality as q, FunctionNode as qt, collectUsedSchemaNames as r, buildDedupePlan as rt, extractStringsFromNodes as s, InputStreamNode as st, OperationParamsResolver as t, DedupePlan as tt, syncSchemaRef as u, HttpOperationNode as ut, PrinterFactoryOptions as v, FunctionParameterNode as vt, createArrowFunction as w, ImportNode as wt, definePrinter as x, ParamsTypeNode as xt, PrinterPartial as y, FunctionParametersNode as yt, createParamsType as z, StringSchemaNode as zt };
3575
- //# sourceMappingURL=types-IHUK_alM.d.ts.map
3587
+ export { SchemaDialect as $, TypeNode as $t, createFunctionParameter as A, DatetimeSchemaNode as At, createProperty as B, SchemaType as Bt, UserFileNode as C, ParamsTypeNode as Ct, createExport as D, SourceNode as Dt, createConst as E, ImportNode as Et, createOperation as F, PrimitiveSchemaType as Ft, createText as G, PropertyNode as Gt, createSchema as H, TimeSchemaNode as Ht, createOutput as I, RefSchemaNode as It, update as J, ConstNode as Jt, createType as K, ArrowFunctionNode as Kt, createParameter as L, ScalarSchemaType as Lt, createImport as M, IntersectionSchemaNode as Mt, createInput as N, NumberSchemaNode as Nt, createFile as O, ArraySchemaNode as Ot, createJsx as P, ObjectSchemaNode as Pt, dispatch as Q, TextNode as Qt, createParameterGroup as R, SchemaNode as Rt, DistributiveOmit as S, ParameterGroupNode as St, createBreak as T, FileNode as Tt, createSource as U, UnionSchemaNode as Ut, createResponse as V, StringSchemaNode as Vt, createStreamInput as W, UrlSchemaNode as Wt, ParserOptions as X, JSDocNode as Xt, InferSchemaNode as Y, FunctionNode as Yt, DispatchRule as Z, JsxNode as Zt, Printer as _, ParameterNode as _t, createDiscriminantNode as a, buildDedupePlan as at, createPrinterFactory as b, FunctionParameterNode as bt, findCircularSchemas as c, InputNode as ct, ParentOf as d, HttpMethod as dt, NodeKind as en, defineSchemaDialect as et, Visitor as f, HttpOperationNode as ft, walk as g, ParameterLocation as gt, transform as h, StatusCode as ht, containsCircularRef as i, applyDedupe as it, createFunctionParameters as j, EnumSchemaNode as jt, createFunction as k, DateSchemaNode as kt, isStringType as l, InputStreamNode as lt, collect as m, ResponseNode as mt, caseParams as n, schemaTypes as nn, DedupeLookups as nt, createOperationParams as o, Node as ot, VisitorContext as p, OperationNode as pt, syncOptionality as q, CodeNode as qt, collectUsedSchemaNames as r, DedupePlan as rt, extractStringsFromNodes as s, InputMeta as st, OperationParamsResolver as t, httpMethods as tn, DedupeCanonical as tt, syncSchemaRef as u, OutputNode as ut, PrinterFactoryOptions as v, FunctionNodeType as vt, createArrowFunction as w, ExportNode as wt, definePrinter as x, FunctionParametersNode as xt, PrinterPartial as y, FunctionParamNode as yt, createParamsType as z, SchemaNodeByType as zt };
3588
+ //# sourceMappingURL=types-BYujEIxF.d.ts.map
package/dist/types.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { $ as SchemaDialect, At as IntersectionSchemaNode, Bt as TimeSchemaNode, C as UserFileNode, Ct as FileNode, Dt as DateSchemaNode, Et as ArraySchemaNode, Ft as ScalarSchemaType, Gt as CodeNode, Ht as UrlSchemaNode, It as SchemaNode, Jt as JSDocNode, Kt as ConstNode, Lt as SchemaNodeByType, Mt as ObjectSchemaNode, Nt as PrimitiveSchemaType, Ot as DatetimeSchemaNode, Pt as RefSchemaNode, Qt as NodeKind, Rt as SchemaType, S as DistributiveOmit, St as ExportNode, Tt as SourceNode, Ut as PropertyNode, Vt as UnionSchemaNode, Wt as ArrowFunctionNode, X as ParserOptions, Xt as TextNode, Y as InferSchemaNode, Yt as JsxNode, Z as DispatchRule, Zt as TypeNode, _ as Printer, _t as FunctionParamNode, at as InputMeta, bt as ParameterGroupNode, ct as OutputNode, d as ParentOf, dt as OperationNode, f as Visitor, ft as ResponseNode, gt as FunctionNodeType, ht as ParameterNode, it as Node, jt as NumberSchemaNode, kt as EnumSchemaNode, lt as HttpMethod, mt as ParameterLocation, ot as InputNode, p as VisitorContext, pt as StatusCode, qt as FunctionNode, st as InputStreamNode, t as OperationParamsResolver, tt as DedupePlan, ut as HttpOperationNode, v as PrinterFactoryOptions, vt as FunctionParameterNode, wt as ImportNode, xt as ParamsTypeNode, y as PrinterPartial, yt as FunctionParametersNode, zt as StringSchemaNode } from "./types-IHUK_alM.js";
2
- export type { ArraySchemaNode, ArrowFunctionNode, CodeNode, ConstNode, DateSchemaNode, DatetimeSchemaNode, DedupePlan, DispatchRule, DistributiveOmit, EnumSchemaNode, ExportNode, FileNode, FunctionNode, FunctionNodeType, FunctionParamNode, FunctionParameterNode, FunctionParametersNode, HttpMethod, HttpOperationNode, ImportNode, InferSchemaNode, InputMeta, InputNode, InputStreamNode, IntersectionSchemaNode, JSDocNode, JsxNode, Node, NodeKind, NumberSchemaNode, ObjectSchemaNode, OperationNode, OperationParamsResolver, OutputNode, ParameterGroupNode, ParameterLocation, ParameterNode, ParamsTypeNode, ParentOf, ParserOptions, PrimitiveSchemaType, Printer, PrinterFactoryOptions, PrinterPartial, PropertyNode, RefSchemaNode, ResponseNode, ScalarSchemaType, SchemaDialect, SchemaNode, SchemaNodeByType, SchemaType, SourceNode, StatusCode, StringSchemaNode, TextNode, TimeSchemaNode, TypeNode, UnionSchemaNode, UrlSchemaNode, UserFileNode, Visitor, VisitorContext };
1
+ import { $ as SchemaDialect, $t as TypeNode, At as DatetimeSchemaNode, Bt as SchemaType, C as UserFileNode, Ct as ParamsTypeNode, Dt as SourceNode, Et as ImportNode, Ft as PrimitiveSchemaType, Gt as PropertyNode, Ht as TimeSchemaNode, It as RefSchemaNode, Jt as ConstNode, Kt as ArrowFunctionNode, Lt as ScalarSchemaType, Mt as IntersectionSchemaNode, Nt as NumberSchemaNode, Ot as ArraySchemaNode, Pt as ObjectSchemaNode, Qt as TextNode, Rt as SchemaNode, S as DistributiveOmit, St as ParameterGroupNode, Tt as FileNode, Ut as UnionSchemaNode, Vt as StringSchemaNode, Wt as UrlSchemaNode, X as ParserOptions, Xt as JSDocNode, Y as InferSchemaNode, Yt as FunctionNode, Z as DispatchRule, Zt as JsxNode, _ as Printer, _t as ParameterNode, bt as FunctionParameterNode, ct as InputNode, d as ParentOf, dt as HttpMethod, en as NodeKind, f as Visitor, ft as HttpOperationNode, gt as ParameterLocation, ht as StatusCode, jt as EnumSchemaNode, kt as DateSchemaNode, lt as InputStreamNode, mt as ResponseNode, nt as DedupeLookups, ot as Node, p as VisitorContext, pt as OperationNode, qt as CodeNode, rt as DedupePlan, st as InputMeta, t as OperationParamsResolver, tt as DedupeCanonical, ut as OutputNode, v as PrinterFactoryOptions, vt as FunctionNodeType, wt as ExportNode, xt as FunctionParametersNode, y as PrinterPartial, yt as FunctionParamNode, zt as SchemaNodeByType } from "./types-BYujEIxF.js";
2
+ export type { ArraySchemaNode, ArrowFunctionNode, CodeNode, ConstNode, DateSchemaNode, DatetimeSchemaNode, DedupeCanonical, DedupeLookups, DedupePlan, DispatchRule, DistributiveOmit, EnumSchemaNode, ExportNode, FileNode, FunctionNode, FunctionNodeType, FunctionParamNode, FunctionParameterNode, FunctionParametersNode, HttpMethod, HttpOperationNode, ImportNode, InferSchemaNode, InputMeta, InputNode, InputStreamNode, IntersectionSchemaNode, JSDocNode, JsxNode, Node, NodeKind, NumberSchemaNode, ObjectSchemaNode, OperationNode, OperationParamsResolver, OutputNode, ParameterGroupNode, ParameterLocation, ParameterNode, ParamsTypeNode, ParentOf, ParserOptions, PrimitiveSchemaType, Printer, PrinterFactoryOptions, PrinterPartial, PropertyNode, RefSchemaNode, ResponseNode, ScalarSchemaType, SchemaDialect, SchemaNode, SchemaNodeByType, SchemaType, SourceNode, StatusCode, StringSchemaNode, TextNode, TimeSchemaNode, TypeNode, UnionSchemaNode, UrlSchemaNode, UserFileNode, Visitor, VisitorContext };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kubb/ast",
3
- "version": "5.0.0-beta.53",
3
+ "version": "5.0.0-beta.54",
4
4
  "description": "Spec-agnostic AST layer for Kubb. Defines the node tree, visitor pattern, factory functions, and type guards used across all code generation plugins.",
5
5
  "keywords": [
6
6
  "ast",
package/src/dedupe.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { createSchema } from './factory.ts'
2
2
  import type { Node, OperationNode, SchemaNode } from './nodes/index.ts'
3
3
  import { signatureOf } from './signature.ts'
4
+ import { extractRefName } from './utils/index.ts'
4
5
  import { collectLazy, transform } from './visitor.ts'
5
6
 
6
7
  /**
@@ -28,6 +29,11 @@ export type DedupePlan = {
28
29
  * Maps a structural signature to the canonical schema that represents it.
29
30
  */
30
31
  canonicalBySignature: Map<string, DedupeCanonical>
32
+ /**
33
+ * Maps the name of a top-level schema that duplicates a canonical one to that canonical, so
34
+ * references to the duplicate can be repointed at the first schema with the same content.
35
+ */
36
+ aliasNames: Map<string, DedupeCanonical>
31
37
  /**
32
38
  * New top-level schema definitions created for inline shapes that had no existing
33
39
  * named component. Nested duplicates inside each definition are already collapsed.
@@ -35,6 +41,11 @@ export type DedupePlan = {
35
41
  hoisted: Array<SchemaNode>
36
42
  }
37
43
 
44
+ /**
45
+ * The lookups {@link applyDedupe} needs from a {@link DedupePlan}.
46
+ */
47
+ export type DedupeLookups = Pick<DedupePlan, 'canonicalBySignature' | 'aliasNames'>
48
+
38
49
  /**
39
50
  * Options that inject the naming and candidate policy into {@link buildDedupePlan}.
40
51
  * The mechanics (grouping, counting, rewriting) live here. The policy lives in the caller.
@@ -86,25 +97,35 @@ function createRefNode(node: SchemaNode, canonical: DedupeCanonical): SchemaNode
86
97
  /**
87
98
  * Rewrites a node, replacing every candidate sub-schema whose signature has a canonical
88
99
  * target with a `ref` to that target. Replacing a node with a `ref` prunes its subtree,
89
- * so nested duplicates inside a replaced shape are not visited again.
100
+ * so nested duplicates inside a replaced shape are not visited again. A `ref` that points
101
+ * at a duplicate top-level schema (see `aliasNames`) is repointed at the first schema with
102
+ * the same content.
90
103
  *
91
104
  * Pass `skipRootMatch` when rewriting a canonical definition so its own root is not
92
105
  * turned into a reference to itself. Nested duplicates are still collapsed.
93
106
  *
94
107
  * @example
95
108
  * ```ts
96
- * const next = applyDedupe(operationNode, plan.canonicalBySignature)
109
+ * const next = applyDedupe(operationNode, plan)
97
110
  * ```
98
111
  */
99
- export function applyDedupe(node: SchemaNode, canonicalBySignature: ReadonlyMap<string, DedupeCanonical>, skipRootMatch?: boolean): SchemaNode
100
- export function applyDedupe(node: OperationNode, canonicalBySignature: ReadonlyMap<string, DedupeCanonical>, skipRootMatch?: boolean): OperationNode
101
- export function applyDedupe(node: Node, canonicalBySignature: ReadonlyMap<string, DedupeCanonical>, skipRootMatch = false): Node {
102
- if (canonicalBySignature.size === 0) return node
112
+ export function applyDedupe(node: SchemaNode, plan: DedupeLookups, skipRootMatch?: boolean): SchemaNode
113
+ export function applyDedupe(node: OperationNode, plan: DedupeLookups, skipRootMatch?: boolean): OperationNode
114
+ export function applyDedupe(node: Node, plan: DedupeLookups, skipRootMatch = false): Node {
115
+ const { canonicalBySignature, aliasNames } = plan
116
+ if (canonicalBySignature.size === 0 && aliasNames.size === 0) return node
103
117
 
104
118
  const root = node
105
119
 
106
120
  return transform(node, {
107
121
  schema(schemaNode) {
122
+ if (schemaNode.type === 'ref') {
123
+ const target = schemaNode.ref ? extractRefName(schemaNode.ref) : schemaNode.name
124
+ const canonical = target ? aliasNames.get(target) : undefined
125
+
126
+ return canonical ? { ...schemaNode, name: canonical.name, ref: canonical.ref } : undefined
127
+ }
128
+
108
129
  const signature = signatureOf(schemaNode)
109
130
  if (skipRootMatch && schemaNode === root) return undefined
110
131
 
@@ -128,9 +149,11 @@ function cleanDefinition(node: SchemaNode, name: string): SchemaNode {
128
149
  * Scans a forest of schema and operation nodes and produces a {@link DedupePlan}.
129
150
  *
130
151
  * A shape that occurs at least `minOccurrences` times is deduplicated: if any occurrence
131
- * is a named top-level schema, that name becomes the canonical (so other top-level duplicates
132
- * and inline copies turn into references to it). Otherwise a new definition is hoisted using
133
- * `nameFor`. The plan is then applied per node with {@link applyDedupe}.
152
+ * is a named top-level schema, the first one becomes the canonical (so other top-level
153
+ * duplicates and inline copies turn into references to it). Every other top-level name with
154
+ * the same content is recorded in `aliasNames`, so refs to it can be repointed at the
155
+ * canonical. Otherwise a new definition is hoisted using `nameFor`. The plan is then applied
156
+ * per node with {@link applyDedupe}.
134
157
  *
135
158
  * @example
136
159
  * ```ts
@@ -149,7 +172,7 @@ export function buildDedupePlan(roots: ReadonlyArray<Node>, options: BuildDedupe
149
172
  type Group = {
150
173
  count: number
151
174
  representative: SchemaNode
152
- topLevelName?: string
175
+ topLevelNames: Array<string>
153
176
  }
154
177
  const groups = new Map<string, Group>()
155
178
 
@@ -161,9 +184,9 @@ export function buildDedupePlan(roots: ReadonlyArray<Node>, options: BuildDedupe
161
184
  const group = groups.get(signature)
162
185
  if (group) {
163
186
  group.count++
164
- if (isTopLevel && !group.topLevelName) group.topLevelName = schemaNode.name!
187
+ if (isTopLevel) group.topLevelNames.push(schemaNode.name!)
165
188
  } else {
166
- groups.set(signature, { count: 1, representative: schemaNode, topLevelName: isTopLevel ? schemaNode.name! : undefined })
189
+ groups.set(signature, { count: 1, representative: schemaNode, topLevelNames: isTopLevel ? [schemaNode.name!] : [] })
167
190
  }
168
191
  }
169
192
 
@@ -175,13 +198,19 @@ export function buildDedupePlan(roots: ReadonlyArray<Node>, options: BuildDedupe
175
198
  }
176
199
 
177
200
  const canonicalBySignature = new Map<string, DedupeCanonical>()
201
+ const aliasNames = new Map<string, DedupeCanonical>()
178
202
  const pendingHoists: Array<{ name: string; representative: SchemaNode }> = []
179
203
 
180
204
  for (const [signature, group] of groups) {
181
205
  if (group.count < minOccurrences) continue
182
206
 
183
- if (group.topLevelName) {
184
- canonicalBySignature.set(signature, { name: group.topLevelName, ref: refFor(group.topLevelName) })
207
+ const [firstName, ...duplicateNames] = group.topLevelNames
208
+ if (firstName) {
209
+ const canonical: DedupeCanonical = { name: firstName, ref: refFor(firstName) }
210
+ canonicalBySignature.set(signature, canonical)
211
+ for (const duplicate of duplicateNames) {
212
+ aliasNames.set(duplicate, canonical)
213
+ }
185
214
  continue
186
215
  }
187
216
 
@@ -194,7 +223,9 @@ export function buildDedupePlan(roots: ReadonlyArray<Node>, options: BuildDedupe
194
223
 
195
224
  // Build hoisted definitions only after every canonical name is known, so nested
196
225
  // duplicates inside a definition also resolve to refs.
197
- const hoisted = pendingHoists.map(({ name, representative }) => cleanDefinition(applyDedupe(representative, canonicalBySignature, true), name))
226
+ const hoisted = pendingHoists.map(({ name, representative }) =>
227
+ cleanDefinition(applyDedupe(representative, { canonicalBySignature, aliasNames }, true), name),
228
+ )
198
229
 
199
- return { canonicalBySignature, hoisted }
230
+ return { canonicalBySignature, aliasNames, hoisted }
200
231
  }
package/src/types.ts CHANGED
@@ -1,4 +1,4 @@
1
- export type { DedupePlan } from './dedupe.ts'
1
+ export type { DedupeCanonical, DedupeLookups, DedupePlan } from './dedupe.ts'
2
2
  export type { SchemaDialect } from './dialect.ts'
3
3
  export type { DispatchRule } from './dispatch.ts'
4
4
  export type { DistributiveOmit } from './factory.ts'