fraiseql 2.2.0 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -855,8 +855,14 @@ declare function Type(_config?: TypeConfig): <T extends {
855
855
  /**
856
856
  * Configuration for Query and Mutation decorators.
857
857
  */
858
+ interface SqlSourceDispatchConfig {
859
+ argument: string;
860
+ mapping?: Record<string, string>;
861
+ template?: string;
862
+ }
858
863
  interface OperationConfig {
859
864
  sqlSource?: string;
865
+ sqlSourceDispatch?: SqlSourceDispatchConfig;
860
866
  autoParams?: Record<string, boolean>;
861
867
  operation?: string;
862
868
  jsonbColumn?: string;
@@ -1108,34 +1114,46 @@ declare function registerTypeFields(typeName: string, fields: Field[], descripti
1108
1114
  crud?: boolean | string[];
1109
1115
  cascade?: boolean;
1110
1116
  }): void;
1117
+ /**
1118
+ * Config object form for registerQuery.
1119
+ */
1120
+ interface RegisterQueryConfig {
1121
+ returnType: string;
1122
+ returnsList?: boolean;
1123
+ nullable?: boolean;
1124
+ arguments?: ArgumentDefinition[];
1125
+ description?: string;
1126
+ sqlSource?: string;
1127
+ sqlSourceDispatch?: {
1128
+ argument: string;
1129
+ mapping?: Record<string, string>;
1130
+ template?: string;
1131
+ };
1132
+ [key: string]: unknown;
1133
+ }
1111
1134
  /**
1112
1135
  * Helper function to manually register query with full metadata.
1113
1136
  *
1114
- * @param name - Query name
1115
- * @param returnType - Return type name
1116
- * @param returnsList - Whether query returns a list
1117
- * @param nullable - Whether result can be null
1118
- * @param args - Argument definitions
1119
- * @param description - Optional query description
1120
- * @param config - Additional configuration
1137
+ * Accepts either the classic positional style:
1138
+ * registerQuery(name, returnType, returnsList, nullable, args, description?, config?)
1139
+ *
1140
+ * Or a compact object style:
1141
+ * registerQuery(name, { returnType, returnsList?, nullable?, arguments?, sqlSourceDispatch?, ... })
1121
1142
  *
1122
1143
  * @example
1123
1144
  * ```ts
1124
- * registerQuery(
1125
- * "users",
1126
- * "User",
1127
- * true,
1128
- * false,
1129
- * [
1130
- * { name: "limit", type: "Int", nullable: false, default: 10 },
1131
- * { name: "offset", type: "Int", nullable: false, default: 0 }
1132
- * ],
1133
- * "Get list of users",
1134
- * { sql_source: "v_user" }
1135
- * );
1145
+ * registerQuery("orders", {
1146
+ * returnType: "Order",
1147
+ * returnsList: true,
1148
+ * sqlSourceDispatch: {
1149
+ * argument: "interval",
1150
+ * mapping: { DAY: "tf_orders_day", WEEK: "tf_orders_week" },
1151
+ * },
1152
+ * arguments: [{ name: "interval", type: "TimeInterval", nullable: false }],
1153
+ * });
1136
1154
  * ```
1137
1155
  */
1138
- declare function registerQuery(name: string, returnType: string, returnsList: boolean, nullable: boolean, args: ArgumentDefinition[], description?: string, config?: Record<string, unknown>): void;
1156
+ declare function registerQuery(name: string, returnTypeOrConfig: string | RegisterQueryConfig, returnsList?: boolean, nullable?: boolean, args?: ArgumentDefinition[], description?: string, config?: Record<string, unknown>): void;
1139
1157
  /**
1140
1158
  * Helper function to manually register mutation with full metadata.
1141
1159
  *
package/dist/index.d.ts CHANGED
@@ -855,8 +855,14 @@ declare function Type(_config?: TypeConfig): <T extends {
855
855
  /**
856
856
  * Configuration for Query and Mutation decorators.
857
857
  */
858
+ interface SqlSourceDispatchConfig {
859
+ argument: string;
860
+ mapping?: Record<string, string>;
861
+ template?: string;
862
+ }
858
863
  interface OperationConfig {
859
864
  sqlSource?: string;
865
+ sqlSourceDispatch?: SqlSourceDispatchConfig;
860
866
  autoParams?: Record<string, boolean>;
861
867
  operation?: string;
862
868
  jsonbColumn?: string;
@@ -1108,34 +1114,46 @@ declare function registerTypeFields(typeName: string, fields: Field[], descripti
1108
1114
  crud?: boolean | string[];
1109
1115
  cascade?: boolean;
1110
1116
  }): void;
1117
+ /**
1118
+ * Config object form for registerQuery.
1119
+ */
1120
+ interface RegisterQueryConfig {
1121
+ returnType: string;
1122
+ returnsList?: boolean;
1123
+ nullable?: boolean;
1124
+ arguments?: ArgumentDefinition[];
1125
+ description?: string;
1126
+ sqlSource?: string;
1127
+ sqlSourceDispatch?: {
1128
+ argument: string;
1129
+ mapping?: Record<string, string>;
1130
+ template?: string;
1131
+ };
1132
+ [key: string]: unknown;
1133
+ }
1111
1134
  /**
1112
1135
  * Helper function to manually register query with full metadata.
1113
1136
  *
1114
- * @param name - Query name
1115
- * @param returnType - Return type name
1116
- * @param returnsList - Whether query returns a list
1117
- * @param nullable - Whether result can be null
1118
- * @param args - Argument definitions
1119
- * @param description - Optional query description
1120
- * @param config - Additional configuration
1137
+ * Accepts either the classic positional style:
1138
+ * registerQuery(name, returnType, returnsList, nullable, args, description?, config?)
1139
+ *
1140
+ * Or a compact object style:
1141
+ * registerQuery(name, { returnType, returnsList?, nullable?, arguments?, sqlSourceDispatch?, ... })
1121
1142
  *
1122
1143
  * @example
1123
1144
  * ```ts
1124
- * registerQuery(
1125
- * "users",
1126
- * "User",
1127
- * true,
1128
- * false,
1129
- * [
1130
- * { name: "limit", type: "Int", nullable: false, default: 10 },
1131
- * { name: "offset", type: "Int", nullable: false, default: 0 }
1132
- * ],
1133
- * "Get list of users",
1134
- * { sql_source: "v_user" }
1135
- * );
1145
+ * registerQuery("orders", {
1146
+ * returnType: "Order",
1147
+ * returnsList: true,
1148
+ * sqlSourceDispatch: {
1149
+ * argument: "interval",
1150
+ * mapping: { DAY: "tf_orders_day", WEEK: "tf_orders_week" },
1151
+ * },
1152
+ * arguments: [{ name: "interval", type: "TimeInterval", nullable: false }],
1153
+ * });
1136
1154
  * ```
1137
1155
  */
1138
- declare function registerQuery(name: string, returnType: string, returnsList: boolean, nullable: boolean, args: ArgumentDefinition[], description?: string, config?: Record<string, unknown>): void;
1156
+ declare function registerQuery(name: string, returnTypeOrConfig: string | RegisterQueryConfig, returnsList?: boolean, nullable?: boolean, args?: ArgumentDefinition[], description?: string, config?: Record<string, unknown>): void;
1139
1157
  /**
1140
1158
  * Helper function to manually register mutation with full metadata.
1141
1159
  *
package/dist/index.js CHANGED
@@ -230,6 +230,7 @@ var VALID_REST_METHODS = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH",
230
230
  function normaliseConfig(config2) {
231
231
  const keyMap = {
232
232
  sqlSource: "sql_source",
233
+ sqlSourceDispatch: "sql_source_dispatch",
233
234
  autoParams: "auto_params",
234
235
  jsonbColumn: "jsonb_column",
235
236
  cacheTtlSeconds: "cache_ttl_seconds",
@@ -861,8 +862,53 @@ function registerTypeFields(typeName, fields, description, options) {
861
862
  generateCrudOperations(typeName, fields, options.crud, options.sqlSource, options.cascade);
862
863
  }
863
864
  }
864
- function registerQuery(name, returnType, returnsList, nullable, args, description, config2) {
865
- SchemaRegistry.registerQuery(name, returnType, returnsList, nullable, args, description, config2);
865
+ var SAFE_SQL_IDENT = /^[A-Za-z_][A-Za-z0-9_$]*$/;
866
+ function registerQuery(name, returnTypeOrConfig, returnsList, nullable, args, description, config2) {
867
+ if (typeof returnTypeOrConfig === "object" && returnTypeOrConfig !== null) {
868
+ const cfg = returnTypeOrConfig;
869
+ const dispatch = cfg.sqlSourceDispatch;
870
+ if (dispatch !== void 0) {
871
+ if (cfg.sqlSource !== void 0) {
872
+ throw new Error(
873
+ `registerQuery('${name}'): sqlSource and sqlSourceDispatch are mutually exclusive.`
874
+ );
875
+ }
876
+ const dispatchArg = dispatch.argument;
877
+ const queryArgs = cfg.arguments ?? [];
878
+ const argDef = queryArgs.find((a) => a.name === dispatchArg);
879
+ if (argDef === void 0) {
880
+ throw new Error(
881
+ `registerQuery('${name}'): sqlSourceDispatch argument '${dispatchArg}' not found in arguments list.`
882
+ );
883
+ }
884
+ if (argDef.nullable) {
885
+ throw new Error(
886
+ `registerQuery('${name}'): sqlSourceDispatch argument '${dispatchArg}' must be non-nullable.`
887
+ );
888
+ }
889
+ if (dispatch.mapping !== void 0) {
890
+ for (const [key, value] of Object.entries(dispatch.mapping)) {
891
+ if (!SAFE_SQL_IDENT.test(value)) {
892
+ throw new Error(
893
+ `registerQuery('${name}'): sql_source_dispatch mapping value '${value}' for key '${key}' is not a safe SQL identifier.`
894
+ );
895
+ }
896
+ }
897
+ }
898
+ }
899
+ const { returnType, returnsList: rl, nullable: nl, arguments: qArgs, description: desc, ...rest } = cfg;
900
+ SchemaRegistry.registerQuery(
901
+ name,
902
+ returnType,
903
+ rl ?? false,
904
+ nl ?? false,
905
+ qArgs ?? [],
906
+ desc,
907
+ rest
908
+ );
909
+ return;
910
+ }
911
+ SchemaRegistry.registerQuery(name, returnTypeOrConfig, returnsList ?? false, nullable ?? false, args ?? [], description, config2);
866
912
  }
867
913
  function registerMutation(name, returnType, returnsList, nullable, args, description, config2) {
868
914
  SchemaRegistry.registerMutation(
package/dist/index.mjs CHANGED
@@ -151,6 +151,7 @@ var VALID_REST_METHODS = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH",
151
151
  function normaliseConfig(config2) {
152
152
  const keyMap = {
153
153
  sqlSource: "sql_source",
154
+ sqlSourceDispatch: "sql_source_dispatch",
154
155
  autoParams: "auto_params",
155
156
  jsonbColumn: "jsonb_column",
156
157
  cacheTtlSeconds: "cache_ttl_seconds",
@@ -782,8 +783,53 @@ function registerTypeFields(typeName, fields, description, options) {
782
783
  generateCrudOperations(typeName, fields, options.crud, options.sqlSource, options.cascade);
783
784
  }
784
785
  }
785
- function registerQuery(name, returnType, returnsList, nullable, args, description, config2) {
786
- SchemaRegistry.registerQuery(name, returnType, returnsList, nullable, args, description, config2);
786
+ var SAFE_SQL_IDENT = /^[A-Za-z_][A-Za-z0-9_$]*$/;
787
+ function registerQuery(name, returnTypeOrConfig, returnsList, nullable, args, description, config2) {
788
+ if (typeof returnTypeOrConfig === "object" && returnTypeOrConfig !== null) {
789
+ const cfg = returnTypeOrConfig;
790
+ const dispatch = cfg.sqlSourceDispatch;
791
+ if (dispatch !== void 0) {
792
+ if (cfg.sqlSource !== void 0) {
793
+ throw new Error(
794
+ `registerQuery('${name}'): sqlSource and sqlSourceDispatch are mutually exclusive.`
795
+ );
796
+ }
797
+ const dispatchArg = dispatch.argument;
798
+ const queryArgs = cfg.arguments ?? [];
799
+ const argDef = queryArgs.find((a) => a.name === dispatchArg);
800
+ if (argDef === void 0) {
801
+ throw new Error(
802
+ `registerQuery('${name}'): sqlSourceDispatch argument '${dispatchArg}' not found in arguments list.`
803
+ );
804
+ }
805
+ if (argDef.nullable) {
806
+ throw new Error(
807
+ `registerQuery('${name}'): sqlSourceDispatch argument '${dispatchArg}' must be non-nullable.`
808
+ );
809
+ }
810
+ if (dispatch.mapping !== void 0) {
811
+ for (const [key, value] of Object.entries(dispatch.mapping)) {
812
+ if (!SAFE_SQL_IDENT.test(value)) {
813
+ throw new Error(
814
+ `registerQuery('${name}'): sql_source_dispatch mapping value '${value}' for key '${key}' is not a safe SQL identifier.`
815
+ );
816
+ }
817
+ }
818
+ }
819
+ }
820
+ const { returnType, returnsList: rl, nullable: nl, arguments: qArgs, description: desc, ...rest } = cfg;
821
+ SchemaRegistry.registerQuery(
822
+ name,
823
+ returnType,
824
+ rl ?? false,
825
+ nl ?? false,
826
+ qArgs ?? [],
827
+ desc,
828
+ rest
829
+ );
830
+ return;
831
+ }
832
+ SchemaRegistry.registerQuery(name, returnTypeOrConfig, returnsList ?? false, nullable ?? false, args ?? [], description, config2);
787
833
  }
788
834
  function registerMutation(name, returnType, returnsList, nullable, args, description, config2) {
789
835
  SchemaRegistry.registerMutation(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fraiseql",
3
- "version": "2.2.0",
3
+ "version": "2.2.1",
4
4
  "description": "FraiseQL v2 - Compiled GraphQL execution engine (schema authoring + HTTP client)",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",