@query-farm/vgi 0.8.0 → 0.9.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.
@@ -8,7 +8,56 @@ export interface ArgumentSpec {
8
8
  isVarargs?: boolean;
9
9
  isConst?: boolean;
10
10
  doc?: string;
11
+ /**
12
+ * Discovery-facing constraint metadata, pre-encoded to their surfaced UTF-8
13
+ * forms (presence-only — `undefined` means the constraint is absent and the
14
+ * corresponding field-metadata key is omitted entirely). Mirrors Python's
15
+ * `ArgumentSpec.default_json` / `choices_json` / `range_notation` / `pattern`
16
+ * so `argumentSpecsToSchema`/`schemaToArgumentSpecs` round-trip symmetrically.
17
+ */
18
+ defaultJson?: string;
19
+ choicesJson?: string;
20
+ rangeNotation?: string;
21
+ pattern?: string;
11
22
  }
23
+ /**
24
+ * Raw per-argument constraint declarations, as authored on a function's
25
+ * argument descriptor. Encoded into the pre-computed {@link ArgumentSpec}
26
+ * constraint fields via {@link constraintSpecFields}.
27
+ */
28
+ export interface ArgumentConstraints {
29
+ /** Closed set of allowed values (JSON-encoded into `vgi_choices`). */
30
+ choices?: readonly unknown[];
31
+ /** Inclusive lower bound (`>=`). */
32
+ ge?: number;
33
+ /** Inclusive upper bound (`<=`). */
34
+ le?: number;
35
+ /** Exclusive lower bound (`>`). */
36
+ gt?: number;
37
+ /** Exclusive upper bound (`<`). */
38
+ lt?: number;
39
+ /** Regex the value must match (surfaced as `vgi_pattern`, as-is). */
40
+ pattern?: string;
41
+ /** Default value (JSON-encoded into `vgi_default`); optional args only. */
42
+ default?: unknown;
43
+ }
44
+ /**
45
+ * Build interval notation from an argument's numeric bounds.
46
+ *
47
+ * Inclusive bounds (`ge`/`le`) render as square brackets, exclusive bounds
48
+ * (`gt`/`lt`) as parentheses, and an open side as `-inf`/`+inf`. Returns
49
+ * `undefined` when the argument has no numeric bound at all.
50
+ *
51
+ * Examples: `ge=0,le=10` -> `"[0, 10]"`; `gt=0` -> `"(0, +inf)"`;
52
+ * `ge=1,lt=10` -> `"[1, 10)"`.
53
+ */
54
+ export declare function formatRange(ge?: number, le?: number, gt?: number, lt?: number): string | undefined;
55
+ /**
56
+ * Encode raw {@link ArgumentConstraints} into the pre-computed constraint
57
+ * fields of an {@link ArgumentSpec} (presence-only — absent constraints yield
58
+ * no field). Mirrors Python's `_constraint_kwargs`.
59
+ */
60
+ export declare function constraintSpecFields(constraints: ArgumentConstraints | undefined): Pick<ArgumentSpec, "defaultJson" | "choicesJson" | "rangeNotation" | "pattern">;
12
61
  /**
13
62
  * Convert ArgumentSpecs to an Arrow Schema with VGI metadata keys.
14
63
  * Positional arguments come first (in order), named arguments follow.
@@ -25,6 +25,20 @@ export interface ScalarParameterDef {
25
25
  varargs?: boolean;
26
26
  /** Human-readable per-argument description (surfaced as `vgi_doc`). */
27
27
  doc?: string;
28
+ /** Closed set of allowed values (surfaced as `vgi_choices`). */
29
+ choices?: readonly unknown[];
30
+ /** Inclusive lower bound, `>=` (folded into `vgi_range`). */
31
+ ge?: number;
32
+ /** Inclusive upper bound, `<=` (folded into `vgi_range`). */
33
+ le?: number;
34
+ /** Exclusive lower bound, `>` (folded into `vgi_range`). */
35
+ gt?: number;
36
+ /** Exclusive upper bound, `<` (folded into `vgi_range`). */
37
+ lt?: number;
38
+ /** Regex the value must match (surfaced as `vgi_pattern`). */
39
+ pattern?: string;
40
+ /** Default value (surfaced as `vgi_default`, JSON-encoded). */
41
+ default?: unknown;
28
42
  }
29
43
  /**
30
44
  * The typed compute row for a scalar function: one property per declared
@@ -14,7 +14,7 @@ export { FunctionRegistry } from "./functions/registry.js";
14
14
  export { FunctionType, FunctionStability, NullHandling, OrderPreservation, OrderDependence, DistinctDependence, TableInOutPhase, DEFAULT_MAX_WORKERS, } from "./types.js";
15
15
  export type { BindRequest, BindResponse, CopyFromContext, CopyToContext, InitRequest, GlobalInitResponse, TableCardinality, } from "./protocol/types.js";
16
16
  export { Arguments } from "./arguments/arguments.js";
17
- export { type ArgumentSpec, argumentSpecsToSchema, schemaToArgumentSpecs, macroArgumentsSchema, macroParameterDocsFromSchema } from "./arguments/argument-spec.js";
17
+ export { type ArgumentSpec, type ArgumentConstraints, argumentSpecsToSchema, schemaToArgumentSpecs, macroArgumentsSchema, macroParameterDocsFromSchema, formatRange, constraintSpecFields } from "./arguments/argument-spec.js";
18
18
  export { VgiError, RowCountMismatchError, FunctionNotFoundError, CatalogReadOnlyError, CatalogNotFoundError, CatalogAlreadyExistsError, ArgumentValidationError, NoCatalogError, } from "./errors.js";
19
19
  export type { ResolvedMetadata, ParameterInfo } from "./metadata/types.js";
20
20
  export { CatalogFunctionType } from "./metadata/types.js";
package/dist/index.js CHANGED
@@ -2600,6 +2600,10 @@ var VGI_VARARGS_TRUE = "true";
2600
2600
  var VGI_CONST_KEY = "vgi_const";
2601
2601
  var VGI_CONST_TRUE = "true";
2602
2602
  var VGI_DOC_KEY = "vgi_doc";
2603
+ var VGI_DEFAULT_KEY = "vgi_default";
2604
+ var VGI_CHOICES_KEY = "vgi_choices";
2605
+ var VGI_RANGE_KEY = "vgi_range";
2606
+ var VGI_PATTERN_KEY = "vgi_pattern";
2603
2607
  var DEFAULT_MAX_WORKERS = 99999;
2604
2608
 
2605
2609
  // src/errors.ts
@@ -2659,6 +2663,180 @@ class NoCatalogError extends VgiError {
2659
2663
  }
2660
2664
  }
2661
2665
 
2666
+ // src/arguments/argument-spec.ts
2667
+ init_arrow();
2668
+ function safeJson(value) {
2669
+ try {
2670
+ const encoded = JSON.stringify(value);
2671
+ if (encoded === undefined) {
2672
+ return JSON.stringify(String(value));
2673
+ }
2674
+ return encoded;
2675
+ } catch {
2676
+ return JSON.stringify(String(value));
2677
+ }
2678
+ }
2679
+ function formatRange(ge, le, gt, lt) {
2680
+ if (ge === undefined && le === undefined && gt === undefined && lt === undefined) {
2681
+ return;
2682
+ }
2683
+ let low;
2684
+ if (gt !== undefined) {
2685
+ low = `(${gt}`;
2686
+ } else if (ge !== undefined) {
2687
+ low = `[${ge}`;
2688
+ } else {
2689
+ low = "(-inf";
2690
+ }
2691
+ let high;
2692
+ if (lt !== undefined) {
2693
+ high = `${lt})`;
2694
+ } else if (le !== undefined) {
2695
+ high = `${le}]`;
2696
+ } else {
2697
+ high = "+inf)";
2698
+ }
2699
+ return `${low}, ${high}`;
2700
+ }
2701
+ function constraintSpecFields(constraints) {
2702
+ const fields = {};
2703
+ if (constraints === undefined)
2704
+ return fields;
2705
+ if ("default" in constraints && constraints.default !== undefined) {
2706
+ fields.defaultJson = safeJson(constraints.default);
2707
+ }
2708
+ if (constraints.choices !== undefined) {
2709
+ fields.choicesJson = safeJson([...constraints.choices]);
2710
+ }
2711
+ const range = formatRange(constraints.ge, constraints.le, constraints.gt, constraints.lt);
2712
+ if (range !== undefined) {
2713
+ fields.rangeNotation = range;
2714
+ }
2715
+ if (constraints.pattern !== undefined) {
2716
+ fields.pattern = constraints.pattern;
2717
+ }
2718
+ return fields;
2719
+ }
2720
+ function argumentSpecSortKey(spec) {
2721
+ if (typeof spec.position === "number") {
2722
+ return [0, spec.position];
2723
+ }
2724
+ return [1, spec.position];
2725
+ }
2726
+ function argumentSpecsToSchema(specs) {
2727
+ const sorted = [...specs].sort((a, b) => {
2728
+ const ka = argumentSpecSortKey(a);
2729
+ const kb = argumentSpecSortKey(b);
2730
+ if (ka[0] !== kb[0])
2731
+ return ka[0] - kb[0];
2732
+ if (typeof ka[1] === "number" && typeof kb[1] === "number") {
2733
+ return ka[1] - kb[1];
2734
+ }
2735
+ return String(ka[1]).localeCompare(String(kb[1]));
2736
+ });
2737
+ const fields = [];
2738
+ for (const spec of sorted) {
2739
+ const metadata = new Map;
2740
+ if (typeof spec.position === "string") {
2741
+ metadata.set(VGI_ARG_KEY, VGI_ARG_NAMED);
2742
+ }
2743
+ if (spec.isTableInput) {
2744
+ metadata.set(VGI_TYPE_KEY, VGI_TYPE_TABLE);
2745
+ } else if (spec.isAnyType) {
2746
+ metadata.set(VGI_TYPE_KEY, VGI_TYPE_ANY);
2747
+ }
2748
+ if (spec.isVarargs) {
2749
+ metadata.set(VGI_VARARGS_KEY, VGI_VARARGS_TRUE);
2750
+ }
2751
+ if (spec.isConst) {
2752
+ metadata.set(VGI_CONST_KEY, VGI_CONST_TRUE);
2753
+ }
2754
+ if (spec.doc) {
2755
+ metadata.set(VGI_DOC_KEY, spec.doc);
2756
+ }
2757
+ if (spec.defaultJson !== undefined) {
2758
+ metadata.set(VGI_DEFAULT_KEY, spec.defaultJson);
2759
+ }
2760
+ if (spec.choicesJson !== undefined) {
2761
+ metadata.set(VGI_CHOICES_KEY, spec.choicesJson);
2762
+ }
2763
+ if (spec.rangeNotation !== undefined) {
2764
+ metadata.set(VGI_RANGE_KEY, spec.rangeNotation);
2765
+ }
2766
+ if (spec.pattern !== undefined) {
2767
+ metadata.set(VGI_PATTERN_KEY, spec.pattern);
2768
+ }
2769
+ const field3 = field2(spec.name, spec.arrowType, true, metadata.size > 0 ? metadata : undefined);
2770
+ fields.push(field3);
2771
+ }
2772
+ return schema2(fields);
2773
+ }
2774
+ function macroArgumentsSchema(parameters, parameterDefaultValues, parameterDocs) {
2775
+ const docs = parameterDocs ?? {};
2776
+ const defaultTypes = new Map;
2777
+ if (parameterDefaultValues && parameterDefaultValues.length > 0) {
2778
+ const batch = deserializeBatch(parameterDefaultValues);
2779
+ for (const f of batch.schema.fields) {
2780
+ defaultTypes.set(f.name, f.type);
2781
+ }
2782
+ }
2783
+ const fields = [];
2784
+ for (const name of parameters) {
2785
+ const metadata = new Map;
2786
+ const doc = docs[name];
2787
+ if (doc) {
2788
+ metadata.set(VGI_DOC_KEY, doc);
2789
+ }
2790
+ const fieldType = defaultTypes.get(name) ?? nullType2();
2791
+ fields.push(field2(name, fieldType, true, metadata.size > 0 ? metadata : undefined));
2792
+ }
2793
+ return schema2(fields);
2794
+ }
2795
+ function macroParameterDocsFromSchema(schema3) {
2796
+ const docs = {};
2797
+ for (const field3 of schema3.fields) {
2798
+ const doc = field3.metadata.get(VGI_DOC_KEY);
2799
+ if (doc) {
2800
+ docs[field3.name] = doc;
2801
+ }
2802
+ }
2803
+ return docs;
2804
+ }
2805
+ function schemaToArgumentSpecs(schema3) {
2806
+ const specs = [];
2807
+ let positionIndex = 0;
2808
+ for (const field3 of schema3.fields) {
2809
+ const metadata = field3.metadata;
2810
+ const isNamed = metadata.get(VGI_ARG_KEY) === VGI_ARG_NAMED;
2811
+ const position = isNamed ? field3.name : positionIndex++;
2812
+ const vgiType = metadata.get(VGI_TYPE_KEY);
2813
+ const isTableInput = vgiType === VGI_TYPE_TABLE;
2814
+ const isAnyType = vgiType === VGI_TYPE_ANY;
2815
+ const isVarargs = metadata.get(VGI_VARARGS_KEY) === VGI_VARARGS_TRUE;
2816
+ const isConst = metadata.get(VGI_CONST_KEY) === VGI_CONST_TRUE;
2817
+ const doc = metadata.get(VGI_DOC_KEY) ?? "";
2818
+ const defaultJson = metadata.get(VGI_DEFAULT_KEY);
2819
+ const choicesJson = metadata.get(VGI_CHOICES_KEY);
2820
+ const rangeNotation = metadata.get(VGI_RANGE_KEY);
2821
+ const pattern = metadata.get(VGI_PATTERN_KEY);
2822
+ specs.push({
2823
+ name: field3.name,
2824
+ position,
2825
+ arrowType: field3.type,
2826
+ isTableInput,
2827
+ isAnyType,
2828
+ isVarargs,
2829
+ isConst,
2830
+ doc,
2831
+ defaultJson,
2832
+ choicesJson,
2833
+ rangeNotation,
2834
+ pattern
2835
+ });
2836
+ }
2837
+ return specs;
2838
+ }
2839
+
2662
2840
  // src/util/arrow/index.ts
2663
2841
  init_arrow();
2664
2842
 
@@ -2676,7 +2854,8 @@ function defineScalarFunction(config) {
2676
2854
  isAnyType: isAny,
2677
2855
  isConst: p.const,
2678
2856
  isVarargs: p.varargs,
2679
- doc: p.doc
2857
+ doc: p.doc,
2858
+ ...constraintSpecFields(p)
2680
2859
  });
2681
2860
  }
2682
2861
  } else {
@@ -6322,108 +6501,6 @@ function serializeColumnStatistics(stats, _cacheMaxAgeSeconds) {
6322
6501
  return serializeBatch(buildStatisticsBatch(stats));
6323
6502
  }
6324
6503
 
6325
- // src/arguments/argument-spec.ts
6326
- init_arrow();
6327
- function argumentSpecSortKey(spec) {
6328
- if (typeof spec.position === "number") {
6329
- return [0, spec.position];
6330
- }
6331
- return [1, spec.position];
6332
- }
6333
- function argumentSpecsToSchema(specs) {
6334
- const sorted = [...specs].sort((a, b) => {
6335
- const ka = argumentSpecSortKey(a);
6336
- const kb = argumentSpecSortKey(b);
6337
- if (ka[0] !== kb[0])
6338
- return ka[0] - kb[0];
6339
- if (typeof ka[1] === "number" && typeof kb[1] === "number") {
6340
- return ka[1] - kb[1];
6341
- }
6342
- return String(ka[1]).localeCompare(String(kb[1]));
6343
- });
6344
- const fields = [];
6345
- for (const spec of sorted) {
6346
- const metadata = new Map;
6347
- if (typeof spec.position === "string") {
6348
- metadata.set(VGI_ARG_KEY, VGI_ARG_NAMED);
6349
- }
6350
- if (spec.isTableInput) {
6351
- metadata.set(VGI_TYPE_KEY, VGI_TYPE_TABLE);
6352
- } else if (spec.isAnyType) {
6353
- metadata.set(VGI_TYPE_KEY, VGI_TYPE_ANY);
6354
- }
6355
- if (spec.isVarargs) {
6356
- metadata.set(VGI_VARARGS_KEY, VGI_VARARGS_TRUE);
6357
- }
6358
- if (spec.isConst) {
6359
- metadata.set(VGI_CONST_KEY, VGI_CONST_TRUE);
6360
- }
6361
- if (spec.doc) {
6362
- metadata.set(VGI_DOC_KEY, spec.doc);
6363
- }
6364
- const field3 = field2(spec.name, spec.arrowType, true, metadata.size > 0 ? metadata : undefined);
6365
- fields.push(field3);
6366
- }
6367
- return schema2(fields);
6368
- }
6369
- function macroArgumentsSchema(parameters, parameterDefaultValues, parameterDocs) {
6370
- const docs = parameterDocs ?? {};
6371
- const defaultTypes = new Map;
6372
- if (parameterDefaultValues && parameterDefaultValues.length > 0) {
6373
- const batch = deserializeBatch(parameterDefaultValues);
6374
- for (const f of batch.schema.fields) {
6375
- defaultTypes.set(f.name, f.type);
6376
- }
6377
- }
6378
- const fields = [];
6379
- for (const name of parameters) {
6380
- const metadata = new Map;
6381
- const doc = docs[name];
6382
- if (doc) {
6383
- metadata.set(VGI_DOC_KEY, doc);
6384
- }
6385
- const fieldType = defaultTypes.get(name) ?? nullType2();
6386
- fields.push(field2(name, fieldType, true, metadata.size > 0 ? metadata : undefined));
6387
- }
6388
- return schema2(fields);
6389
- }
6390
- function macroParameterDocsFromSchema(schema3) {
6391
- const docs = {};
6392
- for (const field3 of schema3.fields) {
6393
- const doc = field3.metadata.get(VGI_DOC_KEY);
6394
- if (doc) {
6395
- docs[field3.name] = doc;
6396
- }
6397
- }
6398
- return docs;
6399
- }
6400
- function schemaToArgumentSpecs(schema3) {
6401
- const specs = [];
6402
- let positionIndex = 0;
6403
- for (const field3 of schema3.fields) {
6404
- const metadata = field3.metadata;
6405
- const isNamed = metadata.get(VGI_ARG_KEY) === VGI_ARG_NAMED;
6406
- const position = isNamed ? field3.name : positionIndex++;
6407
- const vgiType = metadata.get(VGI_TYPE_KEY);
6408
- const isTableInput = vgiType === VGI_TYPE_TABLE;
6409
- const isAnyType = vgiType === VGI_TYPE_ANY;
6410
- const isVarargs = metadata.get(VGI_VARARGS_KEY) === VGI_VARARGS_TRUE;
6411
- const isConst = metadata.get(VGI_CONST_KEY) === VGI_CONST_TRUE;
6412
- const doc = metadata.get(VGI_DOC_KEY) ?? "";
6413
- specs.push({
6414
- name: field3.name,
6415
- position,
6416
- arrowType: field3.type,
6417
- isTableInput,
6418
- isAnyType,
6419
- isVarargs,
6420
- isConst,
6421
- doc
6422
- });
6423
- }
6424
- return specs;
6425
- }
6426
-
6427
6504
  // src/metadata/types.ts
6428
6505
  var CatalogFunctionType;
6429
6506
  ((CatalogFunctionType2) => {
@@ -10791,6 +10868,7 @@ export {
10791
10868
  fromBrandedNumber,
10792
10869
  fromBrandedBigInt,
10793
10870
  fromBranded,
10871
+ formatRange,
10794
10872
  formatPushedFilters,
10795
10873
  float642 as float64,
10796
10874
  float323 as float32,
@@ -10839,6 +10917,7 @@ export {
10839
10917
  dateMillisecond2 as dateMillisecond,
10840
10918
  dateDay2 as dateDay,
10841
10919
  date2 as date,
10920
+ constraintSpecFields,
10842
10921
  columnFromArray,
10843
10922
  codecFor,
10844
10923
  bytes,
@@ -10917,4 +10996,4 @@ export {
10917
10996
  ArgumentValidationError
10918
10997
  };
10919
10998
 
10920
- //# debugId=2E19C6BFB109AD5C64756E2164756E21
10999
+ //# debugId=B8E8A46EBC37A19064756E2164756E21