@cipherstash/protect-ffi 0.20.1 → 0.21.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.
@@ -0,0 +1,11 @@
1
+ export type CredentialOpts = {
2
+ workspaceCrn?: string;
3
+ accessKey?: string;
4
+ clientId?: string;
5
+ clientKey?: string;
6
+ };
7
+ /** Reads an environment variable. Replaceable in tests. */
8
+ export type EnvReader = (key: string) => string | undefined;
9
+ /** Fill in credential fields from env vars when not explicitly set. */
10
+ export declare function withEnvCredentials<T extends CredentialOpts>(opts: T, env?: EnvReader): T;
11
+ export declare function withEnvCredentials(opts: CredentialOpts | undefined, env?: EnvReader): CredentialOpts;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.withEnvCredentials = withEnvCredentials;
4
+ const processEnv = (key) => process.env[key];
5
+ function withEnvCredentials(opts, env = processEnv) {
6
+ // CS_CLIENT_ID and CS_CLIENT_KEY are a keypair — only use them when both are set
7
+ const envClientId = env('CS_CLIENT_ID');
8
+ const envClientKey = env('CS_CLIENT_KEY');
9
+ const hasEnvClientKey = envClientId !== undefined && envClientKey !== undefined;
10
+ const creds = {
11
+ clientId: opts?.clientId ?? (hasEnvClientKey ? envClientId : undefined),
12
+ clientKey: opts?.clientKey ?? (hasEnvClientKey ? envClientKey : undefined),
13
+ workspaceCrn: opts?.workspaceCrn ?? env('CS_WORKSPACE_CRN'),
14
+ accessKey: opts?.accessKey ?? env('CS_ACCESS_KEY'),
15
+ };
16
+ return opts ? { ...opts, ...creds } : creds;
17
+ }
package/lib/index.cjs CHANGED
@@ -34,7 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  };
35
35
  })();
36
36
  Object.defineProperty(exports, "__esModule", { value: true });
37
- exports.ProtectError = void 0;
37
+ exports.ProtectError = exports.withEnvCredentials = void 0;
38
38
  exports.newClient = newClient;
39
39
  exports.encrypt = encrypt;
40
40
  exports.decrypt = decrypt;
@@ -44,7 +44,11 @@ exports.decryptBulk = decryptBulk;
44
44
  exports.decryptBulkFallible = decryptBulkFallible;
45
45
  exports.encryptQuery = encryptQuery;
46
46
  exports.encryptQueryBulk = encryptQueryBulk;
47
+ exports.ensureKeyset = ensureKeyset;
48
+ const credentials_js_1 = require("./credentials.js");
47
49
  const native = __importStar(require("./load.cjs"));
50
+ var credentials_js_2 = require("./credentials.js");
51
+ Object.defineProperty(exports, "withEnvCredentials", { enumerable: true, get: function () { return credentials_js_2.withEnvCredentials; } });
48
52
  class ProtectError extends Error {
49
53
  code;
50
54
  details;
@@ -112,7 +116,10 @@ function wrapSync(fn) {
112
116
  }
113
117
  }
114
118
  function newClient(opts) {
115
- return wrapAsync(() => native.newClient(opts));
119
+ return wrapAsync(() => native.newClient({
120
+ ...opts,
121
+ clientOpts: (0, credentials_js_1.withEnvCredentials)(opts.clientOpts),
122
+ }));
116
123
  }
117
124
  function encrypt(client, opts) {
118
125
  return wrapAsync(() => native.encrypt(client, opts));
@@ -144,3 +151,11 @@ function encryptQuery(client, opts) {
144
151
  function encryptQueryBulk(client, opts) {
145
152
  return wrapAsync(() => native.encryptQueryBulk(client, opts));
146
153
  }
154
+ /**
155
+ * Test-only helper: ensures a keyset with the given name exists, creating it if necessary,
156
+ * and grants the current client access. Not safe for concurrent use — intended for
157
+ * sequential test setup only.
158
+ */
159
+ function ensureKeyset(opts) {
160
+ return wrapAsync(() => native.ensureKeyset((0, credentials_js_1.withEnvCredentials)(opts)));
161
+ }
package/lib/index.d.cts CHANGED
@@ -1,3 +1,5 @@
1
+ import { type CredentialOpts } from './credentials.js';
2
+ export { withEnvCredentials, type EnvReader, type CredentialOpts, } from './credentials.js';
1
3
  declare const sym: unique symbol;
2
4
  export type Client = {
3
5
  readonly [sym]: unknown;
@@ -12,6 +14,7 @@ declare module './load.cjs' {
12
14
  function decryptBulkFallible(client: Client, opts: DecryptBulkOptions): Promise<DecryptResult[]>;
13
15
  function encryptQuery(client: Client, opts: EncryptQueryOptions): Promise<Encrypted>;
14
16
  function encryptQueryBulk(client: Client, opts: EncryptQueryBulkOptions): Promise<Encrypted[]>;
17
+ function ensureKeyset(opts: EnsureKeysetOpts): Promise<EnsureKeysetResult>;
15
18
  }
16
19
  export type ProtectErrorCode = 'INVARIANT_VIOLATION' | 'UNKNOWN_QUERY_OP' | 'UNKNOWN_COLUMN' | 'MISSING_INDEX' | 'INVALID_QUERY_INPUT' | 'INVALID_JSON_PATH' | 'STE_VEC_REQUIRES_JSON_CAST_AS' | 'UNKNOWN';
17
20
  export declare class ProtectError extends Error {
@@ -40,6 +43,12 @@ export declare function decryptBulk(client: Client, opts: DecryptBulkOptions): P
40
43
  export declare function decryptBulkFallible(client: Client, opts: DecryptBulkOptions): Promise<DecryptResult[]>;
41
44
  export declare function encryptQuery(client: Client, opts: EncryptQueryOptions): Promise<Encrypted>;
42
45
  export declare function encryptQueryBulk(client: Client, opts: EncryptQueryBulkOptions): Promise<Encrypted[]>;
46
+ /**
47
+ * Test-only helper: ensures a keyset with the given name exists, creating it if necessary,
48
+ * and grants the current client access. Not safe for concurrent use — intended for
49
+ * sequential test setup only.
50
+ */
51
+ export declare function ensureKeyset(opts: EnsureKeysetOpts): Promise<EnsureKeysetResult>;
43
52
  export type EncryptPayload = {
44
53
  plaintext: JsPlaintext;
45
54
  column: string;
@@ -129,7 +138,7 @@ export type Column = {
129
138
  cast_as?: CastAs;
130
139
  indexes?: Indexes;
131
140
  };
132
- export type CastAs = 'bigint' | 'boolean' | 'date' | 'number' | 'string' | 'json';
141
+ export type CastAs = 'bigint' | 'boolean' | 'date' | 'number' | 'string' | 'text' | 'json';
133
142
  type TablesOf<C extends EncryptConfig> = C['tables'];
134
143
  export type Identifier<C extends EncryptConfig> = {
135
144
  [T in keyof TablesOf<C>]: {
@@ -156,9 +165,15 @@ export type MatchIndexOpts = {
156
165
  m?: number;
157
166
  include_original?: boolean;
158
167
  };
168
+ export type ArrayIndexMode = 'all' | 'none' | {
169
+ item?: boolean;
170
+ wildcard?: boolean;
171
+ position?: boolean;
172
+ };
159
173
  export type SteVecIndexOpts = {
160
174
  prefix: string;
161
175
  term_filters?: TokenFilter[];
176
+ array_index_mode?: ArrayIndexMode;
162
177
  };
163
178
  export type Tokenizer = {
164
179
  kind: 'standard';
@@ -173,11 +188,7 @@ export type NewClientOptions = {
173
188
  encryptConfig: EncryptConfig;
174
189
  clientOpts?: ClientOpts;
175
190
  };
176
- export type ClientOpts = {
177
- workspaceCrn?: string;
178
- accessKey?: string;
179
- clientId?: string;
180
- clientKey?: string;
191
+ export type ClientOpts = CredentialOpts & {
181
192
  keyset?: KeysetIdentifier;
182
193
  };
183
194
  export type KeysetIdentifier = {
@@ -185,6 +196,13 @@ export type KeysetIdentifier = {
185
196
  } | {
186
197
  Name: string;
187
198
  };
199
+ export type EnsureKeysetOpts = CredentialOpts & {
200
+ name: string;
201
+ };
202
+ export type EnsureKeysetResult = {
203
+ id: string;
204
+ name: string;
205
+ };
188
206
  export type JsPlaintext = string | number | boolean | Record<string, unknown> | JsPlaintext[];
189
207
  export type EncryptOptions = {
190
208
  plaintext: JsPlaintext;
@@ -235,4 +253,3 @@ export type EncryptQueryBulkOptions = {
235
253
  serviceToken?: CtsToken;
236
254
  unverifiedContext?: Record<string, unknown>;
237
255
  };
238
- export {};
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@cipherstash/protect-ffi",
3
- "version": "0.20.1",
3
+ "version": "0.21.0",
4
4
  "description": "",
5
5
  "main": "./lib/index.cjs",
6
6
  "scripts": {
7
- "test": "npm run test:typecheck && npm run test:lint && npm run test:format && npm run test:rust",
7
+ "test": "npm run test:typecheck && npm run test:unit && npm run test:lint && npm run test:format && npm run test:rust",
8
8
  "test:typecheck": "tsc",
9
+ "test:unit": "vitest run",
9
10
  "test:rust": "cargo test",
10
11
  "test:lint": "npm run test:lint:ts",
11
12
  "test:lint:ts": "biome lint",
@@ -61,17 +62,18 @@
61
62
  "@neon-rs/cli": "^0.1.82",
62
63
  "@tsconfig/node20": "^20.1.4",
63
64
  "@types/node": "^20.11.16",
64
- "typescript": "^5.3.3"
65
+ "typescript": "^5.3.3",
66
+ "vitest": "^4.1.0"
65
67
  },
66
68
  "dependencies": {
67
69
  "@neon-rs/load": "^0.1.82"
68
70
  },
69
71
  "optionalDependencies": {
70
- "@cipherstash/protect-ffi-darwin-x64": "0.20.1",
71
- "@cipherstash/protect-ffi-darwin-arm64": "0.20.1",
72
- "@cipherstash/protect-ffi-win32-x64-msvc": "0.20.1",
73
- "@cipherstash/protect-ffi-linux-x64-gnu": "0.20.1",
74
- "@cipherstash/protect-ffi-linux-arm64-gnu": "0.20.1",
75
- "@cipherstash/protect-ffi-linux-x64-musl": "0.20.1"
72
+ "@cipherstash/protect-ffi-darwin-x64": "0.21.0",
73
+ "@cipherstash/protect-ffi-darwin-arm64": "0.21.0",
74
+ "@cipherstash/protect-ffi-win32-x64-msvc": "0.21.0",
75
+ "@cipherstash/protect-ffi-linux-x64-gnu": "0.21.0",
76
+ "@cipherstash/protect-ffi-linux-arm64-gnu": "0.21.0",
77
+ "@cipherstash/protect-ffi-linux-x64-musl": "0.21.0"
76
78
  }
77
79
  }