@query-farm/vgi 0.36.3 → 0.37.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@query-farm/vgi",
3
- "version": "0.36.3",
3
+ "version": "0.37.0",
4
4
  "description": "TypeScript framework for extending DuckDB with user-defined functions via the Vector Gateway Interface (VGI) over Arrow IPC.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "author": "Query Farm LLC (https://query.farm)",
@@ -22,6 +22,9 @@
22
22
  // that predates the column reads the batch by
23
23
  // name and simply doesn't see it; absent and
24
24
  // explicit-null both mean "not required".
25
+ // secret: Bool nullable -- the option carries a credential. Appended AFTER
26
+ // `required` under the same rule: readers look it
27
+ // up by name, and absent or null reads as false.
25
28
  //
26
29
  // The extension reads the outer `attach_option_specs: list<binary>` column
27
30
  // from CatalogInfo and validates user-supplied ATTACH options against the
@@ -75,6 +78,31 @@ export interface AttachOptionSpec {
75
78
  * is by definition satisfiable without the caller.
76
79
  */
77
80
  required?: boolean;
81
+ /**
82
+ * The option carries a credential: an API key, a token, a password, or
83
+ * anything else that must not be shown, stored or logged in plain text.
84
+ *
85
+ * Credential options **MUST** be declared `secret: true`. Clients and the
86
+ * DuckDB extension use the flag to mask the value, keep it out of result
87
+ * cache keys (the extension stores a salted hash instead), `duckdb_databases()`,
88
+ * logs, telemetry, shared links and exported configuration. They can also
89
+ * supply it from a `vgi_attach` DuckDB secret, so the ATTACH statement never
90
+ * carries it:
91
+ *
92
+ * ```sql
93
+ * CREATE SECRET (TYPE vgi_attach, SCOPE 'https://worker.example.com', api_key 'sk-...');
94
+ * ATTACH 'sales' (TYPE vgi, LOCATION 'https://worker.example.com');
95
+ * ```
96
+ *
97
+ * Combines with `required` (a credential the catalog cannot attach without,
98
+ * which a client can then ask for before attaching). It is allowed together
99
+ * with `default`, but a secret option normally has none: a default would be
100
+ * a credential shipped in the catalog's own discovery metadata.
101
+ *
102
+ * Defaults to `false`. On the wire it is a nullable `secret` Bool column
103
+ * appended after `required`; a peer that predates it reads it as `false`.
104
+ */
105
+ secret?: boolean;
78
106
  }
79
107
 
80
108
  const SPEC_SCHEMA = makeSchema([
@@ -83,6 +111,7 @@ const SPEC_SCHEMA = makeSchema([
83
111
  field("type", binary(), false),
84
112
  field("default_value", binary(), true),
85
113
  field("required", bool(), true),
114
+ field("secret", bool(), true),
86
115
  ]);
87
116
 
88
117
  /**
@@ -126,6 +155,8 @@ export function serializeAttachOptionSpec(spec: AttachOptionSpec): Uint8Array {
126
155
  // Written explicitly rather than left null so a reader sees `false`, not
127
156
  // NULL, for an option that simply isn't required.
128
157
  required: [spec.required ?? false],
158
+ // Same reasoning: an ordinary option reads `false`, not NULL.
159
+ secret: [spec.secret ?? false],
129
160
  },
130
161
  SPEC_SCHEMA,
131
162
  );
@@ -145,8 +176,8 @@ export function serializeAttachOptionSpecs(
145
176
  * Deserialize one AttachOptionSpec from the wire format above.
146
177
  *
147
178
  * Reads by column name, so a spec written by a peer that predates the
148
- * `required` column deserializes with `required: false` rather than failing —
149
- * the same tolerance the Python and C++ readers have.
179
+ * `required` or `secret` column deserializes with that flag `false` rather
180
+ * than failing — the same tolerance the Python and C++ readers have.
150
181
  */
151
182
  export function deserializeAttachOptionSpec(
152
183
  bytes: Uint8Array,
@@ -181,6 +212,7 @@ export function deserializeAttachOptionSpec(
181
212
  type,
182
213
  ...(value === undefined || value === null ? {} : { default: value }),
183
214
  required: row.required === true,
215
+ secret: row.secret === true,
184
216
  };
185
217
  }
186
218