@cipherstash/protect-ffi 0.12.0 → 0.13.0-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/README.md CHANGED
@@ -76,7 +76,11 @@ Initiate a dry run of a patch release of this library via GitHub Actions. This p
76
76
 
77
77
  #### `npm test`
78
78
 
79
- Runs the unit tests by calling `cargo test`. You can learn more about [adding tests to your Rust code](https://doc.rust-lang.org/book/ch11-01-writing-tests.html) from the [Rust book](https://doc.rust-lang.org/book/).
79
+ Formats and lints Rust and TypeScript code.
80
+ Also runs Rust tests.
81
+
82
+ Note: `npm test` at project root does not run integration tests.
83
+ For integration tests, see [below](#integration-tests).
80
84
 
81
85
  ## Project Layout
82
86
 
@@ -86,6 +90,7 @@ The directory structure of this project is:
86
90
  protect-ffi/
87
91
  ├── Cargo.toml
88
92
  ├── README.md
93
+ ├── integration-tests/
89
94
  ├── lib/
90
95
  ├── src/
91
96
  | ├── index.mts
@@ -99,19 +104,53 @@ protect-ffi/
99
104
  └── target/
100
105
  ```
101
106
 
102
- | Entry | Purpose |
103
- |----------------|------------------------------------------------------------------------------------------------------------------------------------------|
104
- | `Cargo.toml` | The Cargo [manifest file](https://doc.rust-lang.org/cargo/reference/manifest.html), which informs the `cargo` command. |
105
- | `README.md` | This file. |
106
- | `lib/` | The directory containing the generated output from [tsc](https://typescriptlang.org). |
107
- | `src/` | The directory containing the TypeScript source files. |
108
- | `index.mts` | Entry point for when this library is loaded via [ESM `import`](https://nodejs.org/api/esm.html#modules-ecmascript-modules) syntax. |
109
- | `index.cts` | Entry point for when this library is loaded via [CJS `require`](https://nodejs.org/api/modules.html#requireid). |
110
- | `crates/` | The directory tree containing the Rust source code for the project. |
111
- | `lib.rs` | Entry point for the Rust source code. |
112
- | `platforms/` | The directory containing distributions of the binary addon backend for each platform supported by this library. |
113
- | `package.json` | The npm [manifest file](https://docs.npmjs.com/cli/v7/configuring-npm/package-json), which informs the `npm` command. |
114
- | `target/` | Binary artifacts generated by the Rust build. |
107
+ | Entry | Purpose |
108
+ | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
109
+ | `Cargo.toml` | The Cargo [manifest file](https://doc.rust-lang.org/cargo/reference/manifest.html), which informs the `cargo` command. |
110
+ | `README.md` | This file. |
111
+ | `integration-tests/` | The directory containing integration tests. |
112
+ | `lib/` | The directory containing the generated output from [tsc](https://typescriptlang.org). |
113
+ | `src/` | The directory containing the TypeScript source files. |
114
+ | `index.mts` | Entry point for when this library is loaded via [ESM `import`](https://nodejs.org/api/esm.html#modules-ecmascript-modules) syntax. |
115
+ | `index.cts` | Entry point for when this library is loaded via [CJS `require`](https://nodejs.org/api/modules.html#requireid). |
116
+ | `crates/` | The directory tree containing the Rust source code for the project. |
117
+ | `lib.rs` | Entry point for the Rust source code. |
118
+ | `platforms/` | The directory containing distributions of the binary addon backend for each platform supported by this library. |
119
+ | `package.json` | The npm [manifest file](https://docs.npmjs.com/cli/v7/configuring-npm/package-json), which informs the `npm` command. |
120
+ | `target/` | Binary artifacts generated by the Rust build. |
121
+
122
+ ## Integration tests
123
+
124
+ Integration tests live in the `./integration-tests` directory.
125
+ These tests use the local build of Rust and JavaScript artifacts to test `@cipherstash/protect-ffi` as API consumers would.
126
+
127
+ These tests rely on:
128
+
129
+ - CipherStash to be configured (via `.toml` config or environment variables), and
130
+ - Environment variables for Postgres to be set
131
+
132
+ Example environment variables:
133
+ ```
134
+ CS_CLIENT_ID=
135
+ CS_CLIENT_KEY=
136
+ CS_CLIENT_ACCESS_KEY=
137
+ CS_WORKSPACE_ID=
138
+ PGPORT=5432
139
+ PGDATABASE=cipherstash
140
+ PGUSER=cipherstash
141
+ PGPASSWORD=password
142
+ PGHOST=localhost
143
+ ```
144
+
145
+ To run integration tests:
146
+ ```
147
+ npm run debug
148
+ cd integration-tests
149
+ docker compose up --detach --wait
150
+ npm run eql:download
151
+ npm run eql:install
152
+ npm run test
153
+ ```
115
154
 
116
155
  ## Releasing
117
156
 
@@ -119,20 +158,22 @@ Releases are handled by GitHub Actions using a `workflow_dispatch` event trigger
119
158
  The [release workflow](./.github/workflows/release.yml) was generated by [Neon](https://neon-rs.dev/).
120
159
 
121
160
  The release workflow is responsible for:
161
+
122
162
  - Building and publishing the main `@cipherstash/protect-ffi` package as well as the native packages for each platform (e.g. `@cipherstash/protect-ffi-darwin-arm64`).
123
163
  - Creating the GitHub release.
124
164
  - Creating a Git tag for the version.
125
165
 
126
166
  To perform a release:
167
+
127
168
  1. Navigate to the ["Release" workflow page](https://github.com/cipherstash/protect-ffi/actions/workflows/release.yml) in GitHub.
128
169
  1. Click on "Run workflow".
129
170
  1. Select the branch to release from.
130
- Use the default of "main" unless you want to do a pre-release version or dry run from a branch.
171
+ Use the default of `main` unless you want to do a pre-release version or dry run from a branch.
131
172
  1. Select whether or not to do a dry run.
132
- Dry runs are useful for verifying that the build will succeed for all platforms before doing a full run with a publish.
173
+ Dry runs are useful for verifying that the build will succeed for all platforms before doing a full run with a publish.
133
174
  1. Choose a version to publish.
134
- The options are similar to [`npm version`](https://docs.npmjs.com/cli/v11/commands/npm-version).
135
- Select "custom" in the dropdown and fill in the "Custom version" text box if you want to use a semver string instead of the shorthand (patch, minor, major, etc.).
175
+ The options are similar to [`npm version`](https://docs.npmjs.com/cli/v11/commands/npm-version).
176
+ Select "custom" in the dropdown and fill in the "Custom version" text box if you want to use a semver string instead of the shorthand (patch, minor, major, etc.).
136
177
  1. Click "Run workflow".
137
178
 
138
179
  Note that we currently don't have any automation around release notes or a changelog.
package/lib/index.cjs CHANGED
@@ -1,76 +1,20 @@
1
1
  "use strict";
2
2
  // This module is the CJS entry point for the library.
3
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
- if (k2 === undefined) k2 = k;
5
- var desc = Object.getOwnPropertyDescriptor(m, k);
6
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
- desc = { enumerable: true, get: function() { return m[k]; } };
8
- }
9
- Object.defineProperty(o, k2, desc);
10
- }) : (function(o, m, k, k2) {
11
- if (k2 === undefined) k2 = k;
12
- o[k2] = m[k];
13
- }));
14
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
- Object.defineProperty(o, "default", { enumerable: true, value: v });
16
- }) : function(o, v) {
17
- o["default"] = v;
18
- });
19
- var __importStar = (this && this.__importStar) || (function () {
20
- var ownKeys = function(o) {
21
- ownKeys = Object.getOwnPropertyNames || function (o) {
22
- var ar = [];
23
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
- return ar;
25
- };
26
- return ownKeys(o);
27
- };
28
- return function (mod) {
29
- if (mod && mod.__esModule) return mod;
30
- var result = {};
31
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
- __setModuleDefault(result, mod);
33
- return result;
34
- };
35
- })();
36
3
  Object.defineProperty(exports, "__esModule", { value: true });
37
- exports.newClient = newClient;
38
- exports.encrypt = encrypt;
4
+ exports.decryptBulk = exports.newClient = exports.encryptBulk = exports.encrypt = void 0;
39
5
  exports.decrypt = decrypt;
40
- exports.encryptBulk = encryptBulk;
41
- exports.decryptBulk = decryptBulk;
42
- // The Rust addon.
43
- const addon = __importStar(require("./load.cjs"));
44
- function newClient(encryptSchema) {
45
- return addon.newClient(encryptSchema);
46
- }
47
- function encrypt(client, plaintext, columnName, tableName, lockContext, ctsToken) {
48
- if (ctsToken) {
49
- return addon.encrypt(client, plaintext, columnName, tableName, lockContext, ctsToken);
50
- }
51
- if (lockContext) {
52
- return addon.encrypt(client, plaintext, columnName, tableName, lockContext);
53
- }
54
- return addon.encrypt(client, plaintext, columnName, tableName);
55
- }
6
+ var load_cjs_1 = require("./load.cjs");
7
+ Object.defineProperty(exports, "encrypt", { enumerable: true, get: function () { return load_cjs_1.encrypt; } });
8
+ Object.defineProperty(exports, "encryptBulk", { enumerable: true, get: function () { return load_cjs_1.encryptBulk; } });
9
+ Object.defineProperty(exports, "newClient", { enumerable: true, get: function () { return load_cjs_1.newClient; } });
10
+ Object.defineProperty(exports, "decryptBulk", { enumerable: true, get: function () { return load_cjs_1.decryptBulk; } });
11
+ const load_cjs_2 = require("./load.cjs");
56
12
  function decrypt(client, ciphertext, lockContext, ctsToken) {
57
13
  if (ctsToken) {
58
- return addon.decrypt(client, ciphertext, lockContext, ctsToken);
14
+ return (0, load_cjs_2.decrypt)(client, ciphertext, lockContext, ctsToken);
59
15
  }
60
16
  if (lockContext) {
61
- return addon.decrypt(client, ciphertext, lockContext);
62
- }
63
- return addon.decrypt(client, ciphertext);
64
- }
65
- function encryptBulk(client, plaintextTargets, ctsToken) {
66
- if (ctsToken) {
67
- return addon.encryptBulk(client, plaintextTargets, ctsToken);
68
- }
69
- return addon.encryptBulk(client, plaintextTargets);
70
- }
71
- function decryptBulk(client, ciphertexts, ctsToken) {
72
- if (ctsToken) {
73
- return addon.decryptBulk(client, ciphertexts, ctsToken);
17
+ return (0, load_cjs_2.decrypt)(client, ciphertext, lockContext);
74
18
  }
75
- return addon.decryptBulk(client, ciphertexts);
19
+ return (0, load_cjs_2.decrypt)(client, ciphertext);
76
20
  }
package/lib/index.d.cts CHANGED
@@ -1,22 +1,20 @@
1
- import * as addon from './load.cjs';
1
+ export { encrypt, encryptBulk, newClient, decryptBulk } from './load.cjs';
2
+ declare const sym: unique symbol;
3
+ export type Client = {
4
+ readonly [sym]: unknown;
5
+ };
2
6
  declare module './load.cjs' {
3
- interface Client {
4
- }
5
- function newClient(encryptSchema?: string): Promise<Client>;
6
- function encrypt(client: Client, plaintext: string, columnName: string, tableName?: string, context?: Context, ctsToken?: CtsToken): Promise<string>;
7
+ function newClient(encryptSchema: string): Promise<Client>;
8
+ function encrypt(client: Client, plaintext: EncryptPayload, ctsToken?: CtsToken): Promise<Encrypted>;
7
9
  function decrypt(client: Client, ciphertext: string, context?: Context, ctsToken?: CtsToken): Promise<string>;
8
- function encryptBulk(client: Client, plaintextTargets: BulkEncryptPayload[], ctsToken?: CtsToken): Promise<string[]>;
10
+ function encryptBulk(client: Client, plaintextTargets: EncryptPayload[], ctsToken?: CtsToken): Promise<Encrypted[]>;
9
11
  function decryptBulk(client: Client, ciphertexts: BulkDecryptPayload[], ctsToken?: CtsToken): Promise<string[]>;
10
12
  }
11
- export declare function newClient(encryptSchema?: string): Promise<addon.Client>;
12
- export declare function encrypt(client: addon.Client, plaintext: string, columnName: string, tableName?: string, lockContext?: Context, ctsToken?: CtsToken): Promise<string>;
13
- export declare function decrypt(client: addon.Client, ciphertext: string, lockContext?: Context, ctsToken?: CtsToken): Promise<string>;
14
- export declare function encryptBulk(client: addon.Client, plaintextTargets: BulkEncryptPayload[], ctsToken?: CtsToken): Promise<string[]>;
15
- export declare function decryptBulk(client: addon.Client, ciphertexts: BulkDecryptPayload[], ctsToken?: CtsToken): Promise<string[]>;
16
- export type BulkEncryptPayload = {
13
+ export declare function decrypt(client: Client, ciphertext: string, lockContext?: Context, ctsToken?: CtsToken): Promise<string>;
14
+ export type EncryptPayload = {
17
15
  plaintext: string;
18
16
  column: string;
19
- table?: string;
17
+ table: string;
20
18
  lockContext?: Context;
21
19
  };
22
20
  export type BulkDecryptPayload = {
@@ -30,10 +28,15 @@ export type CtsToken = {
30
28
  export type Context = {
31
29
  identityClaim: string[];
32
30
  };
33
- export type EncryptedEqlPayload = {
31
+ export type Encrypted = {
32
+ k: string;
34
33
  c: string;
34
+ o: string[] | null;
35
+ m: number[] | null;
36
+ u: string | null;
37
+ i: {
38
+ c: string;
39
+ t: string;
40
+ };
41
+ v: number;
35
42
  };
36
- export type BulkEncryptedEqlPayload = {
37
- c: string;
38
- id: string;
39
- }[];
package/package.json CHANGED
@@ -1,10 +1,18 @@
1
1
  {
2
2
  "name": "@cipherstash/protect-ffi",
3
- "version": "0.12.0",
3
+ "version": "0.13.0-1",
4
4
  "description": "",
5
5
  "main": "./lib/index.cjs",
6
6
  "scripts": {
7
- "test": "tsc &&cargo test",
7
+ "test": "npm run test:typecheck && npm run test:lint && npm run test:format && npm run test:rust",
8
+ "test:typecheck": "tsc",
9
+ "test:rust": "cargo test",
10
+ "test:lint": "npm run test:lint:rust && npm run test:lint:ts",
11
+ "test:lint:ts": "biome lint",
12
+ "test:lint:rust": "cargo clippy --all --no-deps --all-targets --all-features -- -D warnings",
13
+ "test:format": "npm run test:format:rust && npm run test:format:ts",
14
+ "test:format:ts": "biome format",
15
+ "test:format:rust": "cargo fmt --check",
8
16
  "cargo-build": "tsc &&cargo build --message-format=json-render-diagnostics > cargo.log",
9
17
  "cross-build": "tsc &&cross build --message-format=json-render-diagnostics > cross.log",
10
18
  "postcargo-build": "neon dist < cargo.log",
@@ -43,6 +51,7 @@
43
51
  "prefix": "protect-ffi-"
44
52
  },
45
53
  "devDependencies": {
54
+ "@biomejs/biome": "1.9.4",
46
55
  "@neon-rs/cli": "^0.1.82",
47
56
  "@tsconfig/node20": "^20.1.4",
48
57
  "@types/node": "^20.11.16",
@@ -52,10 +61,10 @@
52
61
  "@neon-rs/load": "^0.1.82"
53
62
  },
54
63
  "optionalDependencies": {
55
- "@cipherstash/protect-ffi-win32-x64-msvc": "0.12.0",
56
- "@cipherstash/protect-ffi-darwin-x64": "0.12.0",
57
- "@cipherstash/protect-ffi-darwin-arm64": "0.12.0",
58
- "@cipherstash/protect-ffi-linux-x64-gnu": "0.12.0",
59
- "@cipherstash/protect-ffi-linux-arm64-gnu": "0.12.0"
64
+ "@cipherstash/protect-ffi-win32-x64-msvc": "0.13.0-1",
65
+ "@cipherstash/protect-ffi-darwin-x64": "0.13.0-1",
66
+ "@cipherstash/protect-ffi-darwin-arm64": "0.13.0-1",
67
+ "@cipherstash/protect-ffi-linux-x64-gnu": "0.13.0-1",
68
+ "@cipherstash/protect-ffi-linux-arm64-gnu": "0.13.0-1"
60
69
  }
61
70
  }