@soda-gql/colocation-tools 0.6.0 → 0.7.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.
package/README.md CHANGED
@@ -26,12 +26,12 @@ import { userFragment } from "./graphql-system";
26
26
 
27
27
  // Create a projection with paths and handle function
28
28
  const userProjection = createProjection(userFragment, {
29
- paths: ["$.user.id", "$.user.name"],
29
+ paths: ["$.user"],
30
30
  handle: (result) => {
31
31
  if (result.isError()) return { error: result.error, user: null };
32
32
  if (result.isEmpty()) return { error: null, user: null };
33
- const data = result.unwrap();
34
- return { error: null, user: data };
33
+ const [user] = result.unwrap(); // tuple of values for each path
34
+ return { error: null, user };
35
35
  },
36
36
  });
37
37
 
@@ -79,7 +79,8 @@ export const userCardProjection = createProjection(userCardFragment, {
79
79
  handle: (result) => {
80
80
  if (result.isError()) return { error: result.error, user: null };
81
81
  if (result.isEmpty()) return { error: null, user: null };
82
- return { error: null, user: result.unwrap().user };
82
+ const [user] = result.unwrap();
83
+ return { error: null, user };
83
84
  },
84
85
  });
85
86
  ```
@@ -133,12 +134,13 @@ import { createProjection } from "@soda-gql/colocation-tools";
133
134
 
134
135
  const projection = createProjection(fragment, {
135
136
  // Field paths to extract (must start with "$.")
136
- paths: ["$.user.id", "$.user.name"],
137
- // Handler to transform the sliced result
137
+ paths: ["$.user"],
138
+ // Handler to transform the sliced result (receives tuple of values for each path)
138
139
  handle: (result) => {
139
140
  if (result.isError()) return { error: result.error, data: null };
140
141
  if (result.isEmpty()) return { error: null, data: null };
141
- return { error: null, data: result.unwrap() };
142
+ const [user] = result.unwrap();
143
+ return { error: null, data: user };
142
144
  },
143
145
  });
144
146
  ```
@@ -164,7 +166,8 @@ export const postListFragment = gql
164
166
  handle: (result) => {
165
167
  if (result.isError()) return { error: result.error, posts: null };
166
168
  if (result.isEmpty()) return { error: null, posts: null };
167
- return { error: null, posts: result.unwrap().user?.posts ?? [] };
169
+ const [posts] = result.unwrap();
170
+ return { error: null, posts: posts ?? [] };
168
171
  },
169
172
  }),
170
173
  );
package/dist/index.cjs CHANGED
@@ -30,10 +30,10 @@ function createProjectionPath(path) {
30
30
  * Creates a type-safe projection from a Fragment.
31
31
  *
32
32
  * The projection extracts and transforms data from GraphQL execution results,
33
- * with full type inference from the Fragment's output type.
33
+ * with full type inference from the Fragment's field structure and output type.
34
34
  *
35
- * Note: The Fragment parameter is used only for type inference.
36
- * The actual paths must be specified explicitly.
35
+ * - Paths are validated against Fragment's TFields via `ReturnType<Fragment["spread"]>`
36
+ * - Handler receives types inferred from the specified paths
37
37
  *
38
38
  * @param _fragment - The Fragment to infer types from (used for type inference only)
39
39
  * @param options - Projection options including paths and handle function
@@ -51,12 +51,12 @@ function createProjectionPath(path) {
51
51
  * );
52
52
  *
53
53
  * const userProjection = createProjection(userFragment, {
54
- * paths: ["$.user"],
54
+ * paths: ["$.user.id", "$.user.name"],
55
55
  * handle: (result) => {
56
- * if (result.isError()) return { error: result.error, user: null };
57
- * if (result.isEmpty()) return { error: null, user: null };
58
- * const data = result.unwrap();
59
- * return { error: null, user: data.user };
56
+ * if (result.isError()) return { error: result.error, data: null };
57
+ * if (result.isEmpty()) return { error: null, data: null };
58
+ * const [id, name] = result.unwrap(); // tuple: [string, string]
59
+ * return { error: null, data: { id, name } };
60
60
  * },
61
61
  * });
62
62
  * ```
@@ -64,6 +64,21 @@ function createProjectionPath(path) {
64
64
  const createProjection = (_fragment, options) => {
65
65
  return new Projection(options.paths, options.handle);
66
66
  };
67
+ /**
68
+ * Creates a projection attachment for use with Fragment.attach().
69
+ *
70
+ * @example
71
+ * ```typescript
72
+ * const fragment = gql(({ fragment }) =>
73
+ * fragment.Query({
74
+ * fields: ({ f }) => ({ ...f.user()(({ f }) => ({ ...f.id() })) }),
75
+ * })
76
+ * ).attach(createProjectionAttachment({
77
+ * paths: ["$.user.id"],
78
+ * handle: (result) => result.isSuccess() ? result.unwrap()[0] : null,
79
+ * }));
80
+ * ```
81
+ */
67
82
  const createProjectionAttachment = (options) => {
68
83
  return {
69
84
  name: "projection",
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["projector: (result: AnySlicedExecutionResult) => TProjected","paths","type: \"success\" | \"error\" | \"empty\"","data: TData","extensions?: unknown","error: NormalizedError","errorMaps: { [label: string]: { [path: string]: { error: GraphQLFormattedError }[] } }","current: unknown"],"sources":["../src/projection.ts","../src/create-projection.ts","../src/utils/map-values.ts","../src/projection-path-graph.ts","../src/sliced-execution-result.ts","../src/parse-execution-result.ts"],"sourcesContent":["import type { AnySlicedExecutionResult } from \"./sliced-execution-result\";\nimport type { Tuple } from \"./utils/type-utils\";\n\n/** Shape of a single selection slice projection. */\n// biome-ignore lint/suspicious/noExplicitAny: Type alias for any Projection regardless of projected type\nexport type AnyProjection = Projection<any>;\n\ndeclare const __PROJECTION_BRAND__: unique symbol;\n/**\n * Nominal type representing any slice selection regardless of schema specifics.\n * Encodes how individual slices map a concrete field path to a projection\n * function. Multiple selections allow slices to expose several derived values.\n */\nexport class Projection<TProjected> {\n declare readonly [__PROJECTION_BRAND__]: void;\n\n declare readonly $infer: { readonly output: TProjected };\n\n constructor(\n paths: Tuple<string>,\n public readonly projector: (result: AnySlicedExecutionResult) => TProjected,\n ) {\n this.paths = paths.map((path) => createProjectionPath(path));\n\n Object.defineProperty(this, \"$infer\", {\n get() {\n throw new Error(\"This property is only for type meta. Do not access this property directly.\");\n },\n });\n }\n\n public readonly paths: ProjectionPath[];\n}\n\nexport type ProjectionPath = {\n full: string;\n segments: Tuple<string>;\n};\n\nfunction createProjectionPath(path: string): ProjectionPath {\n const segments = path.split(\".\");\n if (path === \"$\" || segments.length <= 1) {\n throw new Error(\"Field path must not be only $ or empty\");\n }\n\n return {\n full: path,\n segments: segments.slice(1) as Tuple<string>,\n };\n}\n\nexport type InferExecutionResultProjection<TProjection extends AnyProjection> = ReturnType<TProjection[\"projector\"]>;\n","import type { Fragment, GqlElementAttachment } from \"@soda-gql/core\";\nimport { Projection } from \"./projection\";\nimport type { SlicedExecutionResult } from \"./sliced-execution-result\";\nimport type { Tuple } from \"./utils/type-utils\";\n\n// biome-ignore lint/suspicious/noExplicitAny: Type alias for any Fragment regardless of type parameters\ntype AnyFragment = Fragment<string, any, any, any>;\n\n/**\n * Options for creating a projection from a Fragment.\n */\nexport type CreateProjectionOptions<TOutput extends object, TProjected> = {\n /**\n * Field paths to extract from the execution result.\n * Each path starts with \"$.\" and follows the field selection structure.\n *\n * @example\n * ```typescript\n * paths: [\"$.user.id\", \"$.user.name\"]\n * ```\n */\n paths: Tuple<string>;\n\n /**\n * Handler function to transform the sliced execution result.\n * Receives a SlicedExecutionResult with the Fragment's output type.\n * Handles all cases: success, error, and empty.\n *\n * @example\n * ```typescript\n * handle: (result) => {\n * if (result.isError()) return { error: result.error, data: null };\n * if (result.isEmpty()) return { error: null, data: null };\n * const data = result.unwrap();\n * return { error: null, data: { userId: data.user.id } };\n * }\n * ```\n */\n handle: (result: SlicedExecutionResult<TOutput>) => TProjected;\n};\n\n/**\n * Creates a type-safe projection from a Fragment.\n *\n * The projection extracts and transforms data from GraphQL execution results,\n * with full type inference from the Fragment's output type.\n *\n * Note: The Fragment parameter is used only for type inference.\n * The actual paths must be specified explicitly.\n *\n * @param _fragment - The Fragment to infer types from (used for type inference only)\n * @param options - Projection options including paths and handle function\n * @returns A Projection that can be used with createExecutionResultParser\n *\n * @example\n * ```typescript\n * const userFragment = gql(({ fragment }) =>\n * fragment.Query({\n * variables: { ... },\n * fields: ({ f, $ }) => ({\n * ...f.user({ id: $.userId })(({ f }) => ({ ...f.id(), ...f.name() })),\n * }),\n * })\n * );\n *\n * const userProjection = createProjection(userFragment, {\n * paths: [\"$.user\"],\n * handle: (result) => {\n * if (result.isError()) return { error: result.error, user: null };\n * if (result.isEmpty()) return { error: null, user: null };\n * const data = result.unwrap();\n * return { error: null, user: data.user };\n * },\n * });\n * ```\n */\nexport const createProjection = <TFragment extends AnyFragment, TProjected>(\n _fragment: TFragment,\n options: CreateProjectionOptions<TFragment[\"$infer\"][\"output\"], TProjected>,\n): Projection<TProjected> => {\n return new Projection(options.paths, options.handle);\n};\n\nexport const createProjectionAttachment = <TFragment extends AnyFragment, TProjected>(\n options: CreateProjectionOptions<NoInfer<TFragment>[\"$infer\"][\"output\"], TProjected>,\n): GqlElementAttachment<TFragment, \"projection\", Projection<TProjected>> => {\n return {\n name: \"projection\",\n createValue: (fragment) => createProjection(fragment, options),\n };\n};\n","type ArgEntries<T extends object> = { [K in keyof T]-?: [value: T[K], key: K] }[keyof T];\ntype Entries<T extends object> = { [K in keyof T]: [key: K, value: T[K]] }[keyof T];\n\nexport function mapValues<TObject extends object, TMappedValue>(\n obj: TObject,\n fn: (...args: ArgEntries<TObject>) => TMappedValue,\n): {\n [K in keyof TObject]: TMappedValue;\n} {\n return Object.fromEntries((Object.entries(obj) as Entries<TObject>[]).map(([key, value]) => [key, fn(value, key)])) as {\n [K in keyof TObject]: TMappedValue;\n };\n}\n","import type { AnyProjection } from \"./projection\";\nimport { mapValues } from \"./utils/map-values\";\n\n/**\n * Node in the projection path graph tree.\n * Used for mapping GraphQL errors and data to their corresponding slices.\n */\nexport type ProjectionPathGraphNode = {\n readonly matches: { label: string; path: string; exact: boolean }[];\n readonly children: { readonly [segment: string]: ProjectionPathGraphNode };\n};\n\n/**\n * Payload from a slice that contains projection.\n */\nexport type AnySlicePayload = {\n readonly projection: AnyProjection;\n};\n\nexport type AnySlicePayloads = Record<string, AnySlicePayload>;\n\ntype ExecutionResultProjectionPathGraphIntermediate = {\n [segment: string]: { label: string; raw: string; segments: string[] }[];\n};\n\nfunction createPathGraph(paths: ExecutionResultProjectionPathGraphIntermediate[string]): ProjectionPathGraphNode {\n const intermediate = paths.reduce(\n (acc: ExecutionResultProjectionPathGraphIntermediate, { label, raw, segments: [segment, ...segments] }) => {\n if (segment) {\n (acc[segment] || (acc[segment] = [])).push({ label, raw, segments });\n }\n return acc;\n },\n {},\n );\n\n return {\n matches: paths.map(({ label, raw, segments }) => ({ label, path: raw, exact: segments.length === 0 })),\n children: mapValues(intermediate, (paths) => createPathGraph(paths)),\n } satisfies ProjectionPathGraphNode;\n}\n\n/**\n * Creates a projection path graph from slice entries with field prefixing.\n * Each slice's paths are prefixed with the slice label for disambiguation.\n */\nexport function createPathGraphFromSliceEntries(fragments: AnySlicePayloads) {\n const paths = Object.entries(fragments).flatMap(([label, slice]) =>\n Array.from(\n new Map(\n slice.projection.paths.map(({ full: raw, segments }) => {\n const [first, ...rest] = segments;\n return [raw, { label, raw, segments: [`${label}_${first}`, ...rest] }];\n }),\n ).values(),\n ),\n );\n\n return createPathGraph(paths);\n}\n","/** Result-like wrapper types returned from slice projections. */\n\nimport type { NormalizedError } from \"./types\";\n\n// biome-ignore lint/suspicious/noExplicitAny: Type alias for any SlicedExecutionResult regardless of data type\nexport type AnySlicedExecutionResult = SlicedExecutionResult<any>;\n\n/**\n * Internal discriminated union describing the Result-like wrapper exposed to\n * slice selection callbacks.\n */\nexport type AnySlicedExecutionResultRecord = {\n [path: string]: AnySlicedExecutionResult;\n};\n\nexport type SafeUnwrapResult<TTransformed, TError> =\n | {\n data?: never;\n error?: never;\n }\n | {\n data: TTransformed;\n error?: never;\n }\n | {\n data?: never;\n error: TError;\n };\n\n/** Utility signature returned by the safe unwrap helper. */\ntype SlicedExecutionResultCommon<TData, TError> = {\n safeUnwrap<TTransformed>(transform: (data: TData) => TTransformed): SafeUnwrapResult<TTransformed, TError>;\n};\n\n/** Public union used by selection callbacks to inspect data, empty, or error states. */\nexport type SlicedExecutionResult<TData> =\n | SlicedExecutionResultEmpty<TData>\n | SlicedExecutionResultSuccess<TData>\n | SlicedExecutionResultError<TData>;\n\n/** Runtime guard interface shared by all slice result variants. */\nclass SlicedExecutionResultGuards<TData> {\n isSuccess(): this is SlicedExecutionResultSuccess<TData> {\n return this.type === \"success\";\n }\n isError(): this is SlicedExecutionResultError<TData> {\n return this.type === \"error\";\n }\n isEmpty(): this is SlicedExecutionResultEmpty<TData> {\n return this.type === \"empty\";\n }\n\n constructor(private readonly type: \"success\" | \"error\" | \"empty\") {}\n}\n\n/** Variant representing an empty payload (no data, no error). */\nexport class SlicedExecutionResultEmpty<TData>\n extends SlicedExecutionResultGuards<TData>\n implements SlicedExecutionResultCommon<TData, NormalizedError>\n{\n constructor() {\n super(\"empty\");\n }\n\n unwrap(): null {\n return null;\n }\n\n safeUnwrap() {\n return {\n data: undefined,\n error: undefined,\n };\n }\n}\n\n/** Variant representing a successful payload. */\nexport class SlicedExecutionResultSuccess<TData>\n extends SlicedExecutionResultGuards<TData>\n implements SlicedExecutionResultCommon<TData, NormalizedError>\n{\n constructor(\n public readonly data: TData,\n public readonly extensions?: unknown,\n ) {\n super(\"success\");\n }\n\n unwrap(): TData {\n return this.data;\n }\n\n safeUnwrap<TTransformed>(transform: (data: TData) => TTransformed) {\n return {\n data: transform(this.data),\n error: undefined,\n };\n }\n}\n\n/** Variant representing an error payload. */\nexport class SlicedExecutionResultError<TData>\n extends SlicedExecutionResultGuards<TData>\n implements SlicedExecutionResultCommon<TData, NormalizedError>\n{\n constructor(\n public readonly error: NormalizedError,\n public readonly extensions?: unknown,\n ) {\n super(\"error\");\n }\n\n unwrap(): never {\n throw this.error;\n }\n\n safeUnwrap() {\n return {\n data: undefined,\n error: this.error,\n };\n }\n}\n","import type { GraphQLFormattedError } from \"graphql\";\nimport { type AnySlicePayloads, createPathGraphFromSliceEntries, type ProjectionPathGraphNode } from \"./projection-path-graph\";\nimport { SlicedExecutionResultEmpty, SlicedExecutionResultError, SlicedExecutionResultSuccess } from \"./sliced-execution-result\";\nimport type { NormalizedExecutionResult } from \"./types\";\n\n// Internal function to build path graph from slices\nconst createPathGraphFromSlices = createPathGraphFromSliceEntries;\n\nfunction* generateErrorMapEntries(errors: readonly GraphQLFormattedError[], projectionPathGraph: ProjectionPathGraphNode) {\n for (const error of errors) {\n const errorPath = error.path ?? [];\n let stack = projectionPathGraph;\n\n for (\n let i = 0;\n // i <= errorPath.length to handle the case where the error path is empty\n i <= errorPath.length;\n i++\n ) {\n const segment = errorPath[i];\n\n if (\n // the end of the path\n segment == null ||\n // FieldPath does not support index access. We treat it as the end of the path.\n typeof segment === \"number\"\n ) {\n yield* stack.matches.map(({ label, path }) => ({ label, path, error }));\n break;\n }\n\n yield* stack.matches.filter(({ exact }) => exact).map(({ label, path }) => ({ label, path, error }));\n\n const next = stack.children[segment];\n if (!next) {\n break;\n }\n\n stack = next;\n }\n }\n}\n\nconst createErrorMaps = (errors: readonly GraphQLFormattedError[] | undefined, projectionPathGraph: ProjectionPathGraphNode) => {\n const errorMaps: { [label: string]: { [path: string]: { error: GraphQLFormattedError }[] } } = {};\n for (const { label, path, error } of generateErrorMapEntries(errors ?? [], projectionPathGraph)) {\n const mapPerLabel = errorMaps[label] || (errorMaps[label] = {});\n const mapPerPath = mapPerLabel[path] || (mapPerLabel[path] = []);\n mapPerPath.push({ error });\n }\n return errorMaps;\n};\n\nconst accessDataByPathSegments = (data: object, pathSegments: string[]) => {\n let current: unknown = data;\n\n for (const segment of pathSegments) {\n if (current == null) {\n return { error: new Error(\"No data\") };\n }\n\n if (typeof current !== \"object\") {\n return { error: new Error(\"Incorrect data type\") };\n }\n\n if (Array.isArray(current)) {\n return { error: new Error(\"Incorrect data type\") };\n }\n\n current = (current as Record<string, unknown>)[segment];\n }\n\n return { data: current };\n};\n\n/**\n * Creates an execution result parser for composed operations.\n * The parser maps GraphQL errors and data to their corresponding slices\n * based on the projection path graph.\n *\n * @param slices - Object mapping labels to projections\n * @returns A parser function that takes a NormalizedExecutionResult and returns parsed slices\n *\n * @example\n * ```typescript\n * const parser = createExecutionResultParser({\n * userCard: userCardProjection,\n * posts: postsProjection,\n * });\n *\n * const results = parser({\n * type: \"graphql\",\n * body: { data, errors },\n * });\n * ```\n */\nexport const createExecutionResultParser = <TSlices extends AnySlicePayloads>(slices: TSlices) => {\n // Build path graph from slices\n const projectionPathGraph = createPathGraphFromSlices(slices);\n const fragments = slices;\n const prepare = (result: NormalizedExecutionResult<object, object>) => {\n if (result.type === \"graphql\") {\n const errorMaps = createErrorMaps(result.body.errors, projectionPathGraph);\n\n return { ...result, errorMaps };\n }\n\n if (result.type === \"non-graphql-error\") {\n return { ...result, error: new SlicedExecutionResultError({ type: \"non-graphql-error\", error: result.error }) };\n }\n\n if (result.type === \"empty\") {\n return { ...result, error: new SlicedExecutionResultEmpty() };\n }\n\n throw new Error(\"Invalid result type\", { cause: result satisfies never });\n };\n\n return (result: NormalizedExecutionResult<object, object>) => {\n const prepared = prepare(result);\n\n const entries = Object.entries(fragments).map(([label, fragment]) => {\n const { projection } = fragment;\n\n if (prepared.type === \"graphql\") {\n const matchedErrors = projection.paths.flatMap(({ full: raw }) => prepared.errorMaps[label]?.[raw] ?? []);\n const uniqueErrors = Array.from(new Set(matchedErrors.map(({ error }) => error)).values());\n\n if (uniqueErrors.length > 0) {\n return [label, projection.projector(new SlicedExecutionResultError({ type: \"graphql-error\", errors: uniqueErrors }))];\n }\n\n // Apply label prefix to first segment for data access (matching $colocate prefix pattern)\n const dataResults = projection.paths.map(({ segments }) => {\n const [first, ...rest] = segments;\n const prefixedSegments = [`${label}_${first}`, ...rest];\n return prepared.body.data\n ? accessDataByPathSegments(prepared.body.data, prefixedSegments)\n : { error: new Error(\"No data\") };\n });\n if (dataResults.some(({ error }) => error)) {\n const errors = dataResults.flatMap(({ error }) => (error ? [error] : []));\n return [label, projection.projector(new SlicedExecutionResultError({ type: \"parse-error\", errors }))];\n }\n\n const dataList = dataResults.map(({ data }) => data);\n return [label, projection.projector(new SlicedExecutionResultSuccess(dataList))];\n }\n\n if (prepared.type === \"non-graphql-error\") {\n return [label, projection.projector(prepared.error)];\n }\n\n if (prepared.type === \"empty\") {\n return [label, projection.projector(prepared.error)];\n }\n\n throw new Error(\"Invalid result type\", { cause: prepared satisfies never });\n });\n\n return Object.fromEntries(entries);\n };\n};\n"],"mappings":";;;;;;;AAaA,IAAa,aAAb,MAAoC;CAKlC,YACE,OACA,AAAgBA,WAChB;EADgB;AAEhB,OAAK,QAAQ,MAAM,KAAK,SAAS,qBAAqB,KAAK,CAAC;AAE5D,SAAO,eAAe,MAAM,UAAU,EACpC,MAAM;AACJ,SAAM,IAAI,MAAM,6EAA6E;KAEhG,CAAC;;CAGJ,AAAgB;;AAQlB,SAAS,qBAAqB,MAA8B;CAC1D,MAAM,WAAW,KAAK,MAAM,IAAI;AAChC,KAAI,SAAS,OAAO,SAAS,UAAU,EACrC,OAAM,IAAI,MAAM,yCAAyC;AAG3D,QAAO;EACL,MAAM;EACN,UAAU,SAAS,MAAM,EAAE;EAC5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC4BH,MAAa,oBACX,WACA,YAC2B;AAC3B,QAAO,IAAI,WAAW,QAAQ,OAAO,QAAQ,OAAO;;AAGtD,MAAa,8BACX,YAC0E;AAC1E,QAAO;EACL,MAAM;EACN,cAAc,aAAa,iBAAiB,UAAU,QAAQ;EAC/D;;;;;ACtFH,SAAgB,UACd,KACA,IAGA;AACA,QAAO,OAAO,YAAa,OAAO,QAAQ,IAAI,CAAwB,KAAK,CAAC,KAAK,WAAW,CAAC,KAAK,GAAG,OAAO,IAAI,CAAC,CAAC,CAAC;;;;;ACgBrH,SAAS,gBAAgB,OAAwF;CAC/G,MAAM,eAAe,MAAM,QACxB,KAAqD,EAAE,OAAO,KAAK,UAAU,CAAC,SAAS,GAAG,gBAAgB;AACzG,MAAI,QACF,EAAC,IAAI,aAAa,IAAI,WAAW,EAAE,GAAG,KAAK;GAAE;GAAO;GAAK;GAAU,CAAC;AAEtE,SAAO;IAET,EAAE,CACH;AAED,QAAO;EACL,SAAS,MAAM,KAAK,EAAE,OAAO,KAAK,gBAAgB;GAAE;GAAO,MAAM;GAAK,OAAO,SAAS,WAAW;GAAG,EAAE;EACtG,UAAU,UAAU,eAAe,YAAU,gBAAgBC,QAAM,CAAC;EACrE;;;;;;AAOH,SAAgB,gCAAgC,WAA6B;AAY3E,QAAO,gBAXO,OAAO,QAAQ,UAAU,CAAC,SAAS,CAAC,OAAO,WACvD,MAAM,KACJ,IAAI,IACF,MAAM,WAAW,MAAM,KAAK,EAAE,MAAM,KAAK,eAAe;EACtD,MAAM,CAAC,OAAO,GAAG,QAAQ;AACzB,SAAO,CAAC,KAAK;GAAE;GAAO;GAAK,UAAU,CAAC,GAAG,MAAM,GAAG,SAAS,GAAG,KAAK;GAAE,CAAC;GACtE,CACH,CAAC,QAAQ,CACX,CACF,CAE4B;;;;;;ACjB/B,IAAM,8BAAN,MAAyC;CACvC,YAAyD;AACvD,SAAO,KAAK,SAAS;;CAEvB,UAAqD;AACnD,SAAO,KAAK,SAAS;;CAEvB,UAAqD;AACnD,SAAO,KAAK,SAAS;;CAGvB,YAAY,AAAiBC,MAAqC;EAArC;;;;AAI/B,IAAa,6BAAb,cACU,4BAEV;CACE,cAAc;AACZ,QAAM,QAAQ;;CAGhB,SAAe;AACb,SAAO;;CAGT,aAAa;AACX,SAAO;GACL,MAAM;GACN,OAAO;GACR;;;;AAKL,IAAa,+BAAb,cACU,4BAEV;CACE,YACE,AAAgBC,MAChB,AAAgBC,YAChB;AACA,QAAM,UAAU;EAHA;EACA;;CAKlB,SAAgB;AACd,SAAO,KAAK;;CAGd,WAAyB,WAA0C;AACjE,SAAO;GACL,MAAM,UAAU,KAAK,KAAK;GAC1B,OAAO;GACR;;;;AAKL,IAAa,6BAAb,cACU,4BAEV;CACE,YACE,AAAgBC,OAChB,AAAgBD,YAChB;AACA,QAAM,QAAQ;EAHE;EACA;;CAKlB,SAAgB;AACd,QAAM,KAAK;;CAGb,aAAa;AACX,SAAO;GACL,MAAM;GACN,OAAO,KAAK;GACb;;;;;;AClHL,MAAM,4BAA4B;AAElC,UAAU,wBAAwB,QAA0C,qBAA8C;AACxH,MAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,YAAY,MAAM,QAAQ,EAAE;EAClC,IAAI,QAAQ;AAEZ,OACE,IAAI,IAAI,GAER,KAAK,UAAU,QACf,KACA;GACA,MAAM,UAAU,UAAU;AAE1B,OAEE,WAAW,QAEX,OAAO,YAAY,UACnB;AACA,WAAO,MAAM,QAAQ,KAAK,EAAE,OAAO,YAAY;KAAE;KAAO;KAAM;KAAO,EAAE;AACvE;;AAGF,UAAO,MAAM,QAAQ,QAAQ,EAAE,YAAY,MAAM,CAAC,KAAK,EAAE,OAAO,YAAY;IAAE;IAAO;IAAM;IAAO,EAAE;GAEpG,MAAM,OAAO,MAAM,SAAS;AAC5B,OAAI,CAAC,KACH;AAGF,WAAQ;;;;AAKd,MAAM,mBAAmB,QAAsD,wBAAiD;CAC9H,MAAME,YAAyF,EAAE;AACjG,MAAK,MAAM,EAAE,OAAO,MAAM,WAAW,wBAAwB,UAAU,EAAE,EAAE,oBAAoB,EAAE;EAC/F,MAAM,cAAc,UAAU,WAAW,UAAU,SAAS,EAAE;AAE9D,GADmB,YAAY,UAAU,YAAY,QAAQ,EAAE,GACpD,KAAK,EAAE,OAAO,CAAC;;AAE5B,QAAO;;AAGT,MAAM,4BAA4B,MAAc,iBAA2B;CACzE,IAAIC,UAAmB;AAEvB,MAAK,MAAM,WAAW,cAAc;AAClC,MAAI,WAAW,KACb,QAAO,EAAE,uBAAO,IAAI,MAAM,UAAU,EAAE;AAGxC,MAAI,OAAO,YAAY,SACrB,QAAO,EAAE,uBAAO,IAAI,MAAM,sBAAsB,EAAE;AAGpD,MAAI,MAAM,QAAQ,QAAQ,CACxB,QAAO,EAAE,uBAAO,IAAI,MAAM,sBAAsB,EAAE;AAGpD,YAAW,QAAoC;;AAGjD,QAAO,EAAE,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;AAwB1B,MAAa,+BAAiE,WAAoB;CAEhG,MAAM,sBAAsB,0BAA0B,OAAO;CAC7D,MAAM,YAAY;CAClB,MAAM,WAAW,WAAsD;AACrE,MAAI,OAAO,SAAS,WAAW;GAC7B,MAAM,YAAY,gBAAgB,OAAO,KAAK,QAAQ,oBAAoB;AAE1E,UAAO;IAAE,GAAG;IAAQ;IAAW;;AAGjC,MAAI,OAAO,SAAS,oBAClB,QAAO;GAAE,GAAG;GAAQ,OAAO,IAAI,2BAA2B;IAAE,MAAM;IAAqB,OAAO,OAAO;IAAO,CAAC;GAAE;AAGjH,MAAI,OAAO,SAAS,QAClB,QAAO;GAAE,GAAG;GAAQ,OAAO,IAAI,4BAA4B;GAAE;AAG/D,QAAM,IAAI,MAAM,uBAAuB,EAAE,OAAO,QAAwB,CAAC;;AAG3E,SAAQ,WAAsD;EAC5D,MAAM,WAAW,QAAQ,OAAO;EAEhC,MAAM,UAAU,OAAO,QAAQ,UAAU,CAAC,KAAK,CAAC,OAAO,cAAc;GACnE,MAAM,EAAE,eAAe;AAEvB,OAAI,SAAS,SAAS,WAAW;IAC/B,MAAM,gBAAgB,WAAW,MAAM,SAAS,EAAE,MAAM,UAAU,SAAS,UAAU,SAAS,QAAQ,EAAE,CAAC;IACzG,MAAM,eAAe,MAAM,KAAK,IAAI,IAAI,cAAc,KAAK,EAAE,YAAY,MAAM,CAAC,CAAC,QAAQ,CAAC;AAE1F,QAAI,aAAa,SAAS,EACxB,QAAO,CAAC,OAAO,WAAW,UAAU,IAAI,2BAA2B;KAAE,MAAM;KAAiB,QAAQ;KAAc,CAAC,CAAC,CAAC;IAIvH,MAAM,cAAc,WAAW,MAAM,KAAK,EAAE,eAAe;KACzD,MAAM,CAAC,OAAO,GAAG,QAAQ;KACzB,MAAM,mBAAmB,CAAC,GAAG,MAAM,GAAG,SAAS,GAAG,KAAK;AACvD,YAAO,SAAS,KAAK,OACjB,yBAAyB,SAAS,KAAK,MAAM,iBAAiB,GAC9D,EAAE,uBAAO,IAAI,MAAM,UAAU,EAAE;MACnC;AACF,QAAI,YAAY,MAAM,EAAE,YAAY,MAAM,EAAE;KAC1C,MAAM,SAAS,YAAY,SAAS,EAAE,YAAa,QAAQ,CAAC,MAAM,GAAG,EAAE,CAAE;AACzE,YAAO,CAAC,OAAO,WAAW,UAAU,IAAI,2BAA2B;MAAE,MAAM;MAAe;MAAQ,CAAC,CAAC,CAAC;;IAGvG,MAAM,WAAW,YAAY,KAAK,EAAE,WAAW,KAAK;AACpD,WAAO,CAAC,OAAO,WAAW,UAAU,IAAI,6BAA6B,SAAS,CAAC,CAAC;;AAGlF,OAAI,SAAS,SAAS,oBACpB,QAAO,CAAC,OAAO,WAAW,UAAU,SAAS,MAAM,CAAC;AAGtD,OAAI,SAAS,SAAS,QACpB,QAAO,CAAC,OAAO,WAAW,UAAU,SAAS,MAAM,CAAC;AAGtD,SAAM,IAAI,MAAM,uBAAuB,EAAE,OAAO,UAA0B,CAAC;IAC3E;AAEF,SAAO,OAAO,YAAY,QAAQ"}
1
+ {"version":3,"file":"index.cjs","names":["projector: (result: AnySlicedExecutionResult) => TProjected","paths","type: \"success\" | \"error\" | \"empty\"","data: TData","extensions?: unknown","error: NormalizedError","errorMaps: { [label: string]: { [path: string]: { error: GraphQLFormattedError }[] } }","current: unknown"],"sources":["../src/projection.ts","../src/create-projection.ts","../src/utils/map-values.ts","../src/projection-path-graph.ts","../src/sliced-execution-result.ts","../src/parse-execution-result.ts"],"sourcesContent":["import type { AnySlicedExecutionResult } from \"./sliced-execution-result\";\nimport type { Tuple } from \"./utils/type-utils\";\n\n/** Shape of a single selection slice projection. */\n// biome-ignore lint/suspicious/noExplicitAny: Type alias for any Projection regardless of projected type\nexport type AnyProjection = Projection<any>;\n\ndeclare const __PROJECTION_BRAND__: unique symbol;\n/**\n * Nominal type representing any slice selection regardless of schema specifics.\n * Encodes how individual slices map a concrete field path to a projection\n * function. Multiple selections allow slices to expose several derived values.\n */\nexport class Projection<TProjected> {\n declare readonly [__PROJECTION_BRAND__]: void;\n\n declare readonly $infer: { readonly output: TProjected };\n\n constructor(\n paths: Tuple<string>,\n public readonly projector: (result: AnySlicedExecutionResult) => TProjected,\n ) {\n this.paths = paths.map((path) => createProjectionPath(path));\n\n Object.defineProperty(this, \"$infer\", {\n get() {\n throw new Error(\"This property is only for type meta. Do not access this property directly.\");\n },\n });\n }\n\n public readonly paths: ProjectionPath[];\n}\n\nexport type ProjectionPath = {\n full: string;\n segments: Tuple<string>;\n};\n\nfunction createProjectionPath(path: string): ProjectionPath {\n const segments = path.split(\".\");\n if (path === \"$\" || segments.length <= 1) {\n throw new Error(\"Field path must not be only $ or empty\");\n }\n\n return {\n full: path,\n segments: segments.slice(1) as Tuple<string>,\n };\n}\n\nexport type InferExecutionResultProjection<TProjection extends AnyProjection> = ReturnType<TProjection[\"projector\"]>;\n","import type { AnyFields, Fragment, GqlElementAttachment } from \"@soda-gql/core\";\nimport { Projection } from \"./projection\";\nimport type { SlicedExecutionResult } from \"./sliced-execution-result\";\nimport type { AvailableFieldPathOf } from \"./types/field-path\";\nimport type { InferPathsOutput } from \"./types/output-path\";\nimport type { Tuple } from \"./utils/type-utils\";\n\n// biome-ignore lint/suspicious/noExplicitAny: Type alias for any Fragment regardless of type parameters\ntype AnyFragment = Fragment<string, any, any, any>;\n\n/** Get TFields from Fragment via spread's return type. */\ntype FragmentFields<TFragment extends AnyFragment> = ReturnType<TFragment[\"spread\"]>;\n\n/**\n * Options for creating a projection from a Fragment.\n */\nexport type CreateProjectionOptions<\n TFields extends AnyFields,\n TOutput extends object,\n TPaths extends Tuple<AvailableFieldPathOf<TFields>>,\n TProjected,\n> = {\n /**\n * Field paths to extract from the execution result.\n * Each path starts with \"$.\" and follows the field selection structure.\n * Paths are type-checked against the Fragment's field structure.\n *\n * @example\n * ```typescript\n * paths: [\"$.user.id\", \"$.user.name\"]\n * ```\n */\n paths: TPaths;\n\n /**\n * Handler function to transform the sliced execution result.\n * Receives a SlicedExecutionResult with types inferred from the specified paths.\n * Handles all cases: success, error, and empty.\n *\n * @example\n * ```typescript\n * handle: (result) => {\n * if (result.isError()) return { error: result.error, data: null };\n * if (result.isEmpty()) return { error: null, data: null };\n * const [id, name] = result.unwrap(); // tuple of types from paths\n * return { error: null, data: { id, name } };\n * }\n * ```\n */\n handle: (result: SlicedExecutionResult<InferPathsOutput<TOutput, TPaths>>) => TProjected;\n};\n\n/**\n * Creates a type-safe projection from a Fragment.\n *\n * The projection extracts and transforms data from GraphQL execution results,\n * with full type inference from the Fragment's field structure and output type.\n *\n * - Paths are validated against Fragment's TFields via `ReturnType<Fragment[\"spread\"]>`\n * - Handler receives types inferred from the specified paths\n *\n * @param _fragment - The Fragment to infer types from (used for type inference only)\n * @param options - Projection options including paths and handle function\n * @returns A Projection that can be used with createExecutionResultParser\n *\n * @example\n * ```typescript\n * const userFragment = gql(({ fragment }) =>\n * fragment.Query({\n * variables: { ... },\n * fields: ({ f, $ }) => ({\n * ...f.user({ id: $.userId })(({ f }) => ({ ...f.id(), ...f.name() })),\n * }),\n * })\n * );\n *\n * const userProjection = createProjection(userFragment, {\n * paths: [\"$.user.id\", \"$.user.name\"],\n * handle: (result) => {\n * if (result.isError()) return { error: result.error, data: null };\n * if (result.isEmpty()) return { error: null, data: null };\n * const [id, name] = result.unwrap(); // tuple: [string, string]\n * return { error: null, data: { id, name } };\n * },\n * });\n * ```\n */\nexport const createProjection = <\n TFragment extends AnyFragment,\n const TPaths extends Tuple<AvailableFieldPathOf<FragmentFields<TFragment>>>,\n TProjected,\n>(\n _fragment: TFragment,\n options: CreateProjectionOptions<FragmentFields<TFragment>, TFragment[\"$infer\"][\"output\"], TPaths, TProjected>,\n): Projection<TProjected> => {\n return new Projection(options.paths, options.handle);\n};\n\n/**\n * Creates a projection attachment for use with Fragment.attach().\n *\n * @example\n * ```typescript\n * const fragment = gql(({ fragment }) =>\n * fragment.Query({\n * fields: ({ f }) => ({ ...f.user()(({ f }) => ({ ...f.id() })) }),\n * })\n * ).attach(createProjectionAttachment({\n * paths: [\"$.user.id\"],\n * handle: (result) => result.isSuccess() ? result.unwrap()[0] : null,\n * }));\n * ```\n */\nexport const createProjectionAttachment = <\n TFragment extends AnyFragment,\n const TPaths extends Tuple<AvailableFieldPathOf<FragmentFields<NoInfer<TFragment>>>>,\n TProjected,\n>(\n options: CreateProjectionOptions<\n FragmentFields<NoInfer<TFragment>>,\n NoInfer<TFragment>[\"$infer\"][\"output\"],\n TPaths,\n TProjected\n >,\n): GqlElementAttachment<TFragment, \"projection\", Projection<TProjected>> => {\n return {\n name: \"projection\",\n createValue: (fragment) => createProjection(fragment, options),\n };\n};\n","type ArgEntries<T extends object> = { [K in keyof T]-?: [value: T[K], key: K] }[keyof T];\ntype Entries<T extends object> = { [K in keyof T]: [key: K, value: T[K]] }[keyof T];\n\nexport function mapValues<TObject extends object, TMappedValue>(\n obj: TObject,\n fn: (...args: ArgEntries<TObject>) => TMappedValue,\n): {\n [K in keyof TObject]: TMappedValue;\n} {\n return Object.fromEntries((Object.entries(obj) as Entries<TObject>[]).map(([key, value]) => [key, fn(value, key)])) as {\n [K in keyof TObject]: TMappedValue;\n };\n}\n","import type { AnyProjection } from \"./projection\";\nimport { mapValues } from \"./utils/map-values\";\n\n/**\n * Node in the projection path graph tree.\n * Used for mapping GraphQL errors and data to their corresponding slices.\n */\nexport type ProjectionPathGraphNode = {\n readonly matches: { label: string; path: string; exact: boolean }[];\n readonly children: { readonly [segment: string]: ProjectionPathGraphNode };\n};\n\n/**\n * Payload from a slice that contains projection.\n */\nexport type AnySlicePayload = {\n readonly projection: AnyProjection;\n};\n\nexport type AnySlicePayloads = Record<string, AnySlicePayload>;\n\ntype ExecutionResultProjectionPathGraphIntermediate = {\n [segment: string]: { label: string; raw: string; segments: string[] }[];\n};\n\nfunction createPathGraph(paths: ExecutionResultProjectionPathGraphIntermediate[string]): ProjectionPathGraphNode {\n const intermediate = paths.reduce(\n (acc: ExecutionResultProjectionPathGraphIntermediate, { label, raw, segments: [segment, ...segments] }) => {\n if (segment) {\n (acc[segment] || (acc[segment] = [])).push({ label, raw, segments });\n }\n return acc;\n },\n {},\n );\n\n return {\n matches: paths.map(({ label, raw, segments }) => ({ label, path: raw, exact: segments.length === 0 })),\n children: mapValues(intermediate, (paths) => createPathGraph(paths)),\n } satisfies ProjectionPathGraphNode;\n}\n\n/**\n * Creates a projection path graph from slice entries with field prefixing.\n * Each slice's paths are prefixed with the slice label for disambiguation.\n */\nexport function createPathGraphFromSliceEntries(fragments: AnySlicePayloads) {\n const paths = Object.entries(fragments).flatMap(([label, slice]) =>\n Array.from(\n new Map(\n slice.projection.paths.map(({ full: raw, segments }) => {\n const [first, ...rest] = segments;\n return [raw, { label, raw, segments: [`${label}_${first}`, ...rest] }];\n }),\n ).values(),\n ),\n );\n\n return createPathGraph(paths);\n}\n","/** Result-like wrapper types returned from slice projections. */\n\nimport type { NormalizedError } from \"./types\";\n\n// biome-ignore lint/suspicious/noExplicitAny: Type alias for any SlicedExecutionResult regardless of data type\nexport type AnySlicedExecutionResult = SlicedExecutionResult<any>;\n\n/**\n * Internal discriminated union describing the Result-like wrapper exposed to\n * slice selection callbacks.\n */\nexport type AnySlicedExecutionResultRecord = {\n [path: string]: AnySlicedExecutionResult;\n};\n\nexport type SafeUnwrapResult<TTransformed, TError> =\n | {\n data?: never;\n error?: never;\n }\n | {\n data: TTransformed;\n error?: never;\n }\n | {\n data?: never;\n error: TError;\n };\n\n/** Utility signature returned by the safe unwrap helper. */\ntype SlicedExecutionResultCommon<TData, TError> = {\n safeUnwrap<TTransformed>(transform: (data: TData) => TTransformed): SafeUnwrapResult<TTransformed, TError>;\n};\n\n/** Public union used by selection callbacks to inspect data, empty, or error states. */\nexport type SlicedExecutionResult<TData> =\n | SlicedExecutionResultEmpty<TData>\n | SlicedExecutionResultSuccess<TData>\n | SlicedExecutionResultError<TData>;\n\n/** Runtime guard interface shared by all slice result variants. */\nclass SlicedExecutionResultGuards<TData> {\n isSuccess(): this is SlicedExecutionResultSuccess<TData> {\n return this.type === \"success\";\n }\n isError(): this is SlicedExecutionResultError<TData> {\n return this.type === \"error\";\n }\n isEmpty(): this is SlicedExecutionResultEmpty<TData> {\n return this.type === \"empty\";\n }\n\n constructor(private readonly type: \"success\" | \"error\" | \"empty\") {}\n}\n\n/** Variant representing an empty payload (no data, no error). */\nexport class SlicedExecutionResultEmpty<TData>\n extends SlicedExecutionResultGuards<TData>\n implements SlicedExecutionResultCommon<TData, NormalizedError>\n{\n constructor() {\n super(\"empty\");\n }\n\n unwrap(): null {\n return null;\n }\n\n safeUnwrap() {\n return {\n data: undefined,\n error: undefined,\n };\n }\n}\n\n/** Variant representing a successful payload. */\nexport class SlicedExecutionResultSuccess<TData>\n extends SlicedExecutionResultGuards<TData>\n implements SlicedExecutionResultCommon<TData, NormalizedError>\n{\n constructor(\n public readonly data: TData,\n public readonly extensions?: unknown,\n ) {\n super(\"success\");\n }\n\n unwrap(): TData {\n return this.data;\n }\n\n safeUnwrap<TTransformed>(transform: (data: TData) => TTransformed) {\n return {\n data: transform(this.data),\n error: undefined,\n };\n }\n}\n\n/** Variant representing an error payload. */\nexport class SlicedExecutionResultError<TData>\n extends SlicedExecutionResultGuards<TData>\n implements SlicedExecutionResultCommon<TData, NormalizedError>\n{\n constructor(\n public readonly error: NormalizedError,\n public readonly extensions?: unknown,\n ) {\n super(\"error\");\n }\n\n unwrap(): never {\n throw this.error;\n }\n\n safeUnwrap() {\n return {\n data: undefined,\n error: this.error,\n };\n }\n}\n","import type { GraphQLFormattedError } from \"graphql\";\nimport { type AnySlicePayloads, createPathGraphFromSliceEntries, type ProjectionPathGraphNode } from \"./projection-path-graph\";\nimport { SlicedExecutionResultEmpty, SlicedExecutionResultError, SlicedExecutionResultSuccess } from \"./sliced-execution-result\";\nimport type { NormalizedExecutionResult } from \"./types\";\n\n// Internal function to build path graph from slices\nconst createPathGraphFromSlices = createPathGraphFromSliceEntries;\n\nfunction* generateErrorMapEntries(errors: readonly GraphQLFormattedError[], projectionPathGraph: ProjectionPathGraphNode) {\n for (const error of errors) {\n const errorPath = error.path ?? [];\n let stack = projectionPathGraph;\n\n for (\n let i = 0;\n // i <= errorPath.length to handle the case where the error path is empty\n i <= errorPath.length;\n i++\n ) {\n const segment = errorPath[i];\n\n if (\n // the end of the path\n segment == null ||\n // FieldPath does not support index access. We treat it as the end of the path.\n typeof segment === \"number\"\n ) {\n yield* stack.matches.map(({ label, path }) => ({ label, path, error }));\n break;\n }\n\n yield* stack.matches.filter(({ exact }) => exact).map(({ label, path }) => ({ label, path, error }));\n\n const next = stack.children[segment];\n if (!next) {\n break;\n }\n\n stack = next;\n }\n }\n}\n\nconst createErrorMaps = (errors: readonly GraphQLFormattedError[] | undefined, projectionPathGraph: ProjectionPathGraphNode) => {\n const errorMaps: { [label: string]: { [path: string]: { error: GraphQLFormattedError }[] } } = {};\n for (const { label, path, error } of generateErrorMapEntries(errors ?? [], projectionPathGraph)) {\n const mapPerLabel = errorMaps[label] || (errorMaps[label] = {});\n const mapPerPath = mapPerLabel[path] || (mapPerLabel[path] = []);\n mapPerPath.push({ error });\n }\n return errorMaps;\n};\n\nconst accessDataByPathSegments = (data: object, pathSegments: string[]) => {\n let current: unknown = data;\n\n for (const segment of pathSegments) {\n if (current == null) {\n return { error: new Error(\"No data\") };\n }\n\n if (typeof current !== \"object\") {\n return { error: new Error(\"Incorrect data type\") };\n }\n\n if (Array.isArray(current)) {\n return { error: new Error(\"Incorrect data type\") };\n }\n\n current = (current as Record<string, unknown>)[segment];\n }\n\n return { data: current };\n};\n\n/**\n * Creates an execution result parser for composed operations.\n * The parser maps GraphQL errors and data to their corresponding slices\n * based on the projection path graph.\n *\n * @param slices - Object mapping labels to projections\n * @returns A parser function that takes a NormalizedExecutionResult and returns parsed slices\n *\n * @example\n * ```typescript\n * const parser = createExecutionResultParser({\n * userCard: userCardProjection,\n * posts: postsProjection,\n * });\n *\n * const results = parser({\n * type: \"graphql\",\n * body: { data, errors },\n * });\n * ```\n */\nexport const createExecutionResultParser = <TSlices extends AnySlicePayloads>(slices: TSlices) => {\n // Build path graph from slices\n const projectionPathGraph = createPathGraphFromSlices(slices);\n const fragments = slices;\n const prepare = (result: NormalizedExecutionResult<object, object>) => {\n if (result.type === \"graphql\") {\n const errorMaps = createErrorMaps(result.body.errors, projectionPathGraph);\n\n return { ...result, errorMaps };\n }\n\n if (result.type === \"non-graphql-error\") {\n return { ...result, error: new SlicedExecutionResultError({ type: \"non-graphql-error\", error: result.error }) };\n }\n\n if (result.type === \"empty\") {\n return { ...result, error: new SlicedExecutionResultEmpty() };\n }\n\n throw new Error(\"Invalid result type\", { cause: result satisfies never });\n };\n\n return (result: NormalizedExecutionResult<object, object>) => {\n const prepared = prepare(result);\n\n const entries = Object.entries(fragments).map(([label, fragment]) => {\n const { projection } = fragment;\n\n if (prepared.type === \"graphql\") {\n const matchedErrors = projection.paths.flatMap(({ full: raw }) => prepared.errorMaps[label]?.[raw] ?? []);\n const uniqueErrors = Array.from(new Set(matchedErrors.map(({ error }) => error)).values());\n\n if (uniqueErrors.length > 0) {\n return [label, projection.projector(new SlicedExecutionResultError({ type: \"graphql-error\", errors: uniqueErrors }))];\n }\n\n // Apply label prefix to first segment for data access (matching $colocate prefix pattern)\n const dataResults = projection.paths.map(({ segments }) => {\n const [first, ...rest] = segments;\n const prefixedSegments = [`${label}_${first}`, ...rest];\n return prepared.body.data\n ? accessDataByPathSegments(prepared.body.data, prefixedSegments)\n : { error: new Error(\"No data\") };\n });\n if (dataResults.some(({ error }) => error)) {\n const errors = dataResults.flatMap(({ error }) => (error ? [error] : []));\n return [label, projection.projector(new SlicedExecutionResultError({ type: \"parse-error\", errors }))];\n }\n\n const dataList = dataResults.map(({ data }) => data);\n return [label, projection.projector(new SlicedExecutionResultSuccess(dataList))];\n }\n\n if (prepared.type === \"non-graphql-error\") {\n return [label, projection.projector(prepared.error)];\n }\n\n if (prepared.type === \"empty\") {\n return [label, projection.projector(prepared.error)];\n }\n\n throw new Error(\"Invalid result type\", { cause: prepared satisfies never });\n });\n\n return Object.fromEntries(entries);\n };\n};\n"],"mappings":"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"}
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { AnyFields, AnyGraphqlSchema, AnyNestedObject, Fragment, GqlElementAttachment, InferField } from "@soda-gql/core";
1
+ import { AnyFields, AnyNestedObject, Fragment, GqlElementAttachment } from "@soda-gql/core";
2
2
  import { FormattedExecutionResult, GraphQLFormattedError } from "graphql";
3
3
 
4
4
  //#region packages/colocation-tools/src/types.d.ts
@@ -130,25 +130,79 @@ type ProjectionPath = {
130
130
  };
131
131
  type InferExecutionResultProjection<TProjection extends AnyProjection> = ReturnType<TProjection["projector"]>;
132
132
  //#endregion
133
+ //#region packages/colocation-tools/src/types/field-path.d.ts
134
+ type AnyFieldPath = string;
135
+ /** Maximum recursion depth to prevent infinite type instantiation. */
136
+ type MaxDepth = [unknown, unknown, unknown, unknown, unknown];
137
+ /** Decrement depth counter for recursion limiting. */
138
+ type DecrementDepth<D extends readonly unknown[]> = D extends readonly [unknown, ...infer Rest] ? Rest : [];
139
+ /**
140
+ * Computes strongly typed "$.foo.bar" style selectors for a set of fields so
141
+ * slice result transforms can reference response paths safely.
142
+ *
143
+ * Note: TSchema is not needed - only uses TFields.object for nesting.
144
+ */
145
+ type AvailableFieldPathOf<TFields extends AnyFields> = AvailableFieldPathsInner<TFields, "$", MaxDepth>;
146
+ /** Recursive helper used to build path strings for nested selections. */
147
+ type AvailableFieldPathsInner<TFields extends AnyFields, TCurr extends AnyFieldPath, TDepth extends readonly unknown[]> = TDepth extends readonly [] ? never : { readonly [TAliasName in keyof TFields]-?: TAliasName extends string ? `${TCurr}.${TAliasName}` | (TFields[TAliasName] extends {
148
+ object: infer TNested extends AnyNestedObject;
149
+ } ? AvailableFieldPathsInner<TNested, `${TCurr}.${TAliasName}`, DecrementDepth<TDepth>> : never) : never }[keyof TFields];
150
+ //#endregion
151
+ //#region packages/colocation-tools/src/types/output-path.d.ts
152
+ /** Utilities for inferring types at field paths from TOutput. */
153
+ type AnyOutputPath = string;
154
+ /**
155
+ * Get the TypeScript type at a given path from TOutput.
156
+ *
157
+ * Note: No depth limiting needed here because TOutput is already
158
+ * computed from InferFields and has finite depth.
159
+ *
160
+ * @example
161
+ * ```typescript
162
+ * type Output = { user: { id: string; name: string } };
163
+ * type IdType = InferByOutputPath<Output, "$.user.id">; // string
164
+ * ```
165
+ */
166
+ type InferByOutputPath<TOutput extends object, TPath extends AnyOutputPath> = TPath extends "$" ? TOutput : InferByOutputPathInner<TOutput, TPath, "$">;
167
+ /**
168
+ * Internal helper that walks the output type while matching path segments.
169
+ * Handles arrays and nullables transparently.
170
+ */
171
+ type InferByOutputPathInner<TOutput, TPathTarget extends AnyOutputPath, TPathCurrent extends AnyOutputPath> = TOutput extends readonly (infer _)[] ? never : TOutput extends object ? { readonly [K in keyof TOutput]-?: K extends string ? `${TPathCurrent}.${K}` extends TPathTarget ? TOutput[K] : InferByOutputPathInner<TOutput[K], TPathTarget, `${TPathCurrent}.${K}`> : never }[keyof TOutput] : Extract<TOutput, undefined | null>;
172
+ /**
173
+ * Infer a tuple of types from a tuple of paths.
174
+ *
175
+ * @example
176
+ * ```typescript
177
+ * type Output = { user: { id: string; name: string } };
178
+ * type Tuple = InferPathsOutput<Output, ["$.user.id", "$.user.name"]>;
179
+ * // Result: [string, string]
180
+ * ```
181
+ */
182
+ type InferPathsOutput<TOutput extends object, TPaths extends readonly string[]> = TPaths extends readonly [infer First extends string, ...infer Rest extends readonly string[]] ? [InferByOutputPath<TOutput, First>, ...InferPathsOutput<TOutput, Rest>] : [];
183
+ //#endregion
133
184
  //#region packages/colocation-tools/src/create-projection.d.ts
134
185
  type AnyFragment = Fragment<string, any, any, any>;
186
+ /** Get TFields from Fragment via spread's return type. */
187
+ type FragmentFields<TFragment extends AnyFragment> = ReturnType<TFragment["spread"]>;
135
188
  /**
136
189
  * Options for creating a projection from a Fragment.
137
190
  */
138
- type CreateProjectionOptions<TOutput extends object, TProjected> = {
191
+ type CreateProjectionOptions<TFields extends AnyFields, TOutput extends object, TPaths extends Tuple<AvailableFieldPathOf<TFields>>, TProjected> = {
139
192
  /**
140
193
  * Field paths to extract from the execution result.
141
194
  * Each path starts with "$." and follows the field selection structure.
195
+ * Paths are type-checked against the Fragment's field structure.
142
196
  *
143
197
  * @example
144
198
  * ```typescript
145
199
  * paths: ["$.user.id", "$.user.name"]
146
200
  * ```
147
201
  */
148
- paths: Tuple<string>;
202
+ paths: TPaths;
149
203
  /**
150
204
  * Handler function to transform the sliced execution result.
151
- * Receives a SlicedExecutionResult with the Fragment's output type.
205
+ * Receives a SlicedExecutionResult with types inferred from the specified paths.
152
206
  * Handles all cases: success, error, and empty.
153
207
  *
154
208
  * @example
@@ -156,21 +210,21 @@ type CreateProjectionOptions<TOutput extends object, TProjected> = {
156
210
  * handle: (result) => {
157
211
  * if (result.isError()) return { error: result.error, data: null };
158
212
  * if (result.isEmpty()) return { error: null, data: null };
159
- * const data = result.unwrap();
160
- * return { error: null, data: { userId: data.user.id } };
213
+ * const [id, name] = result.unwrap(); // tuple of types from paths
214
+ * return { error: null, data: { id, name } };
161
215
  * }
162
216
  * ```
163
217
  */
164
- handle: (result: SlicedExecutionResult<TOutput>) => TProjected;
218
+ handle: (result: SlicedExecutionResult<InferPathsOutput<TOutput, TPaths>>) => TProjected;
165
219
  };
166
220
  /**
167
221
  * Creates a type-safe projection from a Fragment.
168
222
  *
169
223
  * The projection extracts and transforms data from GraphQL execution results,
170
- * with full type inference from the Fragment's output type.
224
+ * with full type inference from the Fragment's field structure and output type.
171
225
  *
172
- * Note: The Fragment parameter is used only for type inference.
173
- * The actual paths must be specified explicitly.
226
+ * - Paths are validated against Fragment's TFields via `ReturnType<Fragment["spread"]>`
227
+ * - Handler receives types inferred from the specified paths
174
228
  *
175
229
  * @param _fragment - The Fragment to infer types from (used for type inference only)
176
230
  * @param options - Projection options including paths and handle function
@@ -188,18 +242,33 @@ type CreateProjectionOptions<TOutput extends object, TProjected> = {
188
242
  * );
189
243
  *
190
244
  * const userProjection = createProjection(userFragment, {
191
- * paths: ["$.user"],
245
+ * paths: ["$.user.id", "$.user.name"],
192
246
  * handle: (result) => {
193
- * if (result.isError()) return { error: result.error, user: null };
194
- * if (result.isEmpty()) return { error: null, user: null };
195
- * const data = result.unwrap();
196
- * return { error: null, user: data.user };
247
+ * if (result.isError()) return { error: result.error, data: null };
248
+ * if (result.isEmpty()) return { error: null, data: null };
249
+ * const [id, name] = result.unwrap(); // tuple: [string, string]
250
+ * return { error: null, data: { id, name } };
197
251
  * },
198
252
  * });
199
253
  * ```
200
254
  */
201
- declare const createProjection: <TFragment extends AnyFragment, TProjected>(_fragment: TFragment, options: CreateProjectionOptions<TFragment["$infer"]["output"], TProjected>) => Projection<TProjected>;
202
- declare const createProjectionAttachment: <TFragment extends AnyFragment, TProjected>(options: CreateProjectionOptions<NoInfer<TFragment>["$infer"]["output"], TProjected>) => GqlElementAttachment<TFragment, "projection", Projection<TProjected>>;
255
+ declare const createProjection: <TFragment extends AnyFragment, const TPaths extends Tuple<AvailableFieldPathOf<FragmentFields<TFragment>>>, TProjected>(_fragment: TFragment, options: CreateProjectionOptions<FragmentFields<TFragment>, TFragment["$infer"]["output"], TPaths, TProjected>) => Projection<TProjected>;
256
+ /**
257
+ * Creates a projection attachment for use with Fragment.attach().
258
+ *
259
+ * @example
260
+ * ```typescript
261
+ * const fragment = gql(({ fragment }) =>
262
+ * fragment.Query({
263
+ * fields: ({ f }) => ({ ...f.user()(({ f }) => ({ ...f.id() })) }),
264
+ * })
265
+ * ).attach(createProjectionAttachment({
266
+ * paths: ["$.user.id"],
267
+ * handle: (result) => result.isSuccess() ? result.unwrap()[0] : null,
268
+ * }));
269
+ * ```
270
+ */
271
+ declare const createProjectionAttachment: <TFragment extends AnyFragment, const TPaths extends Tuple<AvailableFieldPathOf<FragmentFields<NoInfer<TFragment>>>>, TProjected>(options: CreateProjectionOptions<FragmentFields<NoInfer<TFragment>>, NoInfer<TFragment>["$infer"]["output"], TPaths, TProjected>) => GqlElementAttachment<TFragment, "projection", Projection<TProjected>>;
203
272
  //#endregion
204
273
  //#region packages/colocation-tools/src/projection-path-graph.d.ts
205
274
  /**
@@ -253,23 +322,5 @@ declare function createPathGraphFromSliceEntries(fragments: AnySlicePayloads): P
253
322
  */
254
323
  declare const createExecutionResultParser: <TSlices extends AnySlicePayloads>(slices: TSlices) => (result: NormalizedExecutionResult<object, object>) => any;
255
324
  //#endregion
256
- //#region packages/colocation-tools/src/types/field-path.d.ts
257
- type AnyFieldPath = string;
258
- /**
259
- * Computes strongly typed "$.foo.bar" style selectors for a set of fields so
260
- * slice result transforms can reference response paths safely.
261
- */
262
- type AvailableFieldPathOf<TSchema extends AnyGraphqlSchema, TFields extends AnyFields> = AvailableFieldPathsInner<TSchema, TFields, "$">;
263
- /** Recursive helper used to build path strings for nested selections. */
264
- type AvailableFieldPathsInner<TSchema extends AnyGraphqlSchema, TFields extends AnyFields, TCurr extends AnyFieldPath> = { readonly [TAliasName in keyof TFields & string]: `${TCurr}.${TAliasName}` | (TFields[TAliasName] extends {
265
- object: infer TNested extends AnyNestedObject;
266
- } ? AvailableFieldPathsInner<TSchema, TNested, `${TCurr}.${TAliasName}`> : never) }[keyof TFields & string];
267
- /** Resolve the TypeScript type located at a given field path. */
268
- type InferByFieldPath<TSchema extends AnyGraphqlSchema, TFields extends AnyFields, TPath extends AnyFieldPath> = string extends keyof TFields ? any : TPath extends "$" ? never : InferByFieldPathInner<TSchema, TFields, TPath, "$">;
269
- /** Internal helper that walks a field tree while matching a path literal. */
270
- type InferByFieldPathInner<TSchema extends AnyGraphqlSchema, TFields extends AnyFields, TPathTarget extends AnyFieldPath, TPathCurrent extends AnyFieldPath> = { readonly [TAliasName in keyof TFields]: TAliasName extends string ? `${TPathCurrent}.${TAliasName}` extends TPathTarget ? InferField<TSchema, TFields[TAliasName]> : TFields[TAliasName] extends {
271
- object: infer TNested extends AnyNestedObject;
272
- } ? InferByFieldPathInner<TSchema, TNested, TPathTarget, `${TPathCurrent}.${TAliasName}`> : never : never }[keyof TFields];
273
- //#endregion
274
- export { type AnyFieldPath, type AnyProjection, type AnySlicePayload, type AnySlicePayloads, type AnySlicedExecutionResult, type AnySlicedExecutionResultRecord, type AvailableFieldPathOf, type CreateProjectionOptions, type EmptyResult, type GraphqlExecutionResult, type InferByFieldPath, type InferExecutionResultProjection, type NonGraphqlError, type NonGraphqlErrorResult, type NormalizedError, type NormalizedExecutionResult, Projection, type ProjectionPath, type ProjectionPathGraphNode, type SafeUnwrapResult, type SlicedExecutionResult, SlicedExecutionResultEmpty, SlicedExecutionResultError, SlicedExecutionResultSuccess, createExecutionResultParser, createPathGraphFromSliceEntries, createProjection, createProjectionAttachment };
325
+ export { type AnyFieldPath, type AnyOutputPath, type AnyProjection, type AnySlicePayload, type AnySlicePayloads, type AnySlicedExecutionResult, type AnySlicedExecutionResultRecord, type AvailableFieldPathOf, type CreateProjectionOptions, type EmptyResult, type GraphqlExecutionResult, type InferByOutputPath, type InferExecutionResultProjection, type InferPathsOutput, type NonGraphqlError, type NonGraphqlErrorResult, type NormalizedError, type NormalizedExecutionResult, Projection, type ProjectionPath, type ProjectionPathGraphNode, type SafeUnwrapResult, type SlicedExecutionResult, SlicedExecutionResultEmpty, SlicedExecutionResultError, SlicedExecutionResultSuccess, createExecutionResultParser, createPathGraphFromSliceEntries, createProjection, createProjectionAttachment };
275
326
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/types.ts","../src/sliced-execution-result.ts","../src/utils/type-utils.ts","../src/projection.ts","../src/create-projection.ts","../src/projection-path-graph.ts","../src/parse-execution-result.ts","../src/types/field-path.ts"],"sourcesContent":[],"mappings":"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OPFI,GAAA,MAAA,CAAA;;AAE4B,KOG5B,gBPH4B,CAAA,gBOItB,gBPJsB,EAAA,gBOKtB,SPLsB,EAAA,cOMxB,YPNwB,CAAA,GAAA,MAAA,SAAA,MOQf,OPRe,GAAA,GAAA,GOQC,KPRD,SAAA,GAAA,GAAA,KAAA,GOQ6B,qBPR7B,COQmD,OPRnD,EOQ4D,OPR5D,EOQqE,KPRrE,EAAA,GAAA,CAAA;;KOWnC,qBPX2B,CAAA,gBOYd,gBPZc,EAAA,gBOad,SPbc,EAAA,oBOcV,YPdU,EAAA,qBOeT,YPfS,CAAA,GAAA,0BAGC,MOcD,OPZvB,GOYiC,UPZjC,SAAe,MAAA,GAAA,GOaf,YPbe,IOaC,UPbD,EAAA,SOasB,WPbtB,GOchB,UPdgB,COcL,OPdK,EOcI,OPdJ,COcY,UPdZ,CAAA,CAAA,GOehB,OPfgB,COeR,UPfQ,CAAA,SAAA;EAMZ,MAAA,EAAA,KAAe,iBOSyC,ePTzC;AAGb,CAAA,GOOJ,qBPPI,COOkB,OPPlB,EOO2B,OPP3B,EOOoC,WPPpC,EAAA,GOOoD,YPPpD,IOOoE,UPPpE,EAAA,CAAA,GAAA,KAAA,GAAA,KAAA,EAID,CAAA,MOML,OPNK,CAAA"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/types.ts","../src/sliced-execution-result.ts","../src/utils/type-utils.ts","../src/projection.ts","../src/types/field-path.ts","../src/types/output-path.ts","../src/create-projection.ts","../src/projection-path-graph.ts","../src/parse-execution-result.ts"],"sourcesContent":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AnyFields, AnyGraphqlSchema, AnyNestedObject, Fragment, GqlElementAttachment, InferField } from "@soda-gql/core";
1
+ import { AnyFields, AnyNestedObject, Fragment, GqlElementAttachment } from "@soda-gql/core";
2
2
  import { FormattedExecutionResult, GraphQLFormattedError } from "graphql";
3
3
 
4
4
  //#region packages/colocation-tools/src/types.d.ts
@@ -130,25 +130,79 @@ type ProjectionPath = {
130
130
  };
131
131
  type InferExecutionResultProjection<TProjection extends AnyProjection> = ReturnType<TProjection["projector"]>;
132
132
  //#endregion
133
+ //#region packages/colocation-tools/src/types/field-path.d.ts
134
+ type AnyFieldPath = string;
135
+ /** Maximum recursion depth to prevent infinite type instantiation. */
136
+ type MaxDepth = [unknown, unknown, unknown, unknown, unknown];
137
+ /** Decrement depth counter for recursion limiting. */
138
+ type DecrementDepth<D extends readonly unknown[]> = D extends readonly [unknown, ...infer Rest] ? Rest : [];
139
+ /**
140
+ * Computes strongly typed "$.foo.bar" style selectors for a set of fields so
141
+ * slice result transforms can reference response paths safely.
142
+ *
143
+ * Note: TSchema is not needed - only uses TFields.object for nesting.
144
+ */
145
+ type AvailableFieldPathOf<TFields extends AnyFields> = AvailableFieldPathsInner<TFields, "$", MaxDepth>;
146
+ /** Recursive helper used to build path strings for nested selections. */
147
+ type AvailableFieldPathsInner<TFields extends AnyFields, TCurr extends AnyFieldPath, TDepth extends readonly unknown[]> = TDepth extends readonly [] ? never : { readonly [TAliasName in keyof TFields]-?: TAliasName extends string ? `${TCurr}.${TAliasName}` | (TFields[TAliasName] extends {
148
+ object: infer TNested extends AnyNestedObject;
149
+ } ? AvailableFieldPathsInner<TNested, `${TCurr}.${TAliasName}`, DecrementDepth<TDepth>> : never) : never }[keyof TFields];
150
+ //#endregion
151
+ //#region packages/colocation-tools/src/types/output-path.d.ts
152
+ /** Utilities for inferring types at field paths from TOutput. */
153
+ type AnyOutputPath = string;
154
+ /**
155
+ * Get the TypeScript type at a given path from TOutput.
156
+ *
157
+ * Note: No depth limiting needed here because TOutput is already
158
+ * computed from InferFields and has finite depth.
159
+ *
160
+ * @example
161
+ * ```typescript
162
+ * type Output = { user: { id: string; name: string } };
163
+ * type IdType = InferByOutputPath<Output, "$.user.id">; // string
164
+ * ```
165
+ */
166
+ type InferByOutputPath<TOutput extends object, TPath extends AnyOutputPath> = TPath extends "$" ? TOutput : InferByOutputPathInner<TOutput, TPath, "$">;
167
+ /**
168
+ * Internal helper that walks the output type while matching path segments.
169
+ * Handles arrays and nullables transparently.
170
+ */
171
+ type InferByOutputPathInner<TOutput, TPathTarget extends AnyOutputPath, TPathCurrent extends AnyOutputPath> = TOutput extends readonly (infer _)[] ? never : TOutput extends object ? { readonly [K in keyof TOutput]-?: K extends string ? `${TPathCurrent}.${K}` extends TPathTarget ? TOutput[K] : InferByOutputPathInner<TOutput[K], TPathTarget, `${TPathCurrent}.${K}`> : never }[keyof TOutput] : Extract<TOutput, undefined | null>;
172
+ /**
173
+ * Infer a tuple of types from a tuple of paths.
174
+ *
175
+ * @example
176
+ * ```typescript
177
+ * type Output = { user: { id: string; name: string } };
178
+ * type Tuple = InferPathsOutput<Output, ["$.user.id", "$.user.name"]>;
179
+ * // Result: [string, string]
180
+ * ```
181
+ */
182
+ type InferPathsOutput<TOutput extends object, TPaths extends readonly string[]> = TPaths extends readonly [infer First extends string, ...infer Rest extends readonly string[]] ? [InferByOutputPath<TOutput, First>, ...InferPathsOutput<TOutput, Rest>] : [];
183
+ //#endregion
133
184
  //#region packages/colocation-tools/src/create-projection.d.ts
134
185
  type AnyFragment = Fragment<string, any, any, any>;
186
+ /** Get TFields from Fragment via spread's return type. */
187
+ type FragmentFields<TFragment extends AnyFragment> = ReturnType<TFragment["spread"]>;
135
188
  /**
136
189
  * Options for creating a projection from a Fragment.
137
190
  */
138
- type CreateProjectionOptions<TOutput extends object, TProjected> = {
191
+ type CreateProjectionOptions<TFields extends AnyFields, TOutput extends object, TPaths extends Tuple<AvailableFieldPathOf<TFields>>, TProjected> = {
139
192
  /**
140
193
  * Field paths to extract from the execution result.
141
194
  * Each path starts with "$." and follows the field selection structure.
195
+ * Paths are type-checked against the Fragment's field structure.
142
196
  *
143
197
  * @example
144
198
  * ```typescript
145
199
  * paths: ["$.user.id", "$.user.name"]
146
200
  * ```
147
201
  */
148
- paths: Tuple<string>;
202
+ paths: TPaths;
149
203
  /**
150
204
  * Handler function to transform the sliced execution result.
151
- * Receives a SlicedExecutionResult with the Fragment's output type.
205
+ * Receives a SlicedExecutionResult with types inferred from the specified paths.
152
206
  * Handles all cases: success, error, and empty.
153
207
  *
154
208
  * @example
@@ -156,21 +210,21 @@ type CreateProjectionOptions<TOutput extends object, TProjected> = {
156
210
  * handle: (result) => {
157
211
  * if (result.isError()) return { error: result.error, data: null };
158
212
  * if (result.isEmpty()) return { error: null, data: null };
159
- * const data = result.unwrap();
160
- * return { error: null, data: { userId: data.user.id } };
213
+ * const [id, name] = result.unwrap(); // tuple of types from paths
214
+ * return { error: null, data: { id, name } };
161
215
  * }
162
216
  * ```
163
217
  */
164
- handle: (result: SlicedExecutionResult<TOutput>) => TProjected;
218
+ handle: (result: SlicedExecutionResult<InferPathsOutput<TOutput, TPaths>>) => TProjected;
165
219
  };
166
220
  /**
167
221
  * Creates a type-safe projection from a Fragment.
168
222
  *
169
223
  * The projection extracts and transforms data from GraphQL execution results,
170
- * with full type inference from the Fragment's output type.
224
+ * with full type inference from the Fragment's field structure and output type.
171
225
  *
172
- * Note: The Fragment parameter is used only for type inference.
173
- * The actual paths must be specified explicitly.
226
+ * - Paths are validated against Fragment's TFields via `ReturnType<Fragment["spread"]>`
227
+ * - Handler receives types inferred from the specified paths
174
228
  *
175
229
  * @param _fragment - The Fragment to infer types from (used for type inference only)
176
230
  * @param options - Projection options including paths and handle function
@@ -188,18 +242,33 @@ type CreateProjectionOptions<TOutput extends object, TProjected> = {
188
242
  * );
189
243
  *
190
244
  * const userProjection = createProjection(userFragment, {
191
- * paths: ["$.user"],
245
+ * paths: ["$.user.id", "$.user.name"],
192
246
  * handle: (result) => {
193
- * if (result.isError()) return { error: result.error, user: null };
194
- * if (result.isEmpty()) return { error: null, user: null };
195
- * const data = result.unwrap();
196
- * return { error: null, user: data.user };
247
+ * if (result.isError()) return { error: result.error, data: null };
248
+ * if (result.isEmpty()) return { error: null, data: null };
249
+ * const [id, name] = result.unwrap(); // tuple: [string, string]
250
+ * return { error: null, data: { id, name } };
197
251
  * },
198
252
  * });
199
253
  * ```
200
254
  */
201
- declare const createProjection: <TFragment extends AnyFragment, TProjected>(_fragment: TFragment, options: CreateProjectionOptions<TFragment["$infer"]["output"], TProjected>) => Projection<TProjected>;
202
- declare const createProjectionAttachment: <TFragment extends AnyFragment, TProjected>(options: CreateProjectionOptions<NoInfer<TFragment>["$infer"]["output"], TProjected>) => GqlElementAttachment<TFragment, "projection", Projection<TProjected>>;
255
+ declare const createProjection: <TFragment extends AnyFragment, const TPaths extends Tuple<AvailableFieldPathOf<FragmentFields<TFragment>>>, TProjected>(_fragment: TFragment, options: CreateProjectionOptions<FragmentFields<TFragment>, TFragment["$infer"]["output"], TPaths, TProjected>) => Projection<TProjected>;
256
+ /**
257
+ * Creates a projection attachment for use with Fragment.attach().
258
+ *
259
+ * @example
260
+ * ```typescript
261
+ * const fragment = gql(({ fragment }) =>
262
+ * fragment.Query({
263
+ * fields: ({ f }) => ({ ...f.user()(({ f }) => ({ ...f.id() })) }),
264
+ * })
265
+ * ).attach(createProjectionAttachment({
266
+ * paths: ["$.user.id"],
267
+ * handle: (result) => result.isSuccess() ? result.unwrap()[0] : null,
268
+ * }));
269
+ * ```
270
+ */
271
+ declare const createProjectionAttachment: <TFragment extends AnyFragment, const TPaths extends Tuple<AvailableFieldPathOf<FragmentFields<NoInfer<TFragment>>>>, TProjected>(options: CreateProjectionOptions<FragmentFields<NoInfer<TFragment>>, NoInfer<TFragment>["$infer"]["output"], TPaths, TProjected>) => GqlElementAttachment<TFragment, "projection", Projection<TProjected>>;
203
272
  //#endregion
204
273
  //#region packages/colocation-tools/src/projection-path-graph.d.ts
205
274
  /**
@@ -253,23 +322,5 @@ declare function createPathGraphFromSliceEntries(fragments: AnySlicePayloads): P
253
322
  */
254
323
  declare const createExecutionResultParser: <TSlices extends AnySlicePayloads>(slices: TSlices) => (result: NormalizedExecutionResult<object, object>) => any;
255
324
  //#endregion
256
- //#region packages/colocation-tools/src/types/field-path.d.ts
257
- type AnyFieldPath = string;
258
- /**
259
- * Computes strongly typed "$.foo.bar" style selectors for a set of fields so
260
- * slice result transforms can reference response paths safely.
261
- */
262
- type AvailableFieldPathOf<TSchema extends AnyGraphqlSchema, TFields extends AnyFields> = AvailableFieldPathsInner<TSchema, TFields, "$">;
263
- /** Recursive helper used to build path strings for nested selections. */
264
- type AvailableFieldPathsInner<TSchema extends AnyGraphqlSchema, TFields extends AnyFields, TCurr extends AnyFieldPath> = { readonly [TAliasName in keyof TFields & string]: `${TCurr}.${TAliasName}` | (TFields[TAliasName] extends {
265
- object: infer TNested extends AnyNestedObject;
266
- } ? AvailableFieldPathsInner<TSchema, TNested, `${TCurr}.${TAliasName}`> : never) }[keyof TFields & string];
267
- /** Resolve the TypeScript type located at a given field path. */
268
- type InferByFieldPath<TSchema extends AnyGraphqlSchema, TFields extends AnyFields, TPath extends AnyFieldPath> = string extends keyof TFields ? any : TPath extends "$" ? never : InferByFieldPathInner<TSchema, TFields, TPath, "$">;
269
- /** Internal helper that walks a field tree while matching a path literal. */
270
- type InferByFieldPathInner<TSchema extends AnyGraphqlSchema, TFields extends AnyFields, TPathTarget extends AnyFieldPath, TPathCurrent extends AnyFieldPath> = { readonly [TAliasName in keyof TFields]: TAliasName extends string ? `${TPathCurrent}.${TAliasName}` extends TPathTarget ? InferField<TSchema, TFields[TAliasName]> : TFields[TAliasName] extends {
271
- object: infer TNested extends AnyNestedObject;
272
- } ? InferByFieldPathInner<TSchema, TNested, TPathTarget, `${TPathCurrent}.${TAliasName}`> : never : never }[keyof TFields];
273
- //#endregion
274
- export { type AnyFieldPath, type AnyProjection, type AnySlicePayload, type AnySlicePayloads, type AnySlicedExecutionResult, type AnySlicedExecutionResultRecord, type AvailableFieldPathOf, type CreateProjectionOptions, type EmptyResult, type GraphqlExecutionResult, type InferByFieldPath, type InferExecutionResultProjection, type NonGraphqlError, type NonGraphqlErrorResult, type NormalizedError, type NormalizedExecutionResult, Projection, type ProjectionPath, type ProjectionPathGraphNode, type SafeUnwrapResult, type SlicedExecutionResult, SlicedExecutionResultEmpty, SlicedExecutionResultError, SlicedExecutionResultSuccess, createExecutionResultParser, createPathGraphFromSliceEntries, createProjection, createProjectionAttachment };
325
+ export { type AnyFieldPath, type AnyOutputPath, type AnyProjection, type AnySlicePayload, type AnySlicePayloads, type AnySlicedExecutionResult, type AnySlicedExecutionResultRecord, type AvailableFieldPathOf, type CreateProjectionOptions, type EmptyResult, type GraphqlExecutionResult, type InferByOutputPath, type InferExecutionResultProjection, type InferPathsOutput, type NonGraphqlError, type NonGraphqlErrorResult, type NormalizedError, type NormalizedExecutionResult, Projection, type ProjectionPath, type ProjectionPathGraphNode, type SafeUnwrapResult, type SlicedExecutionResult, SlicedExecutionResultEmpty, SlicedExecutionResultError, SlicedExecutionResultSuccess, createExecutionResultParser, createPathGraphFromSliceEntries, createProjection, createProjectionAttachment };
275
326
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/sliced-execution-result.ts","../src/utils/type-utils.ts","../src/projection.ts","../src/create-projection.ts","../src/projection-path-graph.ts","../src/parse-execution-result.ts","../src/types/field-path.ts"],"sourcesContent":[],"mappings":"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OPFI,GAAA,MAAA,CAAA;;AAE4B,KOG5B,gBPH4B,CAAA,gBOItB,gBPJsB,EAAA,gBOKtB,SPLsB,EAAA,cOMxB,YPNwB,CAAA,GAAA,MAAA,SAAA,MOQf,OPRe,GAAA,GAAA,GOQC,KPRD,SAAA,GAAA,GAAA,KAAA,GOQ6B,qBPR7B,COQmD,OPRnD,EOQ4D,OPR5D,EOQqE,KPRrE,EAAA,GAAA,CAAA;;KOWnC,qBPX2B,CAAA,gBOYd,gBPZc,EAAA,gBOad,SPbc,EAAA,oBOcV,YPdU,EAAA,qBOeT,YPfS,CAAA,GAAA,0BAGC,MOcD,OPZvB,GOYiC,UPZjC,SAAe,MAAA,GAAA,GOaf,YPbe,IOaC,UPbD,EAAA,SOasB,WPbtB,GOchB,UPdgB,COcL,OPdK,EOcI,OPdJ,COcY,UPdZ,CAAA,CAAA,GOehB,OPfgB,COeR,UPfQ,CAAA,SAAA;EAMZ,MAAA,EAAA,KAAe,iBOSyC,ePTzC;AAGb,CAAA,GOOJ,qBPPI,COOkB,OPPlB,EOO2B,OPP3B,EOOoC,WPPpC,EAAA,GOOoD,YPPpD,IOOoE,UPPpE,EAAA,CAAA,GAAA,KAAA,GAAA,KAAA,EAID,CAAA,MOML,OPNK,CAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/sliced-execution-result.ts","../src/utils/type-utils.ts","../src/projection.ts","../src/types/field-path.ts","../src/types/output-path.ts","../src/create-projection.ts","../src/projection-path-graph.ts","../src/parse-execution-result.ts"],"sourcesContent":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -29,10 +29,10 @@ function createProjectionPath(path) {
29
29
  * Creates a type-safe projection from a Fragment.
30
30
  *
31
31
  * The projection extracts and transforms data from GraphQL execution results,
32
- * with full type inference from the Fragment's output type.
32
+ * with full type inference from the Fragment's field structure and output type.
33
33
  *
34
- * Note: The Fragment parameter is used only for type inference.
35
- * The actual paths must be specified explicitly.
34
+ * - Paths are validated against Fragment's TFields via `ReturnType<Fragment["spread"]>`
35
+ * - Handler receives types inferred from the specified paths
36
36
  *
37
37
  * @param _fragment - The Fragment to infer types from (used for type inference only)
38
38
  * @param options - Projection options including paths and handle function
@@ -50,12 +50,12 @@ function createProjectionPath(path) {
50
50
  * );
51
51
  *
52
52
  * const userProjection = createProjection(userFragment, {
53
- * paths: ["$.user"],
53
+ * paths: ["$.user.id", "$.user.name"],
54
54
  * handle: (result) => {
55
- * if (result.isError()) return { error: result.error, user: null };
56
- * if (result.isEmpty()) return { error: null, user: null };
57
- * const data = result.unwrap();
58
- * return { error: null, user: data.user };
55
+ * if (result.isError()) return { error: result.error, data: null };
56
+ * if (result.isEmpty()) return { error: null, data: null };
57
+ * const [id, name] = result.unwrap(); // tuple: [string, string]
58
+ * return { error: null, data: { id, name } };
59
59
  * },
60
60
  * });
61
61
  * ```
@@ -63,6 +63,21 @@ function createProjectionPath(path) {
63
63
  const createProjection = (_fragment, options) => {
64
64
  return new Projection(options.paths, options.handle);
65
65
  };
66
+ /**
67
+ * Creates a projection attachment for use with Fragment.attach().
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * const fragment = gql(({ fragment }) =>
72
+ * fragment.Query({
73
+ * fields: ({ f }) => ({ ...f.user()(({ f }) => ({ ...f.id() })) }),
74
+ * })
75
+ * ).attach(createProjectionAttachment({
76
+ * paths: ["$.user.id"],
77
+ * handle: (result) => result.isSuccess() ? result.unwrap()[0] : null,
78
+ * }));
79
+ * ```
80
+ */
66
81
  const createProjectionAttachment = (options) => {
67
82
  return {
68
83
  name: "projection",
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["projector: (result: AnySlicedExecutionResult) => TProjected","paths","type: \"success\" | \"error\" | \"empty\"","data: TData","extensions?: unknown","error: NormalizedError","errorMaps: { [label: string]: { [path: string]: { error: GraphQLFormattedError }[] } }","current: unknown"],"sources":["../src/projection.ts","../src/create-projection.ts","../src/utils/map-values.ts","../src/projection-path-graph.ts","../src/sliced-execution-result.ts","../src/parse-execution-result.ts"],"sourcesContent":["import type { AnySlicedExecutionResult } from \"./sliced-execution-result\";\nimport type { Tuple } from \"./utils/type-utils\";\n\n/** Shape of a single selection slice projection. */\n// biome-ignore lint/suspicious/noExplicitAny: Type alias for any Projection regardless of projected type\nexport type AnyProjection = Projection<any>;\n\ndeclare const __PROJECTION_BRAND__: unique symbol;\n/**\n * Nominal type representing any slice selection regardless of schema specifics.\n * Encodes how individual slices map a concrete field path to a projection\n * function. Multiple selections allow slices to expose several derived values.\n */\nexport class Projection<TProjected> {\n declare readonly [__PROJECTION_BRAND__]: void;\n\n declare readonly $infer: { readonly output: TProjected };\n\n constructor(\n paths: Tuple<string>,\n public readonly projector: (result: AnySlicedExecutionResult) => TProjected,\n ) {\n this.paths = paths.map((path) => createProjectionPath(path));\n\n Object.defineProperty(this, \"$infer\", {\n get() {\n throw new Error(\"This property is only for type meta. Do not access this property directly.\");\n },\n });\n }\n\n public readonly paths: ProjectionPath[];\n}\n\nexport type ProjectionPath = {\n full: string;\n segments: Tuple<string>;\n};\n\nfunction createProjectionPath(path: string): ProjectionPath {\n const segments = path.split(\".\");\n if (path === \"$\" || segments.length <= 1) {\n throw new Error(\"Field path must not be only $ or empty\");\n }\n\n return {\n full: path,\n segments: segments.slice(1) as Tuple<string>,\n };\n}\n\nexport type InferExecutionResultProjection<TProjection extends AnyProjection> = ReturnType<TProjection[\"projector\"]>;\n","import type { Fragment, GqlElementAttachment } from \"@soda-gql/core\";\nimport { Projection } from \"./projection\";\nimport type { SlicedExecutionResult } from \"./sliced-execution-result\";\nimport type { Tuple } from \"./utils/type-utils\";\n\n// biome-ignore lint/suspicious/noExplicitAny: Type alias for any Fragment regardless of type parameters\ntype AnyFragment = Fragment<string, any, any, any>;\n\n/**\n * Options for creating a projection from a Fragment.\n */\nexport type CreateProjectionOptions<TOutput extends object, TProjected> = {\n /**\n * Field paths to extract from the execution result.\n * Each path starts with \"$.\" and follows the field selection structure.\n *\n * @example\n * ```typescript\n * paths: [\"$.user.id\", \"$.user.name\"]\n * ```\n */\n paths: Tuple<string>;\n\n /**\n * Handler function to transform the sliced execution result.\n * Receives a SlicedExecutionResult with the Fragment's output type.\n * Handles all cases: success, error, and empty.\n *\n * @example\n * ```typescript\n * handle: (result) => {\n * if (result.isError()) return { error: result.error, data: null };\n * if (result.isEmpty()) return { error: null, data: null };\n * const data = result.unwrap();\n * return { error: null, data: { userId: data.user.id } };\n * }\n * ```\n */\n handle: (result: SlicedExecutionResult<TOutput>) => TProjected;\n};\n\n/**\n * Creates a type-safe projection from a Fragment.\n *\n * The projection extracts and transforms data from GraphQL execution results,\n * with full type inference from the Fragment's output type.\n *\n * Note: The Fragment parameter is used only for type inference.\n * The actual paths must be specified explicitly.\n *\n * @param _fragment - The Fragment to infer types from (used for type inference only)\n * @param options - Projection options including paths and handle function\n * @returns A Projection that can be used with createExecutionResultParser\n *\n * @example\n * ```typescript\n * const userFragment = gql(({ fragment }) =>\n * fragment.Query({\n * variables: { ... },\n * fields: ({ f, $ }) => ({\n * ...f.user({ id: $.userId })(({ f }) => ({ ...f.id(), ...f.name() })),\n * }),\n * })\n * );\n *\n * const userProjection = createProjection(userFragment, {\n * paths: [\"$.user\"],\n * handle: (result) => {\n * if (result.isError()) return { error: result.error, user: null };\n * if (result.isEmpty()) return { error: null, user: null };\n * const data = result.unwrap();\n * return { error: null, user: data.user };\n * },\n * });\n * ```\n */\nexport const createProjection = <TFragment extends AnyFragment, TProjected>(\n _fragment: TFragment,\n options: CreateProjectionOptions<TFragment[\"$infer\"][\"output\"], TProjected>,\n): Projection<TProjected> => {\n return new Projection(options.paths, options.handle);\n};\n\nexport const createProjectionAttachment = <TFragment extends AnyFragment, TProjected>(\n options: CreateProjectionOptions<NoInfer<TFragment>[\"$infer\"][\"output\"], TProjected>,\n): GqlElementAttachment<TFragment, \"projection\", Projection<TProjected>> => {\n return {\n name: \"projection\",\n createValue: (fragment) => createProjection(fragment, options),\n };\n};\n","type ArgEntries<T extends object> = { [K in keyof T]-?: [value: T[K], key: K] }[keyof T];\ntype Entries<T extends object> = { [K in keyof T]: [key: K, value: T[K]] }[keyof T];\n\nexport function mapValues<TObject extends object, TMappedValue>(\n obj: TObject,\n fn: (...args: ArgEntries<TObject>) => TMappedValue,\n): {\n [K in keyof TObject]: TMappedValue;\n} {\n return Object.fromEntries((Object.entries(obj) as Entries<TObject>[]).map(([key, value]) => [key, fn(value, key)])) as {\n [K in keyof TObject]: TMappedValue;\n };\n}\n","import type { AnyProjection } from \"./projection\";\nimport { mapValues } from \"./utils/map-values\";\n\n/**\n * Node in the projection path graph tree.\n * Used for mapping GraphQL errors and data to their corresponding slices.\n */\nexport type ProjectionPathGraphNode = {\n readonly matches: { label: string; path: string; exact: boolean }[];\n readonly children: { readonly [segment: string]: ProjectionPathGraphNode };\n};\n\n/**\n * Payload from a slice that contains projection.\n */\nexport type AnySlicePayload = {\n readonly projection: AnyProjection;\n};\n\nexport type AnySlicePayloads = Record<string, AnySlicePayload>;\n\ntype ExecutionResultProjectionPathGraphIntermediate = {\n [segment: string]: { label: string; raw: string; segments: string[] }[];\n};\n\nfunction createPathGraph(paths: ExecutionResultProjectionPathGraphIntermediate[string]): ProjectionPathGraphNode {\n const intermediate = paths.reduce(\n (acc: ExecutionResultProjectionPathGraphIntermediate, { label, raw, segments: [segment, ...segments] }) => {\n if (segment) {\n (acc[segment] || (acc[segment] = [])).push({ label, raw, segments });\n }\n return acc;\n },\n {},\n );\n\n return {\n matches: paths.map(({ label, raw, segments }) => ({ label, path: raw, exact: segments.length === 0 })),\n children: mapValues(intermediate, (paths) => createPathGraph(paths)),\n } satisfies ProjectionPathGraphNode;\n}\n\n/**\n * Creates a projection path graph from slice entries with field prefixing.\n * Each slice's paths are prefixed with the slice label for disambiguation.\n */\nexport function createPathGraphFromSliceEntries(fragments: AnySlicePayloads) {\n const paths = Object.entries(fragments).flatMap(([label, slice]) =>\n Array.from(\n new Map(\n slice.projection.paths.map(({ full: raw, segments }) => {\n const [first, ...rest] = segments;\n return [raw, { label, raw, segments: [`${label}_${first}`, ...rest] }];\n }),\n ).values(),\n ),\n );\n\n return createPathGraph(paths);\n}\n","/** Result-like wrapper types returned from slice projections. */\n\nimport type { NormalizedError } from \"./types\";\n\n// biome-ignore lint/suspicious/noExplicitAny: Type alias for any SlicedExecutionResult regardless of data type\nexport type AnySlicedExecutionResult = SlicedExecutionResult<any>;\n\n/**\n * Internal discriminated union describing the Result-like wrapper exposed to\n * slice selection callbacks.\n */\nexport type AnySlicedExecutionResultRecord = {\n [path: string]: AnySlicedExecutionResult;\n};\n\nexport type SafeUnwrapResult<TTransformed, TError> =\n | {\n data?: never;\n error?: never;\n }\n | {\n data: TTransformed;\n error?: never;\n }\n | {\n data?: never;\n error: TError;\n };\n\n/** Utility signature returned by the safe unwrap helper. */\ntype SlicedExecutionResultCommon<TData, TError> = {\n safeUnwrap<TTransformed>(transform: (data: TData) => TTransformed): SafeUnwrapResult<TTransformed, TError>;\n};\n\n/** Public union used by selection callbacks to inspect data, empty, or error states. */\nexport type SlicedExecutionResult<TData> =\n | SlicedExecutionResultEmpty<TData>\n | SlicedExecutionResultSuccess<TData>\n | SlicedExecutionResultError<TData>;\n\n/** Runtime guard interface shared by all slice result variants. */\nclass SlicedExecutionResultGuards<TData> {\n isSuccess(): this is SlicedExecutionResultSuccess<TData> {\n return this.type === \"success\";\n }\n isError(): this is SlicedExecutionResultError<TData> {\n return this.type === \"error\";\n }\n isEmpty(): this is SlicedExecutionResultEmpty<TData> {\n return this.type === \"empty\";\n }\n\n constructor(private readonly type: \"success\" | \"error\" | \"empty\") {}\n}\n\n/** Variant representing an empty payload (no data, no error). */\nexport class SlicedExecutionResultEmpty<TData>\n extends SlicedExecutionResultGuards<TData>\n implements SlicedExecutionResultCommon<TData, NormalizedError>\n{\n constructor() {\n super(\"empty\");\n }\n\n unwrap(): null {\n return null;\n }\n\n safeUnwrap() {\n return {\n data: undefined,\n error: undefined,\n };\n }\n}\n\n/** Variant representing a successful payload. */\nexport class SlicedExecutionResultSuccess<TData>\n extends SlicedExecutionResultGuards<TData>\n implements SlicedExecutionResultCommon<TData, NormalizedError>\n{\n constructor(\n public readonly data: TData,\n public readonly extensions?: unknown,\n ) {\n super(\"success\");\n }\n\n unwrap(): TData {\n return this.data;\n }\n\n safeUnwrap<TTransformed>(transform: (data: TData) => TTransformed) {\n return {\n data: transform(this.data),\n error: undefined,\n };\n }\n}\n\n/** Variant representing an error payload. */\nexport class SlicedExecutionResultError<TData>\n extends SlicedExecutionResultGuards<TData>\n implements SlicedExecutionResultCommon<TData, NormalizedError>\n{\n constructor(\n public readonly error: NormalizedError,\n public readonly extensions?: unknown,\n ) {\n super(\"error\");\n }\n\n unwrap(): never {\n throw this.error;\n }\n\n safeUnwrap() {\n return {\n data: undefined,\n error: this.error,\n };\n }\n}\n","import type { GraphQLFormattedError } from \"graphql\";\nimport { type AnySlicePayloads, createPathGraphFromSliceEntries, type ProjectionPathGraphNode } from \"./projection-path-graph\";\nimport { SlicedExecutionResultEmpty, SlicedExecutionResultError, SlicedExecutionResultSuccess } from \"./sliced-execution-result\";\nimport type { NormalizedExecutionResult } from \"./types\";\n\n// Internal function to build path graph from slices\nconst createPathGraphFromSlices = createPathGraphFromSliceEntries;\n\nfunction* generateErrorMapEntries(errors: readonly GraphQLFormattedError[], projectionPathGraph: ProjectionPathGraphNode) {\n for (const error of errors) {\n const errorPath = error.path ?? [];\n let stack = projectionPathGraph;\n\n for (\n let i = 0;\n // i <= errorPath.length to handle the case where the error path is empty\n i <= errorPath.length;\n i++\n ) {\n const segment = errorPath[i];\n\n if (\n // the end of the path\n segment == null ||\n // FieldPath does not support index access. We treat it as the end of the path.\n typeof segment === \"number\"\n ) {\n yield* stack.matches.map(({ label, path }) => ({ label, path, error }));\n break;\n }\n\n yield* stack.matches.filter(({ exact }) => exact).map(({ label, path }) => ({ label, path, error }));\n\n const next = stack.children[segment];\n if (!next) {\n break;\n }\n\n stack = next;\n }\n }\n}\n\nconst createErrorMaps = (errors: readonly GraphQLFormattedError[] | undefined, projectionPathGraph: ProjectionPathGraphNode) => {\n const errorMaps: { [label: string]: { [path: string]: { error: GraphQLFormattedError }[] } } = {};\n for (const { label, path, error } of generateErrorMapEntries(errors ?? [], projectionPathGraph)) {\n const mapPerLabel = errorMaps[label] || (errorMaps[label] = {});\n const mapPerPath = mapPerLabel[path] || (mapPerLabel[path] = []);\n mapPerPath.push({ error });\n }\n return errorMaps;\n};\n\nconst accessDataByPathSegments = (data: object, pathSegments: string[]) => {\n let current: unknown = data;\n\n for (const segment of pathSegments) {\n if (current == null) {\n return { error: new Error(\"No data\") };\n }\n\n if (typeof current !== \"object\") {\n return { error: new Error(\"Incorrect data type\") };\n }\n\n if (Array.isArray(current)) {\n return { error: new Error(\"Incorrect data type\") };\n }\n\n current = (current as Record<string, unknown>)[segment];\n }\n\n return { data: current };\n};\n\n/**\n * Creates an execution result parser for composed operations.\n * The parser maps GraphQL errors and data to their corresponding slices\n * based on the projection path graph.\n *\n * @param slices - Object mapping labels to projections\n * @returns A parser function that takes a NormalizedExecutionResult and returns parsed slices\n *\n * @example\n * ```typescript\n * const parser = createExecutionResultParser({\n * userCard: userCardProjection,\n * posts: postsProjection,\n * });\n *\n * const results = parser({\n * type: \"graphql\",\n * body: { data, errors },\n * });\n * ```\n */\nexport const createExecutionResultParser = <TSlices extends AnySlicePayloads>(slices: TSlices) => {\n // Build path graph from slices\n const projectionPathGraph = createPathGraphFromSlices(slices);\n const fragments = slices;\n const prepare = (result: NormalizedExecutionResult<object, object>) => {\n if (result.type === \"graphql\") {\n const errorMaps = createErrorMaps(result.body.errors, projectionPathGraph);\n\n return { ...result, errorMaps };\n }\n\n if (result.type === \"non-graphql-error\") {\n return { ...result, error: new SlicedExecutionResultError({ type: \"non-graphql-error\", error: result.error }) };\n }\n\n if (result.type === \"empty\") {\n return { ...result, error: new SlicedExecutionResultEmpty() };\n }\n\n throw new Error(\"Invalid result type\", { cause: result satisfies never });\n };\n\n return (result: NormalizedExecutionResult<object, object>) => {\n const prepared = prepare(result);\n\n const entries = Object.entries(fragments).map(([label, fragment]) => {\n const { projection } = fragment;\n\n if (prepared.type === \"graphql\") {\n const matchedErrors = projection.paths.flatMap(({ full: raw }) => prepared.errorMaps[label]?.[raw] ?? []);\n const uniqueErrors = Array.from(new Set(matchedErrors.map(({ error }) => error)).values());\n\n if (uniqueErrors.length > 0) {\n return [label, projection.projector(new SlicedExecutionResultError({ type: \"graphql-error\", errors: uniqueErrors }))];\n }\n\n // Apply label prefix to first segment for data access (matching $colocate prefix pattern)\n const dataResults = projection.paths.map(({ segments }) => {\n const [first, ...rest] = segments;\n const prefixedSegments = [`${label}_${first}`, ...rest];\n return prepared.body.data\n ? accessDataByPathSegments(prepared.body.data, prefixedSegments)\n : { error: new Error(\"No data\") };\n });\n if (dataResults.some(({ error }) => error)) {\n const errors = dataResults.flatMap(({ error }) => (error ? [error] : []));\n return [label, projection.projector(new SlicedExecutionResultError({ type: \"parse-error\", errors }))];\n }\n\n const dataList = dataResults.map(({ data }) => data);\n return [label, projection.projector(new SlicedExecutionResultSuccess(dataList))];\n }\n\n if (prepared.type === \"non-graphql-error\") {\n return [label, projection.projector(prepared.error)];\n }\n\n if (prepared.type === \"empty\") {\n return [label, projection.projector(prepared.error)];\n }\n\n throw new Error(\"Invalid result type\", { cause: prepared satisfies never });\n });\n\n return Object.fromEntries(entries);\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["projector: (result: AnySlicedExecutionResult) => TProjected","paths","type: \"success\" | \"error\" | \"empty\"","data: TData","extensions?: unknown","error: NormalizedError","errorMaps: { [label: string]: { [path: string]: { error: GraphQLFormattedError }[] } }","current: unknown"],"sources":["../src/projection.ts","../src/create-projection.ts","../src/utils/map-values.ts","../src/projection-path-graph.ts","../src/sliced-execution-result.ts","../src/parse-execution-result.ts"],"sourcesContent":["import type { AnySlicedExecutionResult } from \"./sliced-execution-result\";\nimport type { Tuple } from \"./utils/type-utils\";\n\n/** Shape of a single selection slice projection. */\n// biome-ignore lint/suspicious/noExplicitAny: Type alias for any Projection regardless of projected type\nexport type AnyProjection = Projection<any>;\n\ndeclare const __PROJECTION_BRAND__: unique symbol;\n/**\n * Nominal type representing any slice selection regardless of schema specifics.\n * Encodes how individual slices map a concrete field path to a projection\n * function. Multiple selections allow slices to expose several derived values.\n */\nexport class Projection<TProjected> {\n declare readonly [__PROJECTION_BRAND__]: void;\n\n declare readonly $infer: { readonly output: TProjected };\n\n constructor(\n paths: Tuple<string>,\n public readonly projector: (result: AnySlicedExecutionResult) => TProjected,\n ) {\n this.paths = paths.map((path) => createProjectionPath(path));\n\n Object.defineProperty(this, \"$infer\", {\n get() {\n throw new Error(\"This property is only for type meta. Do not access this property directly.\");\n },\n });\n }\n\n public readonly paths: ProjectionPath[];\n}\n\nexport type ProjectionPath = {\n full: string;\n segments: Tuple<string>;\n};\n\nfunction createProjectionPath(path: string): ProjectionPath {\n const segments = path.split(\".\");\n if (path === \"$\" || segments.length <= 1) {\n throw new Error(\"Field path must not be only $ or empty\");\n }\n\n return {\n full: path,\n segments: segments.slice(1) as Tuple<string>,\n };\n}\n\nexport type InferExecutionResultProjection<TProjection extends AnyProjection> = ReturnType<TProjection[\"projector\"]>;\n","import type { AnyFields, Fragment, GqlElementAttachment } from \"@soda-gql/core\";\nimport { Projection } from \"./projection\";\nimport type { SlicedExecutionResult } from \"./sliced-execution-result\";\nimport type { AvailableFieldPathOf } from \"./types/field-path\";\nimport type { InferPathsOutput } from \"./types/output-path\";\nimport type { Tuple } from \"./utils/type-utils\";\n\n// biome-ignore lint/suspicious/noExplicitAny: Type alias for any Fragment regardless of type parameters\ntype AnyFragment = Fragment<string, any, any, any>;\n\n/** Get TFields from Fragment via spread's return type. */\ntype FragmentFields<TFragment extends AnyFragment> = ReturnType<TFragment[\"spread\"]>;\n\n/**\n * Options for creating a projection from a Fragment.\n */\nexport type CreateProjectionOptions<\n TFields extends AnyFields,\n TOutput extends object,\n TPaths extends Tuple<AvailableFieldPathOf<TFields>>,\n TProjected,\n> = {\n /**\n * Field paths to extract from the execution result.\n * Each path starts with \"$.\" and follows the field selection structure.\n * Paths are type-checked against the Fragment's field structure.\n *\n * @example\n * ```typescript\n * paths: [\"$.user.id\", \"$.user.name\"]\n * ```\n */\n paths: TPaths;\n\n /**\n * Handler function to transform the sliced execution result.\n * Receives a SlicedExecutionResult with types inferred from the specified paths.\n * Handles all cases: success, error, and empty.\n *\n * @example\n * ```typescript\n * handle: (result) => {\n * if (result.isError()) return { error: result.error, data: null };\n * if (result.isEmpty()) return { error: null, data: null };\n * const [id, name] = result.unwrap(); // tuple of types from paths\n * return { error: null, data: { id, name } };\n * }\n * ```\n */\n handle: (result: SlicedExecutionResult<InferPathsOutput<TOutput, TPaths>>) => TProjected;\n};\n\n/**\n * Creates a type-safe projection from a Fragment.\n *\n * The projection extracts and transforms data from GraphQL execution results,\n * with full type inference from the Fragment's field structure and output type.\n *\n * - Paths are validated against Fragment's TFields via `ReturnType<Fragment[\"spread\"]>`\n * - Handler receives types inferred from the specified paths\n *\n * @param _fragment - The Fragment to infer types from (used for type inference only)\n * @param options - Projection options including paths and handle function\n * @returns A Projection that can be used with createExecutionResultParser\n *\n * @example\n * ```typescript\n * const userFragment = gql(({ fragment }) =>\n * fragment.Query({\n * variables: { ... },\n * fields: ({ f, $ }) => ({\n * ...f.user({ id: $.userId })(({ f }) => ({ ...f.id(), ...f.name() })),\n * }),\n * })\n * );\n *\n * const userProjection = createProjection(userFragment, {\n * paths: [\"$.user.id\", \"$.user.name\"],\n * handle: (result) => {\n * if (result.isError()) return { error: result.error, data: null };\n * if (result.isEmpty()) return { error: null, data: null };\n * const [id, name] = result.unwrap(); // tuple: [string, string]\n * return { error: null, data: { id, name } };\n * },\n * });\n * ```\n */\nexport const createProjection = <\n TFragment extends AnyFragment,\n const TPaths extends Tuple<AvailableFieldPathOf<FragmentFields<TFragment>>>,\n TProjected,\n>(\n _fragment: TFragment,\n options: CreateProjectionOptions<FragmentFields<TFragment>, TFragment[\"$infer\"][\"output\"], TPaths, TProjected>,\n): Projection<TProjected> => {\n return new Projection(options.paths, options.handle);\n};\n\n/**\n * Creates a projection attachment for use with Fragment.attach().\n *\n * @example\n * ```typescript\n * const fragment = gql(({ fragment }) =>\n * fragment.Query({\n * fields: ({ f }) => ({ ...f.user()(({ f }) => ({ ...f.id() })) }),\n * })\n * ).attach(createProjectionAttachment({\n * paths: [\"$.user.id\"],\n * handle: (result) => result.isSuccess() ? result.unwrap()[0] : null,\n * }));\n * ```\n */\nexport const createProjectionAttachment = <\n TFragment extends AnyFragment,\n const TPaths extends Tuple<AvailableFieldPathOf<FragmentFields<NoInfer<TFragment>>>>,\n TProjected,\n>(\n options: CreateProjectionOptions<\n FragmentFields<NoInfer<TFragment>>,\n NoInfer<TFragment>[\"$infer\"][\"output\"],\n TPaths,\n TProjected\n >,\n): GqlElementAttachment<TFragment, \"projection\", Projection<TProjected>> => {\n return {\n name: \"projection\",\n createValue: (fragment) => createProjection(fragment, options),\n };\n};\n","type ArgEntries<T extends object> = { [K in keyof T]-?: [value: T[K], key: K] }[keyof T];\ntype Entries<T extends object> = { [K in keyof T]: [key: K, value: T[K]] }[keyof T];\n\nexport function mapValues<TObject extends object, TMappedValue>(\n obj: TObject,\n fn: (...args: ArgEntries<TObject>) => TMappedValue,\n): {\n [K in keyof TObject]: TMappedValue;\n} {\n return Object.fromEntries((Object.entries(obj) as Entries<TObject>[]).map(([key, value]) => [key, fn(value, key)])) as {\n [K in keyof TObject]: TMappedValue;\n };\n}\n","import type { AnyProjection } from \"./projection\";\nimport { mapValues } from \"./utils/map-values\";\n\n/**\n * Node in the projection path graph tree.\n * Used for mapping GraphQL errors and data to their corresponding slices.\n */\nexport type ProjectionPathGraphNode = {\n readonly matches: { label: string; path: string; exact: boolean }[];\n readonly children: { readonly [segment: string]: ProjectionPathGraphNode };\n};\n\n/**\n * Payload from a slice that contains projection.\n */\nexport type AnySlicePayload = {\n readonly projection: AnyProjection;\n};\n\nexport type AnySlicePayloads = Record<string, AnySlicePayload>;\n\ntype ExecutionResultProjectionPathGraphIntermediate = {\n [segment: string]: { label: string; raw: string; segments: string[] }[];\n};\n\nfunction createPathGraph(paths: ExecutionResultProjectionPathGraphIntermediate[string]): ProjectionPathGraphNode {\n const intermediate = paths.reduce(\n (acc: ExecutionResultProjectionPathGraphIntermediate, { label, raw, segments: [segment, ...segments] }) => {\n if (segment) {\n (acc[segment] || (acc[segment] = [])).push({ label, raw, segments });\n }\n return acc;\n },\n {},\n );\n\n return {\n matches: paths.map(({ label, raw, segments }) => ({ label, path: raw, exact: segments.length === 0 })),\n children: mapValues(intermediate, (paths) => createPathGraph(paths)),\n } satisfies ProjectionPathGraphNode;\n}\n\n/**\n * Creates a projection path graph from slice entries with field prefixing.\n * Each slice's paths are prefixed with the slice label for disambiguation.\n */\nexport function createPathGraphFromSliceEntries(fragments: AnySlicePayloads) {\n const paths = Object.entries(fragments).flatMap(([label, slice]) =>\n Array.from(\n new Map(\n slice.projection.paths.map(({ full: raw, segments }) => {\n const [first, ...rest] = segments;\n return [raw, { label, raw, segments: [`${label}_${first}`, ...rest] }];\n }),\n ).values(),\n ),\n );\n\n return createPathGraph(paths);\n}\n","/** Result-like wrapper types returned from slice projections. */\n\nimport type { NormalizedError } from \"./types\";\n\n// biome-ignore lint/suspicious/noExplicitAny: Type alias for any SlicedExecutionResult regardless of data type\nexport type AnySlicedExecutionResult = SlicedExecutionResult<any>;\n\n/**\n * Internal discriminated union describing the Result-like wrapper exposed to\n * slice selection callbacks.\n */\nexport type AnySlicedExecutionResultRecord = {\n [path: string]: AnySlicedExecutionResult;\n};\n\nexport type SafeUnwrapResult<TTransformed, TError> =\n | {\n data?: never;\n error?: never;\n }\n | {\n data: TTransformed;\n error?: never;\n }\n | {\n data?: never;\n error: TError;\n };\n\n/** Utility signature returned by the safe unwrap helper. */\ntype SlicedExecutionResultCommon<TData, TError> = {\n safeUnwrap<TTransformed>(transform: (data: TData) => TTransformed): SafeUnwrapResult<TTransformed, TError>;\n};\n\n/** Public union used by selection callbacks to inspect data, empty, or error states. */\nexport type SlicedExecutionResult<TData> =\n | SlicedExecutionResultEmpty<TData>\n | SlicedExecutionResultSuccess<TData>\n | SlicedExecutionResultError<TData>;\n\n/** Runtime guard interface shared by all slice result variants. */\nclass SlicedExecutionResultGuards<TData> {\n isSuccess(): this is SlicedExecutionResultSuccess<TData> {\n return this.type === \"success\";\n }\n isError(): this is SlicedExecutionResultError<TData> {\n return this.type === \"error\";\n }\n isEmpty(): this is SlicedExecutionResultEmpty<TData> {\n return this.type === \"empty\";\n }\n\n constructor(private readonly type: \"success\" | \"error\" | \"empty\") {}\n}\n\n/** Variant representing an empty payload (no data, no error). */\nexport class SlicedExecutionResultEmpty<TData>\n extends SlicedExecutionResultGuards<TData>\n implements SlicedExecutionResultCommon<TData, NormalizedError>\n{\n constructor() {\n super(\"empty\");\n }\n\n unwrap(): null {\n return null;\n }\n\n safeUnwrap() {\n return {\n data: undefined,\n error: undefined,\n };\n }\n}\n\n/** Variant representing a successful payload. */\nexport class SlicedExecutionResultSuccess<TData>\n extends SlicedExecutionResultGuards<TData>\n implements SlicedExecutionResultCommon<TData, NormalizedError>\n{\n constructor(\n public readonly data: TData,\n public readonly extensions?: unknown,\n ) {\n super(\"success\");\n }\n\n unwrap(): TData {\n return this.data;\n }\n\n safeUnwrap<TTransformed>(transform: (data: TData) => TTransformed) {\n return {\n data: transform(this.data),\n error: undefined,\n };\n }\n}\n\n/** Variant representing an error payload. */\nexport class SlicedExecutionResultError<TData>\n extends SlicedExecutionResultGuards<TData>\n implements SlicedExecutionResultCommon<TData, NormalizedError>\n{\n constructor(\n public readonly error: NormalizedError,\n public readonly extensions?: unknown,\n ) {\n super(\"error\");\n }\n\n unwrap(): never {\n throw this.error;\n }\n\n safeUnwrap() {\n return {\n data: undefined,\n error: this.error,\n };\n }\n}\n","import type { GraphQLFormattedError } from \"graphql\";\nimport { type AnySlicePayloads, createPathGraphFromSliceEntries, type ProjectionPathGraphNode } from \"./projection-path-graph\";\nimport { SlicedExecutionResultEmpty, SlicedExecutionResultError, SlicedExecutionResultSuccess } from \"./sliced-execution-result\";\nimport type { NormalizedExecutionResult } from \"./types\";\n\n// Internal function to build path graph from slices\nconst createPathGraphFromSlices = createPathGraphFromSliceEntries;\n\nfunction* generateErrorMapEntries(errors: readonly GraphQLFormattedError[], projectionPathGraph: ProjectionPathGraphNode) {\n for (const error of errors) {\n const errorPath = error.path ?? [];\n let stack = projectionPathGraph;\n\n for (\n let i = 0;\n // i <= errorPath.length to handle the case where the error path is empty\n i <= errorPath.length;\n i++\n ) {\n const segment = errorPath[i];\n\n if (\n // the end of the path\n segment == null ||\n // FieldPath does not support index access. We treat it as the end of the path.\n typeof segment === \"number\"\n ) {\n yield* stack.matches.map(({ label, path }) => ({ label, path, error }));\n break;\n }\n\n yield* stack.matches.filter(({ exact }) => exact).map(({ label, path }) => ({ label, path, error }));\n\n const next = stack.children[segment];\n if (!next) {\n break;\n }\n\n stack = next;\n }\n }\n}\n\nconst createErrorMaps = (errors: readonly GraphQLFormattedError[] | undefined, projectionPathGraph: ProjectionPathGraphNode) => {\n const errorMaps: { [label: string]: { [path: string]: { error: GraphQLFormattedError }[] } } = {};\n for (const { label, path, error } of generateErrorMapEntries(errors ?? [], projectionPathGraph)) {\n const mapPerLabel = errorMaps[label] || (errorMaps[label] = {});\n const mapPerPath = mapPerLabel[path] || (mapPerLabel[path] = []);\n mapPerPath.push({ error });\n }\n return errorMaps;\n};\n\nconst accessDataByPathSegments = (data: object, pathSegments: string[]) => {\n let current: unknown = data;\n\n for (const segment of pathSegments) {\n if (current == null) {\n return { error: new Error(\"No data\") };\n }\n\n if (typeof current !== \"object\") {\n return { error: new Error(\"Incorrect data type\") };\n }\n\n if (Array.isArray(current)) {\n return { error: new Error(\"Incorrect data type\") };\n }\n\n current = (current as Record<string, unknown>)[segment];\n }\n\n return { data: current };\n};\n\n/**\n * Creates an execution result parser for composed operations.\n * The parser maps GraphQL errors and data to their corresponding slices\n * based on the projection path graph.\n *\n * @param slices - Object mapping labels to projections\n * @returns A parser function that takes a NormalizedExecutionResult and returns parsed slices\n *\n * @example\n * ```typescript\n * const parser = createExecutionResultParser({\n * userCard: userCardProjection,\n * posts: postsProjection,\n * });\n *\n * const results = parser({\n * type: \"graphql\",\n * body: { data, errors },\n * });\n * ```\n */\nexport const createExecutionResultParser = <TSlices extends AnySlicePayloads>(slices: TSlices) => {\n // Build path graph from slices\n const projectionPathGraph = createPathGraphFromSlices(slices);\n const fragments = slices;\n const prepare = (result: NormalizedExecutionResult<object, object>) => {\n if (result.type === \"graphql\") {\n const errorMaps = createErrorMaps(result.body.errors, projectionPathGraph);\n\n return { ...result, errorMaps };\n }\n\n if (result.type === \"non-graphql-error\") {\n return { ...result, error: new SlicedExecutionResultError({ type: \"non-graphql-error\", error: result.error }) };\n }\n\n if (result.type === \"empty\") {\n return { ...result, error: new SlicedExecutionResultEmpty() };\n }\n\n throw new Error(\"Invalid result type\", { cause: result satisfies never });\n };\n\n return (result: NormalizedExecutionResult<object, object>) => {\n const prepared = prepare(result);\n\n const entries = Object.entries(fragments).map(([label, fragment]) => {\n const { projection } = fragment;\n\n if (prepared.type === \"graphql\") {\n const matchedErrors = projection.paths.flatMap(({ full: raw }) => prepared.errorMaps[label]?.[raw] ?? []);\n const uniqueErrors = Array.from(new Set(matchedErrors.map(({ error }) => error)).values());\n\n if (uniqueErrors.length > 0) {\n return [label, projection.projector(new SlicedExecutionResultError({ type: \"graphql-error\", errors: uniqueErrors }))];\n }\n\n // Apply label prefix to first segment for data access (matching $colocate prefix pattern)\n const dataResults = projection.paths.map(({ segments }) => {\n const [first, ...rest] = segments;\n const prefixedSegments = [`${label}_${first}`, ...rest];\n return prepared.body.data\n ? accessDataByPathSegments(prepared.body.data, prefixedSegments)\n : { error: new Error(\"No data\") };\n });\n if (dataResults.some(({ error }) => error)) {\n const errors = dataResults.flatMap(({ error }) => (error ? [error] : []));\n return [label, projection.projector(new SlicedExecutionResultError({ type: \"parse-error\", errors }))];\n }\n\n const dataList = dataResults.map(({ data }) => data);\n return [label, projection.projector(new SlicedExecutionResultSuccess(dataList))];\n }\n\n if (prepared.type === \"non-graphql-error\") {\n return [label, projection.projector(prepared.error)];\n }\n\n if (prepared.type === \"empty\") {\n return [label, projection.projector(prepared.error)];\n }\n\n throw new Error(\"Invalid result type\", { cause: prepared satisfies never });\n });\n\n return Object.fromEntries(entries);\n };\n};\n"],"mappings":";;;;;;AAaA,IAAa,aAAb,MAAoC;CAKlC,YACE,OACA,AAAgBA,WAChB;EADgB;AAEhB,OAAK,QAAQ,MAAM,KAAK,SAAS,qBAAqB,KAAK,CAAC;AAE5D,SAAO,eAAe,MAAM,UAAU,EACpC,MAAM;AACJ,SAAM,IAAI,MAAM,6EAA6E;KAEhG,CAAC;;CAGJ,AAAgB;;AAQlB,SAAS,qBAAqB,MAA8B;CAC1D,MAAM,WAAW,KAAK,MAAM,IAAI;AAChC,KAAI,SAAS,OAAO,SAAS,UAAU,EACrC,OAAM,IAAI,MAAM,yCAAyC;AAG3D,QAAO;EACL,MAAM;EACN,UAAU,SAAS,MAAM,EAAE;EAC5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACuCH,MAAa,oBAKX,WACA,YAC2B;AAC3B,QAAO,IAAI,WAAW,QAAQ,OAAO,QAAQ,OAAO;;;;;;;;;;;;;;;;;AAkBtD,MAAa,8BAKX,YAM0E;AAC1E,QAAO;EACL,MAAM;EACN,cAAc,aAAa,iBAAiB,UAAU,QAAQ;EAC/D;;;;;AC7HH,SAAgB,UACd,KACA,IAGA;AACA,QAAO,OAAO,YAAa,OAAO,QAAQ,IAAI,CAAwB,KAAK,CAAC,KAAK,WAAW,CAAC,KAAK,GAAG,OAAO,IAAI,CAAC,CAAC,CAAC;;;;;ACgBrH,SAAS,gBAAgB,OAAwF;CAC/G,MAAM,eAAe,MAAM,QACxB,KAAqD,EAAE,OAAO,KAAK,UAAU,CAAC,SAAS,GAAG,gBAAgB;AACzG,MAAI,QACF,EAAC,IAAI,aAAa,IAAI,WAAW,EAAE,GAAG,KAAK;GAAE;GAAO;GAAK;GAAU,CAAC;AAEtE,SAAO;IAET,EAAE,CACH;AAED,QAAO;EACL,SAAS,MAAM,KAAK,EAAE,OAAO,KAAK,gBAAgB;GAAE;GAAO,MAAM;GAAK,OAAO,SAAS,WAAW;GAAG,EAAE;EACtG,UAAU,UAAU,eAAe,YAAU,gBAAgBC,QAAM,CAAC;EACrE;;;;;;AAOH,SAAgB,gCAAgC,WAA6B;AAY3E,QAAO,gBAXO,OAAO,QAAQ,UAAU,CAAC,SAAS,CAAC,OAAO,WACvD,MAAM,KACJ,IAAI,IACF,MAAM,WAAW,MAAM,KAAK,EAAE,MAAM,KAAK,eAAe;EACtD,MAAM,CAAC,OAAO,GAAG,QAAQ;AACzB,SAAO,CAAC,KAAK;GAAE;GAAO;GAAK,UAAU,CAAC,GAAG,MAAM,GAAG,SAAS,GAAG,KAAK;GAAE,CAAC;GACtE,CACH,CAAC,QAAQ,CACX,CACF,CAE4B;;;;;;ACjB/B,IAAM,8BAAN,MAAyC;CACvC,YAAyD;AACvD,SAAO,KAAK,SAAS;;CAEvB,UAAqD;AACnD,SAAO,KAAK,SAAS;;CAEvB,UAAqD;AACnD,SAAO,KAAK,SAAS;;CAGvB,YAAY,AAAiBC,MAAqC;EAArC;;;;AAI/B,IAAa,6BAAb,cACU,4BAEV;CACE,cAAc;AACZ,QAAM,QAAQ;;CAGhB,SAAe;AACb,SAAO;;CAGT,aAAa;AACX,SAAO;GACL,MAAM;GACN,OAAO;GACR;;;;AAKL,IAAa,+BAAb,cACU,4BAEV;CACE,YACE,AAAgBC,MAChB,AAAgBC,YAChB;AACA,QAAM,UAAU;EAHA;EACA;;CAKlB,SAAgB;AACd,SAAO,KAAK;;CAGd,WAAyB,WAA0C;AACjE,SAAO;GACL,MAAM,UAAU,KAAK,KAAK;GAC1B,OAAO;GACR;;;;AAKL,IAAa,6BAAb,cACU,4BAEV;CACE,YACE,AAAgBC,OAChB,AAAgBD,YAChB;AACA,QAAM,QAAQ;EAHE;EACA;;CAKlB,SAAgB;AACd,QAAM,KAAK;;CAGb,aAAa;AACX,SAAO;GACL,MAAM;GACN,OAAO,KAAK;GACb;;;;;;AClHL,MAAM,4BAA4B;AAElC,UAAU,wBAAwB,QAA0C,qBAA8C;AACxH,MAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,YAAY,MAAM,QAAQ,EAAE;EAClC,IAAI,QAAQ;AAEZ,OACE,IAAI,IAAI,GAER,KAAK,UAAU,QACf,KACA;GACA,MAAM,UAAU,UAAU;AAE1B,OAEE,WAAW,QAEX,OAAO,YAAY,UACnB;AACA,WAAO,MAAM,QAAQ,KAAK,EAAE,OAAO,YAAY;KAAE;KAAO;KAAM;KAAO,EAAE;AACvE;;AAGF,UAAO,MAAM,QAAQ,QAAQ,EAAE,YAAY,MAAM,CAAC,KAAK,EAAE,OAAO,YAAY;IAAE;IAAO;IAAM;IAAO,EAAE;GAEpG,MAAM,OAAO,MAAM,SAAS;AAC5B,OAAI,CAAC,KACH;AAGF,WAAQ;;;;AAKd,MAAM,mBAAmB,QAAsD,wBAAiD;CAC9H,MAAME,YAAyF,EAAE;AACjG,MAAK,MAAM,EAAE,OAAO,MAAM,WAAW,wBAAwB,UAAU,EAAE,EAAE,oBAAoB,EAAE;EAC/F,MAAM,cAAc,UAAU,WAAW,UAAU,SAAS,EAAE;AAE9D,GADmB,YAAY,UAAU,YAAY,QAAQ,EAAE,GACpD,KAAK,EAAE,OAAO,CAAC;;AAE5B,QAAO;;AAGT,MAAM,4BAA4B,MAAc,iBAA2B;CACzE,IAAIC,UAAmB;AAEvB,MAAK,MAAM,WAAW,cAAc;AAClC,MAAI,WAAW,KACb,QAAO,EAAE,uBAAO,IAAI,MAAM,UAAU,EAAE;AAGxC,MAAI,OAAO,YAAY,SACrB,QAAO,EAAE,uBAAO,IAAI,MAAM,sBAAsB,EAAE;AAGpD,MAAI,MAAM,QAAQ,QAAQ,CACxB,QAAO,EAAE,uBAAO,IAAI,MAAM,sBAAsB,EAAE;AAGpD,YAAW,QAAoC;;AAGjD,QAAO,EAAE,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;AAwB1B,MAAa,+BAAiE,WAAoB;CAEhG,MAAM,sBAAsB,0BAA0B,OAAO;CAC7D,MAAM,YAAY;CAClB,MAAM,WAAW,WAAsD;AACrE,MAAI,OAAO,SAAS,WAAW;GAC7B,MAAM,YAAY,gBAAgB,OAAO,KAAK,QAAQ,oBAAoB;AAE1E,UAAO;IAAE,GAAG;IAAQ;IAAW;;AAGjC,MAAI,OAAO,SAAS,oBAClB,QAAO;GAAE,GAAG;GAAQ,OAAO,IAAI,2BAA2B;IAAE,MAAM;IAAqB,OAAO,OAAO;IAAO,CAAC;GAAE;AAGjH,MAAI,OAAO,SAAS,QAClB,QAAO;GAAE,GAAG;GAAQ,OAAO,IAAI,4BAA4B;GAAE;AAG/D,QAAM,IAAI,MAAM,uBAAuB,EAAE,OAAO,QAAwB,CAAC;;AAG3E,SAAQ,WAAsD;EAC5D,MAAM,WAAW,QAAQ,OAAO;EAEhC,MAAM,UAAU,OAAO,QAAQ,UAAU,CAAC,KAAK,CAAC,OAAO,cAAc;GACnE,MAAM,EAAE,eAAe;AAEvB,OAAI,SAAS,SAAS,WAAW;IAC/B,MAAM,gBAAgB,WAAW,MAAM,SAAS,EAAE,MAAM,UAAU,SAAS,UAAU,SAAS,QAAQ,EAAE,CAAC;IACzG,MAAM,eAAe,MAAM,KAAK,IAAI,IAAI,cAAc,KAAK,EAAE,YAAY,MAAM,CAAC,CAAC,QAAQ,CAAC;AAE1F,QAAI,aAAa,SAAS,EACxB,QAAO,CAAC,OAAO,WAAW,UAAU,IAAI,2BAA2B;KAAE,MAAM;KAAiB,QAAQ;KAAc,CAAC,CAAC,CAAC;IAIvH,MAAM,cAAc,WAAW,MAAM,KAAK,EAAE,eAAe;KACzD,MAAM,CAAC,OAAO,GAAG,QAAQ;KACzB,MAAM,mBAAmB,CAAC,GAAG,MAAM,GAAG,SAAS,GAAG,KAAK;AACvD,YAAO,SAAS,KAAK,OACjB,yBAAyB,SAAS,KAAK,MAAM,iBAAiB,GAC9D,EAAE,uBAAO,IAAI,MAAM,UAAU,EAAE;MACnC;AACF,QAAI,YAAY,MAAM,EAAE,YAAY,MAAM,EAAE;KAC1C,MAAM,SAAS,YAAY,SAAS,EAAE,YAAa,QAAQ,CAAC,MAAM,GAAG,EAAE,CAAE;AACzE,YAAO,CAAC,OAAO,WAAW,UAAU,IAAI,2BAA2B;MAAE,MAAM;MAAe;MAAQ,CAAC,CAAC,CAAC;;IAGvG,MAAM,WAAW,YAAY,KAAK,EAAE,WAAW,KAAK;AACpD,WAAO,CAAC,OAAO,WAAW,UAAU,IAAI,6BAA6B,SAAS,CAAC,CAAC;;AAGlF,OAAI,SAAS,SAAS,oBACpB,QAAO,CAAC,OAAO,WAAW,UAAU,SAAS,MAAM,CAAC;AAGtD,OAAI,SAAS,SAAS,QACpB,QAAO,CAAC,OAAO,WAAW,UAAU,SAAS,MAAM,CAAC;AAGtD,SAAM,IAAI,MAAM,uBAAuB,EAAE,OAAO,UAA0B,CAAC;IAC3E;AAEF,SAAO,OAAO,YAAY,QAAQ"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soda-gql/colocation-tools",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "Colocation utilities for soda-gql fragments",
5
5
  "type": "module",
6
6
  "private": false,
@@ -47,7 +47,7 @@
47
47
  "./package.json": "./package.json"
48
48
  },
49
49
  "dependencies": {
50
- "@soda-gql/core": "~0.6.0",
50
+ "@soda-gql/core": "~0.7.0",
51
51
  "graphql": "^16.11.0"
52
52
  },
53
53
  "devDependencies": {},