diff --git a/README.md b/README.md index ccb1de08..e14fa64f 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ Securely handle sensitive data at rest, in-transit, and in-use with the Skyflow - [ES modules](#es-modules) - [All imports](#all-imports) - [Quickstart](#quickstart) + - [Before you begin](#before-you-begin) - [Authenticate](#authenticate) - [API Key](#api-key) - [Bearer Token (static)](#bearer-token-static) @@ -51,6 +52,7 @@ Securely handle sensitive data at rest, in-transit, and in-use with the Skyflow - [De-identify File: `.deidentifyFile(fileReq, options)`](#de-identify-file-deidentifyfilefilereq-options) - [Get Run: `.getDetectRun(request)`](#get-run-getdetectrunrequest) - [Connections](#connections) + - [Configure a connection](#configure-a-connection) - [Invoke a connection](#invoke-a-connection) - [Construct an invoke connection request](#construct-an-invoke-connection-request) - [Authentication \& authorization](#authentication--authorization) @@ -58,15 +60,24 @@ Securely handle sensitive data at rest, in-transit, and in-use with the Skyflow - [Generate bearer tokens for authentication \& authorization](#generate-bearer-tokens-for-authentication--authorization) - [Generate a bearer token](#generate-a-bearer-token) - [`generateBearerToken(filepath)`](#generatebearertokenfilepath) - - [`generateBearerTokenFromCreds(credentials)`](#generatebearertokenfromcredscredentials) + - [`generateBearerTokenFromCreds(credentialsString)`](#generatebearertokenfromcredscredentialsstring) - [Generate bearer tokens scoped to certain roles](#generate-bearer-tokens-scoped-to-certain-roles) - [Generate bearer tokens with `ctx` for context-aware authorization](#generate-bearer-tokens-with-ctx-for-context-aware-authorization) - - [Generate signed data tokens: `generateSignedDataTokens(filepath, options)`](#generate-signed-data-tokens-generatesigneddatatokensfilepath-options) + - [Generate signed data tokens](#generate-signed-data-tokens) + - [Runtime client management](#runtime-client-management) + - [Vault management](#vault-management) + - [Connection management](#connection-management) + - [Credentials and log level](#credentials-and-log-level) + - [Skyflow class public methods reference](#skyflow-class-public-methods-reference) + - [Using the client in production](#using-the-client-in-production) - [Logging](#logging) - [Example `skyflowConfig.logLevel: LogLevel.INFO`](#example-skyflowconfigloglevel-loglevelinfo) - [Error handling](#error-handling) - [Catching `SkyflowError` instances](#catching-skyflowerror-instances) + - [Per-record errors (`SkyflowRecordError`)](#per-record-errors-skyflowrecorderror) - [Bearer token expiration edge cases](#bearer-token-expiration-edge-cases) + - [Troubleshooting](#troubleshooting) + - [TypeScript types reference](#typescript-types-reference) - [Security](#security) - [Reporting a Vulnerability](#reporting-a-vulnerability) @@ -74,6 +85,9 @@ Securely handle sensitive data at rest, in-transit, and in-use with the Skyflow The Skyflow SDK enables you to connect to your Skyflow Vault(s) to securely handle sensitive data at rest, in-transit, and in-use. +> [!TIP] +> Looking for the full list of request parameters, options setters, response fields, enums, and Detect helper classes? See the **[API Reference](docs/api_reference.md)**. + > [!IMPORTANT] > This readme documents SDK version 2. > For version 1 see the [v1.14.2 README](https://github.com/skyflowapi/skyflow-node/tree/1.14.2). @@ -115,6 +129,19 @@ import { Get started quickly with the essential steps: authenticate, initialize the client, and perform a basic vault operation. This section shows you a minimal working example. +### Before you begin + +You need a Skyflow account and a few values from Skyflow Studio. If you don't have an account, [request a demo](https://www.skyflow.com/get-demo). + +| Value | Where to find it | +|---|---| +| `vaultId` | Your vault's details page in Skyflow Studio. | +| `clusterId` | The first segment of your vault URL: `https://{clusterId}.vault.skyflowapis.com`. | +| `env` | The environment your vault runs in — `Env.PROD`, `Env.SANDBOX`, `Env.DEV`, or `Env.STAGE` (defaults to `PROD`). | +| Credentials | Create a **service account** in Studio. Choose **API key** during creation for the simplest setup, or download the `credentials.json` file for token-based auth. See [Authentication & authorization](#authentication--authorization). | + +The quickstart below assumes a table named `table1` with `card_number` and `cardholder_name` columns. Adjust the table and column names to match your vault schema. + ### Authenticate You can use an API key or a personal bearer token to directly authenticate and authorize requests with the SDK. Use API keys for long-term service authentication. Use bearer tokens for optimal security. @@ -155,9 +182,10 @@ const skyflowCredentials = { // Configure vault const vaultConfig: VaultConfig = { - vaultId: '', - clusterId: '', - env: Env.PROD + vaultId: '', // required: vault identifier + clusterId: '', // required: from vault URL + env: Env.PROD, // optional: PROD (default), SANDBOX, DEV, STAGE + // credentials: vaultCredentials // optional: per-vault credentials; overrides skyflowCredentials }; // Initialize Skyflow client @@ -199,6 +227,8 @@ const insertResponse = await skyflowClient console.log("Insert response:", insertResponse); ``` +Returns an `InsertResponse` — see [API Reference](docs/api_reference.md#insertresponse) for the full field list. + ## Upgrade from v1 to v2 Upgrade from `skyflow-node` v1 using the dedicated guide in [docs/migrate_to_v2.md](docs/migrate_to_v2.md). @@ -232,6 +262,8 @@ const response: InsertResponse = await skyflowClient console.log('Insert response:', response); ``` +Returns an `InsertResponse` (`insertedFields`, `errors`) — see [API Reference](docs/api_reference.md#insertresponse). With `setContinueOnError(true)`, `insertedFields` contains successful records and `errors` contains per-record failures. + > **Note:** The response key is `skyflowId`. The legacy `skyflow_id` key is deprecated and will be removed in an upcoming release. #### Insert example with `continueOnError` option @@ -246,13 +278,38 @@ Set the `continueOnError` flag to `true` to allow insert operations to proceed d Turn an insert into an 'update-or-insert' operation using the upsert option. The vault checks for an existing record with the same value in the specified column. If a match exists, the record updates; otherwise, a new record inserts. ```typescript -// ... -// Specify the column to use as the index for the upsert. +// Specify the column to use as the index for the upsert. // Note: The column must have the `unique` constraint configured in the vault. insertOptions.setUpsertColumn("cardholder_name"); -// ... ``` +#### InsertOptions reference + +`InsertOptions` accepts the following setters: + +| Setter | Type | Description | +|---|---|---| +| `setReturnTokens(bool)` | `boolean` | Return tokens for inserted fields. Default `false`. | +| `setUpsertColumn(column)` | `string` | Column to use as the upsert key. Must have the `unique` constraint. | +| `setContinueOnError(bool)` | `boolean` | Allow the batch to proceed despite per-record errors. Default `false`. | +| `setTokens(tokens)` | `Array>` | Provide pre-existing tokens for BYOT (bring-your-own-token) inserts. | +| `setHomogeneous(bool)` | `boolean` | Treat all records as the same schema for a homogeneous bulk insert. | +| `setTokenMode(mode)` | `TokenMode` | Control tokenization mode for BYOT operations (see below). | + +**`TokenMode` enum** — controls how the SDK handles bring-your-own-token inserts: + +```typescript +import { TokenMode } from 'skyflow-node'; + +insertOptions.setTokenMode(TokenMode.ENABLE); +``` + +| Value | Description | +|---|---| +| `TokenMode.DISABLE` | Default. Vault generates all tokens. | +| `TokenMode.ENABLE` | Caller provides tokens; vault accepts them as-is. | +| `TokenMode.ENABLE_STRICT` | Caller provides tokens; vault validates them before accepting. | + ### Detokenize: `.detokenize(request, options)` Convert tokens back into plaintext values (or masked values) using the `.detokenize()` method. Detokenization accepts tokens and returns values. @@ -286,6 +343,8 @@ const response: DetokenizeResponse = await skyflowClient console.log("Detokenization response:", response); ``` +Returns a `DetokenizeResponse` (`detokenizedFields`, `errors`) — see [API Reference](docs/api_reference.md#detokenizeresponse). + > [!TIP] > See the full example in the samples directory: [detokenzie-records.ts](samples/vault-api/detokenzie-records.ts) @@ -313,6 +372,8 @@ const response: GetResponse = await skyflowClient console.log("Get response:", response); ``` +Returns a `GetResponse` (`data`, `errors`) — see [API Reference](docs/api_reference.md#getresponse). + > **Note:** The response key is `skyflowId`. The legacy `skyflow_id` key is deprecated and will be removed in an upcoming release. #### Get by Skyflow IDs @@ -397,6 +458,36 @@ Use redaction types to control how sensitive data displays when retrieved from t - Use `MASKED` to provide partial visibility of sensitive data for less critical use cases. - Use `PLAIN_TEXT` for internal, authorized access where full data visibility is necessary. +#### GetOptions reference + +`GetOptions` accepts the following setters: + +| Setter | Type | Description | +|---|---|---| +| `setReturnTokens(bool)` | `boolean` | Return tokens instead of plain-text values. | +| `setRedactionType(type)` | `RedactionType` | Control how values are redacted in the response. | +| `setFields(fields)` | `Array` | Limit the response to specific field names. | +| `setOffset(offset)` | `string` | Pagination offset (number of records to skip). | +| `setLimit(limit)` | `string` | Maximum number of records to return. | +| `setDownloadUrl(bool)` | `boolean` | Return a pre-signed download URL for file fields. | +| `setColumnName(name)` | `string` | Column to query by value (use with `setColumnValues`). | +| `setColumnValues(values)` | `Array` | Values to match in the column specified by `setColumnName`. | +| `setOrderBy(order)` | `OrderByEnum` | Sort order for returned records (see below). | + +**`OrderByEnum`** — controls sort order when retrieving records: + +```typescript +import { OrderByEnum } from 'skyflow-node'; + +getOptions.setOrderBy(OrderByEnum.ASCENDING); +``` + +| Value | Description | +|---|---| +| `OrderByEnum.ASCENDING` | Sort records in ascending order. | +| `OrderByEnum.DESCENDING` | Sort records in descending order. | +| `OrderByEnum.NONE` | No explicit sort order (server default). | + ### Update Records Update data in your vault using the `update` method. Create an update request with the `UpdateRequest` class, specifying parameters such as the table name and data (as a dictionary). @@ -406,7 +497,7 @@ Configure update options using the `UpdateOptions` class to control returnTokens #### Construct an update request ```typescript -import { UpdateRequest, UpdateResponse } from 'skyflow-node'; +import { UpdateRequest, UpdateOptions, UpdateResponse, TokenMode } from 'skyflow-node'; const updateRequest = new UpdateRequest('table1', { skyflowId: '', @@ -414,15 +505,30 @@ const updateRequest = new UpdateRequest('table1', { : '' }); +const updateOptions = new UpdateOptions(); +updateOptions.setReturnTokens(true); // return tokens for updated fields + const response: UpdateResponse = await skyflowClient .vault('') - .update(updateRequest); + .update(updateRequest, updateOptions); console.log('Update response:', response); ``` +Returns an `UpdateResponse` (`updatedField`, `errors`) — see [API Reference](docs/api_reference.md#updateresponse). With the default `setReturnTokens(false)`, `updatedField` contains only `skyflowId`. + > **Note:** The response key is `skyflowId`. The legacy `skyflow_id` key is deprecated and will be removed in an upcoming release. +#### UpdateOptions reference + +`UpdateOptions` accepts the following setters: + +| Setter | Type | Description | +|---|---|---| +| `setReturnTokens(bool)` | `boolean` | When `true`, returns tokens for updated fields. When `false`, returns the Skyflow ID only. Default `false`. | +| `setTokens(tokens)` | `Record` | Provide pre-existing tokens for a BYOT update. | +| `setTokenMode(mode)` | `TokenMode` | Control tokenization mode for BYOT operations. See [`TokenMode`](#insertOptions-reference). | + > [!TIP] > See the full example in the samples directory: [update-record.ts](samples/vault-api/update-record.ts) @@ -446,6 +552,8 @@ const response: DeleteResponse = await skyflowClient console.log("Delete response:", response); ``` +Returns a `DeleteResponse` (`deletedIds`, `errors`) — see [API Reference](docs/api_reference.md#deleteresponse). + > [!TIP] > See the full example in the samples directory: [delete-records.ts](samples/vault-api/delete-records.ts) @@ -468,6 +576,9 @@ const response: QueryResponse = await skyflowClient console.log("Query response:", response); ``` + +Returns a `QueryResponse` (`fields`, `errors`) — see [API Reference](docs/api_reference.md#queryresponse). Each record also includes a `tokenizedData` map. + > [!TIP] > See the full example in the samples directory: [query-records.ts](samples/vault-api/query-records.ts) @@ -514,6 +625,18 @@ const response: FileUploadResponse = await skyflowClient console.log("File upload:", response); ``` +#### FileUploadOptions reference + +`FileUploadOptions` accepts the following setters. Set **exactly one** file source (`setFileObject`, `setFilePath`, or `setBase64`): + +| Setter | Type | Description | +|---|---|---| +| `setSkyflowId(id)` | `string` | **Required.** The Skyflow ID of the record to attach the file to. | +| `setFileObject(file)` | `File` | Provide an in-memory `File` object directly. | +| `setFilePath(path)` | `string` | Path to the file on disk. The SDK reads and uploads the file. Requires Node.js v20+. | +| `setBase64(data)` | `string` | Base64-encoded file content. Use `setFileName` to supply the filename when using this option. | +| `setFileName(name)` | `string` | Filename to use when uploading base64-encoded content (e.g. `"document.pdf"`). | + > [!TIP] > See the full example in the samples directory: [file-upload.ts](samples/vault-api/file-upload.ts) @@ -538,6 +661,8 @@ const response: TokenizeResponse = await skyflowClient console.log("Tokenization Result:", response); ``` +Returns a `TokenizeResponse` (`tokens`, `errors`) — see [API Reference](docs/api_reference.md#tokenizeresponse). + > [!TIP] > See the full example in the samples directory: [tokenize-records.ts](samples/vault-api/tokenize-records.ts) @@ -573,17 +698,20 @@ options.setEntities([DetectEntities.ACCOUNT_NUMBER, DetectEntities.SSN]); // Ent options.setAllowRegexList([""]); // Allowlist regex patterns options.setRestrictRegexList([""]); // Restrict regex patterns -const tokenFormat = new TokenFormat(); // Specify the token format for deidentified entities -tokenFormat.setDefault(TokenType.VAULT_TOKEN); -optionsText.setTokenFormat(tokenFormat); +const tokenFormat = new TokenFormat(); +tokenFormat.setDefault(TokenType.VAULT_TOKEN); // default format for all entity types +// tokenFormat.setVaultToken([DetectEntities.SSN]); // vault token for specific entities +// tokenFormat.setEntityUniqueCounter([DetectEntities.NAME]); // unique counter for specific entities +// tokenFormat.setEntityOnly([DetectEntities.CREDIT_CARD]); // entity-only (no token) for specific entities +options.setTokenFormat(tokenFormat); -const transformations = new Transformations(); // Specify custom transformations for entities +const transformations = new Transformations(); transformations.setShiftDays({ - max: 30, // Maximum shift days - min: 30, // Minimum shift days - entities: [DetectEntities.ACCOUNT_NUMBER, DetectEntities.SSN], // Entities to apply the shift + max: 30, // maximum days to shift + min: 10, // minimum days to shift + entities: [DetectEntities.ACCOUNT_NUMBER, DetectEntities.SSN], // entity types to apply the shift }); -optionsText.setTransformations(transformations); +options.setTransformations(transformations); // Call deidentifyText const response = await skyflowClient @@ -675,9 +803,25 @@ transformations.setShiftDays({ }); options.setTransformations(transformations); -options.setOutputDirectory(''); // Output directory for saving the deidentified file. This is not supported in Cloudflare workers - -options.setWaitTime(64); // Wait time for response (max 64 seconds; throws error if more) +options.setOutputDirectory(''); // Output directory for saving the deidentified file. Not supported in Cloudflare workers. +options.setWaitTime(64); // Wait time for polling (max 64 seconds; returns runId + status if exceeded) + +// Image-specific options +options.setOutputProcessedImage(true); // Include the deidentified image in the response +options.setOutputOcrText(true); // Include OCR-extracted text in the response +options.setMaskingMethod(MaskingMethod.BLUR); // How to mask detected entities in images +options.setPixelDensity(150); // DPI for image rendering (higher = better quality) +options.setMaxResolution(1920); // Maximum pixel dimension for output images + +// Audio-specific options +options.setOutputProcessedAudio(true); // Include the deidentified audio in the response +options.setOutputTranscription(DetectOutputTranscription.DIARIZED_TRANSCRIPTION); // Transcription format +const bleep = new Bleep(); +bleep.setGain(1.0); // Volume of the bleep tone (0.0–1.0) +bleep.setFrequency(1000); // Frequency of the bleep tone in Hz +bleep.setStartPadding(0.1); // Seconds of silence before the bleep +bleep.setStopPadding(0.1); // Seconds of silence after the bleep +options.setBleep(bleep); // Apply bleep settings to redacted audio spans // Call deidentifyFile const response: DeidentifyFileResponse = await skyflowClient @@ -697,11 +841,39 @@ console.log('De-identify File Response:', response); - Presentations: `ppt`, `pptx` - Audio: `mp3`, `wav` +#### DeidentifyFileOptions reference + +| Setter | Type | Description | +|---|---|---| +| `setEntities(entities)` | `DetectEntities[]` | Entity types to detect and de-identify. | +| `setAllowRegexList(patterns)` | `string[]` | Regex patterns that always match as entities (allowlist). | +| `setRestrictRegexList(patterns)` | `string[]` | Regex patterns that never match as entities (denylist). | +| `setTokenFormat(format)` | `TokenFormat` | Token format for de-identified entities. | +| `setTransformations(t)` | `Transformations` | Custom transformations per entity type. | +| `setOutputDirectory(path)` | `string` | Directory to write de-identified output files. Not supported in Cloudflare Workers. | +| `setWaitTime(seconds)` | `number` | Max seconds to poll before returning `runId`+`status`. Minimum 1; maximum 64. | +| `setOutputProcessedImage(bool)` | `boolean` | Include the de-identified image binary in the response. Images only. | +| `setOutputOcrText(bool)` | `boolean` | Include OCR-extracted text in the response. Images only. | +| `setMaskingMethod(method)` | `MaskingMethod` | How to mask entities in images (`BLUR`, `BLACKBOX`, etc.). Images only. | +| `setPixelDensity(dpi)` | `number` | DPI for image rendering. Higher values improve quality. Images only. | +| `setMaxResolution(px)` | `number` | Maximum pixel dimension of the output image. Images only. | +| `setOutputProcessedAudio(bool)` | `boolean` | Include the de-identified audio binary in the response. Audio only. | +| `setOutputTranscription(format)` | `DetectOutputTranscription` | Transcription format (`DIARIZED_TRANSCRIPTION`, `MEDICAL_DIARIZED_TRANSCRIPTION`, etc.). Audio only. | +| `setBleep(bleep)` | `Bleep` | Bleep tone settings for redacted audio spans. Audio only. See `Bleep` below. | + +**`Bleep` class** — configures the bleep tone applied to redacted audio spans: + +| Setter | Type | Description | +|---|---|---| +| `setGain(value)` | `number` | Volume of the bleep tone (0.0 – 1.0). | +| `setFrequency(hz)` | `number` | Frequency of the bleep in hertz. | +| `setStartPadding(seconds)` | `number` | Silence padding before the bleep starts. | +| `setStopPadding(seconds)` | `number` | Silence padding after the bleep ends. | + **Notes:** -- Transformations can't be applied to Documents, Images, or PDFs file formats. -- The `waitTime` option must be ≤ 64 seconds; otherwise, an error is thrown. -- If the API takes more than 64 seconds to process the file, it will return only the `runId` and `status` in the response. +- Transformations can't be applied to Documents, Images, or PDFs. +- If the API takes more than `waitTime` seconds to process, the response contains only `runId` and `status`. Use `.getDetectRun(request)` to poll for the final result. > [!TIP] > See the full example in the samples directory: [deidentify-file.ts](samples/detect-api/deidentify-file.ts) @@ -742,6 +914,20 @@ Securely send and receive data between your systems and first- or third-party se - **Inbound connections**: Act as intermediaries between your client and server, tokenizing sensitive data before it reaches your backend, ensuring downstream services handle only tokenized data. - **Outbound connections**: Enable secure extraction of data from the vault and transfer it to third-party services via your backend server, such as processing checkout or card issuance flows. +### Configure a connection + +Add a `ConnectionConfig` to `SkyflowConfig.connectionConfigs` during initialization, or call `addConnectionConfig()` at runtime: + +```typescript +import { ConnectionConfig, Credentials } from 'skyflow-node'; + +const connectionConfig: ConnectionConfig = { + connectionId: '', // required: unique connection identifier + connectionUrl: '', // required: gateway URL for this connection + // credentials: connectionCredentials // optional: per-connection credentials; overrides skyflowCredentials +}; +``` + ### Invoke a connection Invoke a connection using the `invoke` method of the Skyflow client. @@ -776,7 +962,6 @@ The method of `RequestMethod.POST` must be one of: - `POST` - `PUT` - `PATCH` -- `DELETE` **pathParams, queryParams, header, body** are the JSON objects represented as dictionaries that will be sent through the connection integration url. @@ -844,33 +1029,79 @@ Generate service account tokens using the [Service Account](https://github.com/s The `generateBearerToken(filepath)` function takes the `credentials.json` file path for token generation. -```js -let bearerToken: string = ''; -generateBearerToken('path/to/credentials.json') +```ts +import { generateBearerToken, BearerTokenOptions } from 'skyflow-node'; + +const options: BearerTokenOptions = { + roleIds: ['roleId1'], // optional: scope to specific roles + ctx: 'user_12345', // optional: embed context + logLevel: LogLevel.ERROR, +}; + +generateBearerToken('path/to/credentials.json', options) .then(response => { - bearerToken = response.accessToken; - // Resolve the generated Bearer Token - resolve(bearerToken); + const bearerToken = response.accessToken; }) - .catch(error => { - // Handle any errors that occur during the generation process - reject(error); - }); + .catch(error => { /* handle error */ }); +``` + +##### `generateBearerTokenFromCreds(credentialsString)` + +Use `generateBearerTokenFromCreds` when your credentials JSON is available as a string (e.g. from a secret manager) rather than a file on disk. It accepts the same `BearerTokenOptions` as `generateBearerToken`. + +```ts +import { generateBearerTokenFromCreds, BearerTokenOptions } from 'skyflow-node'; + +const credentialsString = JSON.stringify(require('./credentials.json')); +const options: BearerTokenOptions = { roleIds: ['roleId1'] }; + +const response = await generateBearerTokenFromCreds(credentialsString, options); +const bearerToken = response.accessToken; +``` + +**`BearerTokenOptions` type:** + +```ts +type BearerTokenOptions = { + roleIds?: string[]; // Scope the token to specific service-account roles + ctx?: string | Record; // Context value(s) embedded in the token + logLevel?: LogLevel; // Override SDK log level for this call + tokenUri?: string; // Override the token endpoint URL from the credentials file +}; +``` + +**`GenerateTokenOptions` type** — used when logLevel override is the only option needed: + +```ts +import { GenerateTokenOptions } from 'skyflow-node'; + +const options: GenerateTokenOptions = { + logLevel: LogLevel.DEBUG, +}; ``` -##### `generateBearerTokenFromCreds(credentials)` +**Checking whether a token has expired — `isExpired`:** + +```ts +import { isExpired } from 'skyflow-node'; -Alternatively, you can also send the entire credentials as string by using `generateBearerTokenFromCreds(string)`. +// Returns true if the JWT bearer token is expired or will expire within the threshold +const expired: boolean = isExpired(bearerToken); +if (expired) { + // regenerate before making API calls + const { accessToken } = await generateBearerToken('path/to/credentials.json'); +} +``` > [!TIP] > See the full example in the samples directory: [token-generation-example.ts](http://github.com/skyflowapi/skyflow-node/blob/v2/samples/service-account/token-generation-example.ts) #### Generate bearer tokens scoped to certain roles -Generate bearer tokens with access limited to a specific role by specifying the appropriate roleId when using a service account with multiple roles. Use this to limit access for services with multiple responsibilities, such as segregating access for billing and analytics. Generated bearer tokens are valid for 60 minutes and can only execute operations permitted by the permissions associated with the designated role. +Generate bearer tokens with access limited to a specific role by specifying the appropriate `roleIds` when using a service account with multiple roles. Use this to limit access for services with multiple responsibilities, such as segregating access for billing and analytics. Generated bearer tokens are valid for 60 minutes and can only execute operations permitted by the permissions associated with the designated role. ```ts -const options = { +const options: BearerTokenOptions = { roleIds: ['roleId1', 'roleId2'], }; ``` @@ -934,28 +1165,56 @@ const credentials: PathCredentials = { > See the full example in the samples directory: [token-generation-with-context-example.ts](samples/service-account/token-generation-with-context-example.ts) > See Skyflow's [context-aware authorization](https://docs.skyflow.com) and [conditional data access](https://docs.skyflow.com) docs for policy variable syntax like `request.context.*`. -#### Generate signed data tokens: `generateSignedDataTokens(filepath, options)` +#### Generate signed data tokens Digitally sign data tokens with a service account's private key to add an extra layer of protection. Skyflow generates data tokens when sensitive data is inserted into the vault. Detokenize signed tokens only by providing the signed data token along with a bearer token generated from the service account's credentials. The service account must have the necessary permissions and context to successfully detokenize the signed data tokens. -The `ctx` parameter on signed data tokens also accepts either a **string** or a **JSON object**, using the same format as bearer tokens: +Two variants are available — choose based on how you supply credentials: + +```ts +import { + generateSignedDataTokens, + generateSignedDataTokensFromCreds, + SignedDataTokensOptions, +} from 'skyflow-node'; + +const options: SignedDataTokensOptions = { + dataTokens: ['dataToken1', 'dataToken2'], // required: tokens to sign + timeToLive: 90, // optional: seconds until expiry (default 60) + ctx: 'user_12345', // optional: context embedded in token +}; + +// From a credentials file on disk: +const response = await generateSignedDataTokens('path/to/credentials.json', options); + +// From a credentials JSON string (e.g. from a secret manager): +const credentialsString = JSON.stringify(require('./credentials.json')); +const response = await generateSignedDataTokensFromCreds(credentialsString, options); + +response.forEach(({ token, signedToken }) => { + console.log('Original token:', token); + console.log('Signed token:', signedToken); +}); +``` + +The `ctx` parameter also accepts a JSON object for multi-value context: ```typescript -// String context -const options = { - ctx: 'user_12345', - dataTokens: ['dataToken1', 'dataToken2'], - timeToLive: 90, +const options: SignedDataTokensOptions = { + dataTokens: ['dataToken1'], + ctx: { role: 'analyst', department: 'research' }, }; +``` -// JSON object context -const options = { - ctx: { - role: 'analyst', - department: 'research', - }, - dataTokens: ['dataToken1', 'dataToken2'], - timeToLive: 90, +**`SignedDataTokensOptions` type:** + +```ts +type SignedDataTokensOptions = { + dataTokens: string[]; // Data tokens to sign (required) + timeToLive?: number; // Seconds until token expiry (default 60) + ctx?: string | Record; // Context value(s) embedded in the token + logLevel?: LogLevel; // Override SDK log level for this call + tokenUri?: string; // Override the token endpoint URL from credentials }; ``` @@ -963,6 +1222,114 @@ const options = { > See the full example in the samples directory: [signed-token-generation-example.ts](samples/service-account/signed-token-generation-example.ts) > See [docs.skyflow.com](https://docs.skyflow.com) for more details on authentication, access control, and governance for Skyflow. +## Runtime client management + +After initializing the `Skyflow` client, you can add, update, retrieve, and remove vault and connection configurations at any time without recreating the client. + +### Vault management + +```ts +import { Skyflow, VaultConfig, Credentials, Env } from 'skyflow-node'; + +// Add a new vault after initialization +const newVault: VaultConfig = { + vaultId: '', + clusterId: '', + env: Env.PROD, +}; +skyflowClient.addVaultConfig(newVault); + +// Update an existing vault's configuration (e.g. rotate credentials) +const rotatedCredentials: Credentials = { apiKey: '' }; +skyflowClient.updateVaultConfig({ ...newVault, credentials: rotatedCredentials }); + +// Retrieve a vault configuration by ID +const config = skyflowClient.getVaultConfig(''); + +// Remove a vault configuration +skyflowClient.removeVaultConfig(''); +``` + +### Connection management + +```ts +import { ConnectionConfig } from 'skyflow-node'; + +const newConnection: ConnectionConfig = { + connectionId: '', + connectionUrl: '', +}; + +// Add a new connection after initialization +skyflowClient.addConnectionConfig(newConnection); + +// Update an existing connection (e.g. change the URL or credentials) +skyflowClient.updateConnectionConfig({ ...newConnection, connectionUrl: '' }); + +// Retrieve a connection configuration by ID +const connConfig = skyflowClient.getConnectionConfig(''); + +// Remove a connection +skyflowClient.removeConnectionConfig(''); +``` + +### Credentials and log level + +```ts +import { Credentials, LogLevel } from 'skyflow-node'; + +// Update shared credentials at runtime (applies to all vaults/connections +// that don't have their own individual credentials) +const newCredentials: Credentials = { apiKey: '' }; +skyflowClient.updateSkyflowCredentials(newCredentials); + +// Read current shared credentials +const creds = skyflowClient.getSkyflowCredentials(); + +// Change log level at runtime +skyflowClient.setLogLevel(LogLevel.DEBUG); + +// Read current log level +const level = skyflowClient.getLogLevel(); +``` + +### Skyflow class public methods reference + +| Method | Description | +|---|---| +| `vault(vaultId?)` | Return a `VaultController` for the given vault ID. Defaults to the first configured vault. | +| `detect(vaultId?)` | Return a `DetectController` for the given vault ID. | +| `connection(connectionId?)` | Return a `ConnectionController` for the given connection ID. | +| `addVaultConfig(config)` | Add a new vault configuration. Throws if the vault ID already exists. | +| `updateVaultConfig(config)` | Update an existing vault configuration. Throws if the vault ID is not found. | +| `getVaultConfig(vaultId)` | Return the `VaultConfig` for the given vault ID. | +| `removeVaultConfig(vaultId)` | Remove a vault configuration by ID. | +| `addConnectionConfig(config)` | Add a new connection configuration. Throws if the connection ID already exists. | +| `updateConnectionConfig(config)` | Update an existing connection configuration. | +| `getConnectionConfig(connectionId)` | Return the `ConnectionConfig` for the given connection ID. | +| `removeConnectionConfig(connectionId)` | Remove a connection configuration by ID. | +| `updateSkyflowCredentials(credentials)` | Replace the shared credentials used by all vaults/connections. | +| `getSkyflowCredentials()` | Return the current shared credentials. | +| `setLogLevel(logLevel)` | Change the SDK log level at runtime. | +| `getLogLevel()` | Return the current SDK log level. | + +## Using the client in production + +**Initialize once and reuse.** `new Skyflow(config)` returns a long-lived client that caches tokens per vault. Construct it once at startup (e.g. as a module-level singleton) and reuse it across requests. Recreating the client on every call discards these caches and forces unnecessary token regeneration. + +```ts +// At application startup +const skyflowClient = new Skyflow(skyflowConfig); + +// Reuse `skyflowClient` for the lifetime of the process +``` + +**Bearer token refresh is automatic.** When you authenticate with a service-account credentials file/string (or API key), the SDK caches the generated bearer token and regenerates it automatically once it expires. You don't need to manage token lifecycle yourself. (For the rare expire-mid-request case, see [Bearer token expiration edge cases](#bearer-token-expiration-edge-cases).) + +**Runtime configuration changes are not concurrency-safe.** Methods that mutate client state at runtime — `addVaultConfig`, `updateVaultConfig`, `removeVaultConfig`, the `*ConnectionConfig` methods, and `updateSkyflowCredentials` — should be called during setup, not concurrently with in-flight requests. Once configured, the client is safe to reuse across concurrent calls. + +**Timeouts and retries.** The SDK does not currently expose request timeout or automatic-retry configuration. Wrap your SDK calls with your own timeout/retry logic at the application layer if needed. + ## Logging The SDK provides useful logging. By default, the logging level is set to `LogLevel.ERROR`. Change this by setting the `logLevel` in Skyflow Config while creating the Skyflow Client as shown below: @@ -978,7 +1345,7 @@ Currently, the following five log levels are supported: - `ERROR`: When `LogLevel.ERROR` is passed, only ERROR logs will be printed. - `OFF`: - `LogLevel.OFF` can be used to turn off all logging from the Skyflow Python SDK. + `LogLevel.OFF` can be used to turn off all logging from the Skyflow Node SDK. > [!NOTE] > The ranking of logging levels is as follows: `DEBUG` < `INFO` < `WARN` < `ERROR` < `OFF`. @@ -1010,6 +1377,7 @@ try { console.error("Skyflow Specific Error:", { code: error.error?.httpCode, message: error.message, + requestId: error.error?.requestId, details: error.error?.details, }); } else { @@ -1018,6 +1386,40 @@ try { } ``` +### Per-record errors (`SkyflowRecordError`) + +Some operations — such as `insert` with `continueOnError: true` and `detokenize` — can partially succeed. In these cases the response object contains an `errors` array alongside the successful results. Each entry in `errors` is a `SkyflowRecordError`: + +```ts +import { InsertResponse, SkyflowRecordError } from 'skyflow-node'; + +const response: InsertResponse = await skyflowClient.vault(vaultId).insert(request, options); + +if (response.errors && response.errors.length > 0) { + response.errors.forEach((err: SkyflowRecordError) => { + console.error({ + requestId: err.requestId, // x-request-id from the server response + httpCode: err.httpCode, // HTTP status code for this record + requestIndex: err.requestIndex, // Index of the failed record in the input array + error: err.error, // Error description string + token: err.token, // Token (detokenize errors only) + }); + }); +} +``` + +`SkyflowRecordError` shape: + +```ts +interface SkyflowRecordError { + error: string; + requestId: string | null; + httpCode?: string | number | null; + requestIndex?: number | null; + token?: string | null; // present on detokenize errors +} +``` + ### Bearer token expiration edge cases When using bearer tokens for authentication and API requests, a token may expire after verification but before the actual API call completes. This causes the request to fail unexpectedly. An error from this edge case looks like this: @@ -1032,6 +1434,51 @@ If you encounter this kind of error, retry the request. During the retry the SDK > See the full example in the samples directory: [bearer-token-expiry-example.ts](samples/service-account/bearer-token-expiry-example.ts) > See [docs.skyflow.com](https://docs.skyflow.com) for more details on authentication, access control, and governance for Skyflow. +## Troubleshooting + +Most first-run problems come from configuration mismatches. Every error thrown by the SDK is a `SkyflowError` exposing `httpCode`, `message`, and `details` — inspect these first (see [Error handling](#error-handling)). + +| Symptom | Likely cause | Fix | +|---|---|---| +| `npm install skyflow-node` fails | Unsupported Node version | Requires Node v12.22.12 or above. | +| Connection/DNS failures, or 404 on every call | Wrong `clusterId` | `clusterId` is the first segment of your vault URL: `https://{clusterId}.vault.skyflowapis.com`. | +| Requests hit the wrong host / unexpected auth failures | Wrong `env` | Match `env` to where your vault runs (`Env.PROD`, `Env.SANDBOX`, `Env.DEV`, `Env.STAGE`). | +| `401 Unauthorized` | Invalid or expired credentials | Verify your API key or service-account credentials. Regenerate if needed. | +| `403 Forbidden` | Service account lacks permission | Grant the service account a role with the required permissions, or use a [scoped token](#generate-bearer-tokens-scoped-to-certain-roles). | +| `404` referencing a table or column | Name mismatch | Confirm table and column names match your vault schema exactly (case-sensitive). | +| Vault not found / 404 with a valid `clusterId` | Wrong `vaultId` | Copy `vaultId` from the vault's details page in Skyflow Studio. | +| `Authentication failed. Bearer token is expired.` | Token expired mid-request | Retry the request; the SDK regenerates the token. See [Bearer token expiration edge cases](#bearer-token-expiration-edge-cases). | +| Unexpected credential is used | Multiple credential types provided | Only one credential type is used at a time; the last one added takes precedence. | + +If you're stuck, set `logLevel: LogLevel.DEBUG` during development for detailed SDK logs (see [Logging](#logging)). + +## TypeScript types reference + +For the full reference of all exported types, interfaces, enums, request/response fields, and options setters, see the **[API Reference](docs/api_reference.md)**. + +The most commonly imported TypeScript types are: + +```ts +import { + // Credential sub-types (for stricter typing) + ApiKeyCredentials, + TokenCredentials, + PathCredentials, // supports optional tokenUri + StringCredentials, // supports optional tokenUri + + // Request item shapes + DetokenizeData, // { token: string; redactionType?: RedactionType } + TokenizeRequestType, // { value: string; columnGroup: string } + FileInput, // { file: File } | { filePath: string } + + // Response record shapes + InsertResponseType, // { skyflowId: string; [field: string]: unknown } + GetResponseData, // { [field: string]: unknown } + QueryResponseType, // { [field: string]: unknown } + SkyflowRecordError, // shape of entries in response.errors[] +} from 'skyflow-node'; +``` + ## Security ### Reporting a Vulnerability diff --git a/docs/api_reference.md b/docs/api_reference.md new file mode 100644 index 00000000..7a72694c --- /dev/null +++ b/docs/api_reference.md @@ -0,0 +1,624 @@ +# API Reference + +A reference for the public Skyflow Node SDK surface: client-management methods, request classes, options classes, response classes, enums, Detect helper classes, and service-account functions. For task-oriented usage and examples, see the [README](../README.md). + +All properties, setters, and enum values below are taken directly from the SDK source. + +## Table of Contents + +- [Client management methods](#client-management-methods) +- [Request classes](#request-classes) +- [Options classes](#options-classes) +- [Response classes](#response-classes) +- [Enums](#enums) +- [Detect helper classes](#detect-helper-classes) +- [Service account functions](#service-account-functions) + +--- + +## Client management methods + +The `Skyflow` client exposes the following methods to manage configuration at runtime, in addition to the vault/detect/connection accessors. + +| Method | Description | +|--------|-------------| +| `vault(vaultId?)` | Return a `VaultController` for the given vault ID. Defaults to the first configured vault. | +| `detect(vaultId?)` | Return a `DetectController` for the given vault ID. | +| `connection(connectionId?)` | Return a `ConnectionController` for the given connection ID. | +| `addVaultConfig(config)` | Add a vault configuration after initialization. Throws if the vault ID already exists. | +| `updateVaultConfig(config)` | Update an existing vault configuration. | +| `getVaultConfig(vaultId)` | Return the `VaultConfig` for the given vault ID. | +| `removeVaultConfig(vaultId)` | Remove a vault configuration. | +| `addConnectionConfig(config)` | Add a connection configuration. Throws if the connection ID already exists. | +| `updateConnectionConfig(config)` | Update an existing connection configuration. | +| `getConnectionConfig(connectionId)` | Return the `ConnectionConfig` for the given connection ID. | +| `removeConnectionConfig(connectionId)` | Remove a connection configuration. | +| `updateSkyflowCredentials(credentials)` | Replace the shared credentials used by all vaults/connections. | +| `getSkyflowCredentials()` | Return the current shared credentials. | +| `setLogLevel(logLevel)` | Change the log level at runtime. | +| `updateLogLevel(logLevel)` | Change the log level and return `this` for chaining. | +| `getLogLevel()` | Return the current log level. | + +```ts +// Example: manage configuration after initialization +skyflowClient.addVaultConfig(anotherVaultConfig); +skyflowClient.updateLogLevel(LogLevel.DEBUG); +const level = skyflowClient.getLogLevel(); +``` + +--- + +## Request classes + +All request classes are importable from `'skyflow-node'`. + +### `InsertRequest` + +Passed to `vault().insert()`. + +| Constructor argument | Type | Description | +|---|---|---| +| `table` | `string` | Target table name. | +| `data` | `Record[]` | Records to insert. Each is a `{ column: value }` object. | + +Configure additional behavior with [`InsertOptions`](#insertoptions). + +### `UpdateRequest` + +Passed to `vault().update()`. + +| Constructor argument | Type | Description | +|---|---|---| +| `table` | `string` | Target table name. | +| `data` | `Record` | Object containing `skyflowId` and the columns to update. | + +Configure additional behavior with [`UpdateOptions`](#updateoptions). + +### `GetRequest` + +Passed to `vault().get()` for retrieval by Skyflow IDs. + +| Constructor argument | Type | Description | +|---|---|---| +| `table` | `string` | Target table name. | +| `ids` | `string[]` | Skyflow IDs to retrieve. Mutually exclusive with column-based options. | + +Configure additional behavior with [`GetOptions`](#getoptions). + +### `GetColumnRequest` + +Passed to `vault().get()` for retrieval by a unique column value. + +| Constructor argument | Type | Description | +|---|---|---| +| `table` | `string` | Target table name. | +| `columnName` | `string` | Unique column to look up by (must have a `unique` constraint). | +| `columnValues` | `string[]` | Values to match in the column. | + +Configure additional behavior with [`GetOptions`](#getoptions). + +### `DetokenizeRequest` + +Passed to `vault().detokenize()`. + +| Constructor argument | Type | Description | +|---|---|---| +| `data` | `DetokenizeData[]` | Tokens to detokenize. Each item: `{ token: string; redactionType?: RedactionType }`. | + +Configure additional behavior with [`DetokenizeOptions`](#detokenizeoptions). + +### `TokenizeRequest` + +Passed to `vault().tokenize()`. + +| Constructor argument | Type | Description | +|---|---|---| +| `values` | `TokenizeRequestType[]` | Values to tokenize. Each item: `{ value: string; columnGroup: string }`. | + +### `DeleteRequest` + +Passed to `vault().delete()`. + +| Constructor argument | Type | Description | +|---|---|---| +| `table` | `string` | Target table name. | +| `ids` | `string[]` | Skyflow IDs to delete. | + +### `QueryRequest` + +Passed to `vault().query()`. + +| Constructor argument | Type | Description | +|---|---|---| +| `query` | `string` | SQL query string to execute. | + +### `FileUploadRequest` + +Passed to `vault().uploadFile()`. Use [`FileUploadOptions`](#fileuploadoptions) to supply the file and Skyflow ID. + +| Constructor argument | Type | Description | +|---|---|---| +| `table` | `string` | Target table name. | +| `columnName` | `string` | File column name. | + +### `DeidentifyTextRequest` + +Passed to `detect().deidentifyText()`. + +| Constructor argument | Type | Description | +|---|---|---| +| `text` | `string` | Text to de-identify. | + +Configure additional behavior with [`DeidentifyTextOptions`](#deidentifytextoptions). + +### `ReidentifyTextRequest` + +Passed to `detect().reidentifyText()`. + +| Constructor argument | Type | Description | +|---|---|---| +| `text` | `string` | The redacted/de-identified text to re-identify. | + +Configure additional behavior with [`ReidentifyTextOptions`](#reidentifytextoptions). + +### `DeidentifyFileRequest` + +Passed to `detect().deidentifyFile()`. Provide either a `File` object or a file path — not both. + +| Constructor argument | Type | Description | +|---|---|---| +| `fileInput` | `FileInput` | `{ file: File }` or `{ filePath: string }`. | + +Configure additional behavior with [`DeidentifyFileOptions`](#deidentifyfileoptions). + +### `GetDetectRunRequest` + +Passed to `detect().getDetectRun()`. + +| Constructor argument | Type | Description | +|---|---|---| +| `options` | `{ runId: string }` | The `runId` returned by a prior `deidentifyFile` call. | + +### `InvokeConnectionRequest` + +Passed to `connection().invoke()`. + +| Constructor argument | Type | Description | +|---|---|---| +| `method` | `RequestMethod` | HTTP method. See [`RequestMethod`](#requestmethod). | +| `body` | `StringKeyValueMapType \| null` | Request body. | +| `headers` | `StringKeyValueMapType \| null` | Request headers. | +| `pathParams` | `StringKeyValueMapType \| null` | Path parameters. | +| `queryParams` | `StringKeyValueMapType \| null` | Query parameters. | + +--- + +## Options classes + +All options classes are importable from `'skyflow-node'`. Construct an options object, call setters to configure, then pass it as the second argument to the corresponding operation. + +### `InsertOptions` + +| Setter | Type | Default | Description | +|---|---|---|---| +| `setReturnTokens(bool)` | `boolean` | `false` | Return tokens for inserted fields. | +| `setContinueOnError(bool)` | `boolean` | `false` | Continue the batch despite per-record errors. | +| `setUpsertColumn(column)` | `string` | — | Column to use as the upsert index (must have `unique` constraint). | +| `setHomogeneous(bool)` | `boolean` | `false` | Treat all records as the same schema. | +| `setTokens(tokens)` | `Record[]` | — | BYOT values, aligned with the insert data (used with `setTokenMode`). | +| `setTokenMode(mode)` | `TokenMode` | `DISABLE` | BYOT mode. See [`TokenMode`](#tokenmode). | + +### `UpdateOptions` + +| Setter | Type | Default | Description | +|---|---|---|---| +| `setReturnTokens(bool)` | `boolean` | `false` | Return tokens for updated fields. When `false`, only `skyflowId` is returned. | +| `setTokens(tokens)` | `Record` | — | BYOT values for the updated columns. | +| `setTokenMode(mode)` | `TokenMode` | `DISABLE` | BYOT mode. See [`TokenMode`](#tokenmode). | + +### `GetOptions` + +| Setter | Type | Default | Description | +|---|---|---|---| +| `setReturnTokens(bool)` | `boolean` | `false` | Return tokens instead of plain-text values. | +| `setRedactionType(type)` | `RedactionType` | — | Control how values are redacted. See [`RedactionType`](#redactiontype). | +| `setFields(fields)` | `string[]` | — | Limit the response to specific field names. | +| `setOffset(offset)` | `string` | — | Pagination offset (records to skip). | +| `setLimit(limit)` | `string` | — | Maximum records to return. | +| `setDownloadUrl(bool)` | `boolean` | — | Return a pre-signed download URL for file fields. | +| `setColumnName(name)` | `string` | — | Column to filter by (use with `setColumnValues`). | +| `setColumnValues(values)` | `string[]` | — | Values to match in the column set by `setColumnName`. | +| `setOrderBy(order)` | `OrderByEnum` | — | Sort order. See [`OrderByEnum`](#orderbyenum). | + +### `DetokenizeOptions` + +| Setter | Type | Default | Description | +|---|---|---|---| +| `setContinueOnError(bool)` | `boolean` | `false` | Continue despite per-token errors. | +| `setDownloadUrl(bool)` | `boolean` | — | Return pre-signed download URLs for file tokens. | + +### `FileUploadOptions` + +Provide **exactly one** file source: `setFileObject`, `setFilePath`, or `setBase64`. + +| Setter | Type | Description | +|---|---|---| +| `setSkyflowId(id)` | `string` | **Required.** Skyflow ID of the record to attach the file to. | +| `setFileObject(file)` | `File` | In-memory `File` object. | +| `setFilePath(path)` | `string` | Path to a file on disk. Requires Node.js v20+. | +| `setBase64(data)` | `string` | Base64-encoded file content. Use with `setFileName`. | +| `setFileName(name)` | `string` | Filename for base64 uploads (e.g. `"document.pdf"`). | + +### `DeidentifyTextOptions` + +| Setter | Type | Description | +|---|---|---| +| `setEntities(entities)` | `DetectEntities[]` | Entity types to detect and de-identify. | +| `setAllowRegexList(patterns)` | `string[]` | Regex patterns that always match as entities. | +| `setRestrictRegexList(patterns)` | `string[]` | Regex patterns that never match as entities. | +| `setTokenFormat(format)` | `TokenFormat` | Token format per entity type. See [`TokenFormat`](#tokenformat). | +| `setTransformations(t)` | `Transformations` | Custom transformations. See [`Transformations`](#transformations). | + +### `ReidentifyTextOptions` + +| Setter | Type | Description | +|---|---|---| +| `setRedactedEntities(entities)` | `DetectEntities[]` | Entity types to keep redacted. | +| `setMaskedEntities(entities)` | `DetectEntities[]` | Entity types to mask. | +| `setPlainTextEntities(entities)` | `DetectEntities[]` | Entity types to reveal as plain text. | + +### `DeidentifyFileOptions` + +| Setter | Type | Description | +|---|---|---| +| `setEntities(entities)` | `DetectEntities[]` | Entity types to detect. | +| `setAllowRegexList(patterns)` | `string[]` | Regex patterns to always treat as detectable. | +| `setRestrictRegexList(patterns)` | `string[]` | Regex patterns to exclude from detection. | +| `setTokenFormat(format)` | `TokenFormat` | Token format per entity type. | +| `setTransformations(t)` | `Transformations` | Custom transformations (not supported for Documents, Images, or PDFs). | +| `setOutputDirectory(path)` | `string` | Directory to write the processed file. Not supported in Cloudflare Workers. | +| `setWaitTime(seconds)` | `number` | Max seconds to poll (≤ 64). Returns `runId` + `status` if exceeded. | +| `setOutputProcessedImage(bool)` | `boolean` | Include the processed image in the response. Images only. | +| `setOutputOcrText(bool)` | `boolean` | Include OCR-extracted text. Images only. | +| `setMaskingMethod(method)` | `MaskingMethod` | Masking method for image entities. See [`MaskingMethod`](#maskingmethod). | +| `setPixelDensity(dpi)` | `number` | DPI for image rendering. Images/PDFs only. | +| `setMaxResolution(px)` | `number` | Maximum pixel dimension of the output. Images/PDFs only. | +| `setOutputProcessedAudio(bool)` | `boolean` | Include processed audio in the response. Audio only. | +| `setOutputTranscription(format)` | `DetectOutputTranscription` | Transcription format. See [`DetectOutputTranscription`](#detectoutputtranscription). Audio only. | +| `setBleep(bleep)` | `Bleep` | Bleep tone config for redacted audio spans. See [`Bleep`](#bleep). Audio only. | + +--- + +## Response classes + +Every operation returns a typed response class. All response classes are importable from `'skyflow-node'`. + +> **The `errors` field** is present on most responses as `SkyflowRecordError[] | null`. It is populated only on partial failure (for example when `setContinueOnError(true)` is used); it is `null` when there are no errors. See [`SkyflowRecordError`](#skyflowrecorderror). + +### `InsertResponse` + +Returned by `vault().insert()`. + +| Field | Type | Description | +|---|---|---| +| `insertedFields` | `InsertResponseType[]` | Inserted records. Each has `skyflowId`; with `setReturnTokens(true)`, also a token per column; with `setContinueOnError(true)`, also a `requestIndex`. | +| `errors` | `SkyflowRecordError[] \| null` | See note above. | + +### `GetResponse` + +Returned by `vault().get()`. + +| Field | Type | Description | +|---|---|---| +| `data` | `GetResponseData[]` | Retrieved records as `{ field: value }` objects. Tokens instead of values when `setReturnTokens(true)`. | +| `errors` | `SkyflowRecordError[] \| null` | See note above. | + +### `UpdateResponse` + +Returned by `vault().update()`. + +| Field | Type | Description | +|---|---|---| +| `updatedField` | `InsertResponseType` | The updated record: `skyflowId`, plus tokens per column when `setReturnTokens(true)`. | +| `errors` | `SkyflowRecordError[] \| null` | See note above. | + +### `DeleteResponse` + +Returned by `vault().delete()`. + +| Field | Type | Description | +|---|---|---| +| `deletedIds` | `string[]` | Skyflow IDs of the deleted records. | +| `errors` | `SkyflowRecordError[] \| null` | See note above. | + +### `DetokenizeResponse` + +Returned by `vault().detokenize()`. + +| Field | Type | Description | +|---|---|---| +| `detokenizedFields` | `Array<{token: string; value: string; type: string}> \| null` | One entry per token with the original `token`, the decoded `value`, and its `type`. | +| `errors` | `SkyflowRecordError[] \| null` | See note above. | + +### `TokenizeResponse` + +Returned by `vault().tokenize()`. + +| Field | Type | Description | +|---|---|---| +| `tokens` | `string[]` | One token per input value, in the same order as the request. | +| `errors` | `SkyflowRecordError[] \| null` | See note above. | + +### `QueryResponse` + +Returned by `vault().query()`. + +| Field | Type | Description | +|---|---|---| +| `fields` | `QueryResponseType[]` | Matching records. Each includes a `tokenizedData` map alongside the field values. | +| `errors` | `SkyflowRecordError[] \| null` | See note above. | + +### `FileUploadResponse` + +Returned by `vault().uploadFile()`. + +| Field | Type | Description | +|---|---|---| +| `skyflowId` | `string` | ID of the record the file was attached to. | +| `errors` | `SkyflowRecordError[] \| null` | See note above. | + +### `InvokeConnectionResponse` + +Returned by `connection().invoke()`. + +| Field | Type | Description | +|---|---|---| +| `data` | `object \| undefined` | The connection's response body. | +| `metadata` | `{ requestId: string } \| undefined` | Response metadata including the server-side `requestId`. | +| `errors` | `SkyflowRecordError[] \| null` | See note above. | + +### `DeidentifyTextResponse` + +Returned by `detect().deidentifyText()`. + +| Field | Type | Description | +|---|---|---| +| `processedText` | `string` | The de-identified text. | +| `entities` | `Array<{token, value, textIndex: IndexRange, processedIndex: IndexRange, entity, scores}>` | Detected entities. | +| `wordCount` | `number` | Word count of the input text. | +| `charCount` | `number` | Character count of the input text. | +| `errors` | `SkyflowRecordError[] \| null` | See note above. | + +### `ReidentifyTextResponse` + +Returned by `detect().reidentifyText()`. + +| Field | Type | Description | +|---|---|---| +| `processedText` | `string` | The re-identified text. | + +### `DeidentifyFileResponse` + +Returned by `detect().deidentifyFile()` and `detect().getDetectRun()`. All fields are optional — populated based on file type and processing status. When processing exceeds `setWaitTime`, only `runId` and `status` are set; poll with `getDetectRun`. + +| Field | Type | Description | +|---|---|---| +| `fileBase64` | `string \| undefined` | The processed file as a base64 string. | +| `file` | `File \| undefined` | The processed `File` object. | +| `type` | `string \| undefined` | MIME type of the processed file. | +| `wordCount` | `number \| undefined` | Word count (text-bearing files). | +| `charCount` | `number \| undefined` | Character count (text-bearing files). | +| `pageCount` | `number \| undefined` | Page count (PDF/document files). | +| `slideCount` | `number \| undefined` | Slide count (presentation files). | +| `entities` | `Array<{file: string; extension: string}>` | Detected entity files. Defaults to `[]`. | +| `runId` | `string \| undefined` | Run identifier; pass to `getDetectRun` to poll. | +| `status` | `string \| undefined` | Processing status (`IN_PROGRESS`, `SUCCESS`, `FAILED`). | +| `errors` | `SkyflowRecordError[] \| null` | See note above. | + +### `SkyflowRecordError` + +The shape of each entry in a response's `errors` array. + +| Field | Type | Description | +|---|---|---| +| `error` | `string` | Error description. | +| `requestId` | `string \| null` | Server-side `x-request-id` header value. | +| `httpCode` | `string \| number \| null` | HTTP status code for this record. | +| `requestIndex` | `number \| null` | Index of the failed record in the input array. | +| `token` | `string \| null` | Token (present on detokenize errors only). | + +--- + +## Enums + +All enums are importable from `'skyflow-node'`. + +### `Env` + +Deployment environment. + +| Value | Vault host | +|---|---| +| `Env.PROD` | `vault.skyflowapis.com` (default) | +| `Env.SANDBOX` | `vault.skyflowapis-preview.com` | +| `Env.DEV` | `vault.skyflowapis.dev` | +| `Env.STAGE` | `vault.skyflowapis.tech` | + +### `LogLevel` + +`DEBUG` < `INFO` < `WARN` < `ERROR` < `OFF`. Default is `ERROR`. See [Logging](../README.md#logging). + +### `RedactionType` + +Controls how retrieved data is displayed. + +| Value | Description | +|---|---| +| `RedactionType.DEFAULT` | Vault-configured default. | +| `RedactionType.PLAIN_TEXT` | Full, unmasked value. | +| `RedactionType.MASKED` | Partially obscured. | +| `RedactionType.REDACTED` | Fully removed. | + +### `TokenMode` + +BYOT mode for `InsertOptions` and `UpdateOptions`. + +| Value | Description | +|---|---| +| `TokenMode.DISABLE` | Vault generates tokens (default). | +| `TokenMode.ENABLE` | Caller-supplied tokens accepted as-is. | +| `TokenMode.ENABLE_STRICT` | Caller-supplied tokens validated before accepting. | + +### `TokenType` + +Token format used in `TokenFormat.setDefault()`. + +| Value | Description | +|---|---| +| `TokenType.VAULT_TOKEN` | Standard vault token. | +| `TokenType.ENTITY_UNIQUE_COUNTER` | Entity-unique counter token. | +| `TokenType.ENTITY_ONLY` | Entity label only (no token value). | + +### `OrderByEnum` + +Sort order for `GetOptions.setOrderBy()`. + +| Value | Description | +|---|---| +| `OrderByEnum.ASCENDING` | Ascending order. | +| `OrderByEnum.DESCENDING` | Descending order. | +| `OrderByEnum.NONE` | No explicit sort (server default). | + +### `RequestMethod` + +HTTP method for `InvokeConnectionRequest`. + +Values: `GET`, `POST`, `PUT`, `PATCH`. + +### `MaskingMethod` + +Image masking method for `DeidentifyFileOptions.setMaskingMethod()`. + +Values: `Blackbox`, `Blur`. + +### `DetectOutputTranscription` + +Audio transcription format for `DeidentifyFileOptions.setOutputTranscription()`. + +Values: `DIARIZED_TRANSCRIPTION`, `MEDICAL_DIARIZED_TRANSCRIPTION`, `MEDICAL_TRANSCRIPTION`, `TRANSCRIPTION`, `PLAINTEXT_TRANSCRIPTION`. + +### `DetectEntities` + +Entity types Skyflow Detect can identify — e.g. `SSN`, `CREDIT_CARD`, `NAME`, `DOB`, `PHONE_NUMBER`, `EMAIL`, `ACCOUNT_NUMBER`, and more. Import from `'skyflow-node'`. + +--- + +## Detect helper classes + +All importable from `'skyflow-node'`. + +### `TokenFormat` + +Controls the token representation per entity type in de-identification. Pass to `DeidentifyTextOptions.setTokenFormat()` or `DeidentifyFileOptions.setTokenFormat()`. + +| Setter | Type | Description | +|---|---|---| +| `setDefault(type)` | `TokenType` | Default token format for all detected entities. | +| `setVaultToken(entities)` | `DetectEntities[]` | Use vault tokens for these specific entity types. | +| `setEntityUniqueCounter(entities)` | `DetectEntities[]` | Use entity-unique counter tokens for these types. | +| `setEntityOnly(entities)` | `DetectEntities[]` | Use entity-only (no token) for these types. | + +### `Transformations` + +Specifies custom transformations applied to detected entities during de-identification. Pass to `DeidentifyTextOptions.setTransformations()`. + +| Setter | Type | Description | +|---|---|---| +| `setShiftDays(config)` | `{ max: number; min: number; entities: DetectEntities[] }` | Shift date entities by a random number of days within `[min, max]`. | + +### `Bleep` + +Audio bleep tone configuration. Pass to `DeidentifyFileOptions.setBleep()`. + +| Setter | Type | Description | +|---|---|---| +| `setGain(value)` | `number` | Volume of the bleep tone (0.0 – 1.0). | +| `setFrequency(hz)` | `number` | Frequency in hertz. | +| `setStartPadding(seconds)` | `number` | Silence padding before the bleep. | +| `setStopPadding(seconds)` | `number` | Silence padding after the bleep. | + +### `IndexRange` + +Character position range within text. Used in `DeidentifyTextResponse.entities[].textIndex` and `.processedIndex`. + +| Field | Type | Description | +|---|---|---| +| `start` | `number \| undefined` | Start offset. | +| `end` | `number \| undefined` | End offset. | + +--- + +## Service account functions + +All importable from `'skyflow-node'`. See [Authentication & authorization](../README.md#authentication--authorization) for full usage of `generateBearerToken`, `generateBearerTokenFromCreds`, and `generateSignedDataTokens`. + +### `isExpired(token)` + +Returns `true` if the given JWT bearer token is expired. Use to cache tokens and only regenerate when needed. + +```ts +import { generateBearerToken, isExpired } from 'skyflow-node'; + +if (!cachedToken || isExpired(cachedToken)) { + const { accessToken } = await generateBearerToken('path/to/credentials.json'); + cachedToken = accessToken; +} +``` + +### `generateSignedDataTokensFromCreds(credentialsString, options)` + +The credentials-string counterpart to `generateSignedDataTokens(filepath, options)`. Accepts a JSON credentials string instead of a file path. `options` is the same `SignedDataTokensOptions` type. + +```ts +import { generateSignedDataTokensFromCreds } from 'skyflow-node'; + +const response = await generateSignedDataTokensFromCreds( + process.env.SKYFLOW_CREDENTIALS!, + { + dataTokens: ['dataToken1', 'dataToken2'], + timeToLive: 90, + ctx: 'user_12345', + } +); +``` + +### `BearerTokenOptions` + +```ts +type BearerTokenOptions = { + roleIds?: string[]; // Scope to specific service-account roles + ctx?: string | Record; // Context embedded in the token + logLevel?: LogLevel; // Override log level for this call + tokenUri?: string; // Override the token endpoint URL +}; +``` + +### `SignedDataTokensOptions` + +```ts +type SignedDataTokensOptions = { + dataTokens: string[]; // Data tokens to sign (required) + timeToLive?: number; // Seconds until expiry (default 60) + ctx?: string | Record; // Context embedded in the token + logLevel?: LogLevel; + tokenUri?: string; +}; +``` + +### `GenerateTokenOptions` + +```ts +type GenerateTokenOptions = { + logLevel?: LogLevel; +}; +``` diff --git a/samples/README.md b/samples/README.md index 80cc0efa..90f49e8a 100644 --- a/samples/README.md +++ b/samples/README.md @@ -64,8 +64,8 @@ Sample files are organized by API type: **Vault API samples** ([`vault-api/`](vault-api/)): - [`insert-records.ts`](vault-api/insert-records.ts) - Insert data and get tokens -- [`insert-continue-on-error.ts`](vault-api/insert-continue-on-error.ts) - Bulk insert with error handling -- [`insert-byot.ts`](vault-api/insert-byot.ts) - Upsert operations +- [`insert-continue-on-error.ts`](vault-api/insert-continue-on-error.ts) - Bulk insert with per-record error handling +- [`insert-byot.ts`](vault-api/insert-byot.ts) - Insert with bring-your-own tokens (BYOT) - [`get-records.ts`](vault-api/get-records.ts) - Retrieve records by Skyflow IDs - [`get-column-values.ts`](vault-api/get-column-values.ts) - Query by column values - [`detokenzie-records.ts`](vault-api/detokenzie-records.ts) - Convert tokens to values @@ -73,14 +73,19 @@ Sample files are organized by API type: - [`update-record.ts`](vault-api/update-record.ts) - Update existing records - [`delete-records.ts`](vault-api/delete-records.ts) - Delete records by ID - [`query-records.ts`](vault-api/query-records.ts) - SQL query operations -- [`file-upload.ts`](vault-api/file-upload.ts) - Upload files to vault +- [`file-upload.ts`](vault-api/file-upload.ts) - Upload files to vault (file path, base64, or File object) - [`invoke-connection.ts`](vault-api/invoke-connection.ts) - Call external integrations +- [`client-operations.ts`](vault-api/client-operations.ts) - Runtime vault and connection management +- [`credentials-options.ts`](vault-api/credentials-options.ts) - All credential types and multi-vault setup +- [`data-residency.ts`](vault-api/data-residency.ts) - Multi-region vault configuration **Detect API samples** ([`detect-api/`](detect-api/)): - [`deidentify-text.ts`](detect-api/deidentify-text.ts) - Anonymize text data -- [`deidentify-file.ts`](detect-api/deidentify-file.ts) - Anonymize file data -- [`reidentify-text.ts`](detect-api/reidentify-text.ts) - Restore original values -- [`get-detect-run.ts`](detect-api/get-detect-run.ts) - Check operation status +- [`deidentify-file.ts`](detect-api/deidentify-file.ts) - Anonymize a file using a File object +- [`deidentify-file-with-filepath.ts`](detect-api/deidentify-file-with-filepath.ts) - Anonymize a file using a file path +- [`deidentify-file-with-filepath-async.ts`](detect-api/deidentify-file-with-filepath-async.ts) - Anonymize a file asynchronously (poll for result) +- [`reidentify-text.ts`](detect-api/reidentify-text.ts) - Restore original values from de-identified text +- [`get-detect-run.ts`](detect-api/get-detect-run.ts) - Check the status of an async de-identify operation **Service Account samples** ([`service-account/`](service-account/)): - [`token-generation-example.ts`](service-account/token-generation-example.ts) - Generate bearer tokens diff --git a/samples/detect-api/deidentify-file-with-filepath-async.ts b/samples/detect-api/deidentify-file-with-filepath-async.ts index 58dfc06d..2841b57e 100644 --- a/samples/detect-api/deidentify-file-with-filepath-async.ts +++ b/samples/detect-api/deidentify-file-with-filepath-async.ts @@ -131,7 +131,7 @@ import { // Comprehensive Error Handling if (error instanceof SkyflowError) { console.error('Skyflow Specific Error:', { - code: error.error?.http_code, + code: error.error?.httpCode, message: error.message, details: error.error?.details, }); diff --git a/samples/detect-api/deidentify-text.ts b/samples/detect-api/deidentify-text.ts index d1d641e2..dcc09737 100644 --- a/samples/detect-api/deidentify-text.ts +++ b/samples/detect-api/deidentify-text.ts @@ -61,15 +61,28 @@ async function performDeidentifyText() { // setEntities: Specify which entities to deidentify options.setEntities([DetectEntities.CREDIT_CARD, DetectEntities.SSN]); - // setAllowRegexList: Allowlist regex patterns (entities matching these will not be deidentified) - // optionsText.setAllowRegexList(['']); + // Allowlist: regex patterns whose matches will NOT be de-identified + // options.setAllowRegexList(['']); - // setRestrictRegexList: Restrict de-identification to entities matching these regex patterns - // optionsText.setRestrictRegexList(['']); + // Denylist: restrict de-identification to only entities matching these patterns + // options.setRestrictRegexList(['']); - // setTokenFormat: Specify the token format for deidentified entities + // setTokenFormat: choose how de-identified entities are represented as tokens const tokenFormat = new TokenFormat(); + + // Apply one token type as the default for all entity types tokenFormat.setDefault(TokenType.VAULT_TOKEN); + + // --- Per-entity-type token format overrides (optional) --- + // Use vault tokens only for specific entity types + // tokenFormat.setVaultToken([DetectEntities.SSN, DetectEntities.CREDIT_CARD]); + + // Use an entity-unique counter token for specific entity types + // tokenFormat.setEntityUniqueCounter([DetectEntities.NAME]); + + // Use entity-only (no token) for specific entity types + // tokenFormat.setEntityOnly([DetectEntities.DATE_OF_BIRTH]); + options.setTokenFormat(tokenFormat); // setTransformations: Specify custom transformations for entities diff --git a/samples/vault-api/credentials-options.ts b/samples/vault-api/credentials-options.ts index 0a316962..35ccbc66 100644 --- a/samples/vault-api/credentials-options.ts +++ b/samples/vault-api/credentials-options.ts @@ -70,9 +70,9 @@ async function performSecureDataDeletion() { // Step 4: Prepare Delete Request for Primary Vault const primaryDeleteIds: Array = [ - 'skyflow_id1', - 'skyflow_id2', - 'skyflow_id3', + '', + '', + '', ]; const primaryTableName: string = ''; // Replace with actual table name @@ -91,9 +91,9 @@ async function performSecureDataDeletion() { // Step 5: Prepare Delete Request for Secondary Vault const secondaryDeleteIds: Array = [ - 'skyflow_id4', - 'skyflow_id5', - 'skyflow_id6', + '', + '', + '', ]; const secondaryTableName: string = ''; // Replace with actual table name diff --git a/samples/vault-api/delete-records.ts b/samples/vault-api/delete-records.ts index 58d299e3..0b29ee83 100644 --- a/samples/vault-api/delete-records.ts +++ b/samples/vault-api/delete-records.ts @@ -44,7 +44,7 @@ async function performDeletion() { const skyflowClient: Skyflow = new Skyflow(skyflowConfig); // Step 4: Prepare Delete Data - const deleteIds: Array = ['skyflow_id1', 'skyflow_id2', 'skyflow_id3']; // Record IDs to delete + const deleteIds: Array = ['', '', '']; // Record IDs to delete const tableName: string = 'sensitive_data_table'; // Table name in the vault schema // Create Delete Request diff --git a/samples/vault-api/detokenzie-records.ts b/samples/vault-api/detokenzie-records.ts index debf346b..8dd32a3d 100644 --- a/samples/vault-api/detokenzie-records.ts +++ b/samples/vault-api/detokenzie-records.ts @@ -27,7 +27,7 @@ async function performDetokenization() { try { // Step 1: Configure Credentials const credentials: Credentials = { - token: 'token', // Bearer token for authentication + token: '', }; // Step 2: Configure Vault diff --git a/samples/vault-api/file-upload.ts b/samples/vault-api/file-upload.ts index 9fe9dfc9..3df082e6 100644 --- a/samples/vault-api/file-upload.ts +++ b/samples/vault-api/file-upload.ts @@ -15,63 +15,69 @@ import * as fs from 'fs'; /** * Skyflow File Upload Example - * - * This example demonstrates how to: - * 1. Configure credentials - * 2. Set up vault configuration - * 3. Create a file upload request - * 4. Handle response and errors - * - * Note: File upload requires Node version 20 or above. + * + * This example demonstrates how to upload a file to a Skyflow vault using three + * different file source options — pick exactly one per upload: + * Option A: setFilePath() — read a file from disk by path (simplest for server-side Node.js) + * Option B: setBase64() — supply file content as a base64-encoded string + * Option C: setFileObject() — supply an in-memory File object directly + * + * Note: File upload requires Node.js v20 or above. */ async function performFileUpload() { try { - // Step 1: Configure Credentials + // Step 1: Configure credentials const credentials: Credentials = { - path: 'path-to-credentials-json', // Path to credentials file + path: '', }; - // Step 2: Configure Vault + // Step 2: Configure vault const primaryVaultConfig: VaultConfig = { - vaultId: 'your-vault-id', // Unique vault identifier - clusterId: 'your-cluster-id', // From vault URL - env: Env.PROD, // Deployment environment - credentials: credentials // Authentication method + vaultId: '', + clusterId: '', + env: Env.PROD, + credentials: credentials, }; - // Step 3: Configure Skyflow Client + // Step 3: Initialize Skyflow client const skyflowConfig: SkyflowConfig = { vaultConfigs: [primaryVaultConfig], - logLevel: LogLevel.ERROR, // Logging verbosity + logLevel: LogLevel.ERROR, }; - - // Initialize Skyflow Client const skyflowClient: Skyflow = new Skyflow(skyflowConfig); - // Step 4: Prepare File Upload Data - const tableName: string = 'table-name'; // Table name - const skyflowId: string = 'skyflow-id'; // Skyflow ID of the record - const columnName: string = 'column-name'; // Column name to store file - const filePath: string = 'file-path'; // Path to the file for upload - - // Step 5: Create File Upload Request (SK-2812: 2-arg constructor, skyflowId moved to options) + // Step 4: Create a file upload request (table + column only; Skyflow ID goes in options) const uploadReq: FileUploadRequest = new FileUploadRequest( - tableName, - columnName, + '', + '', ); - // Step 6: Configure FileUpload Options + // Step 5: Configure upload options — set Skyflow ID, then choose one file source + const uploadOptions: FileUploadOptions = new FileUploadOptions(); - uploadOptions.setSkyflowId(skyflowId); // SK-2812: new API - uploadOptions.setFilePath(filePath); - // Step 6: Perform File Upload + // Required: the Skyflow ID of the record to attach this file to + uploadOptions.setSkyflowId(''); + + // --- Option A: File path (SDK reads the file from disk) --- + uploadOptions.setFilePath(''); + + // --- Option B: Base64-encoded content --- + // const base64Content = fs.readFileSync('').toString('base64'); + // uploadOptions.setBase64(base64Content); + // uploadOptions.setFileName('document.pdf'); // required when using setBase64 + + // --- Option C: In-memory File object --- + // const buffer = fs.readFileSync(''); + // uploadOptions.setFileObject(new File([buffer], 'document.pdf')); + + // Step 6: Upload the file const response: FileUploadResponse = await skyflowClient .vault(primaryVaultConfig.vaultId) .uploadFile(uploadReq, uploadOptions); - // Handle Successful Response console.log('File upload successful:', response); + console.log('Skyflow ID:', response.skyflowId); } catch (error) { // Comprehensive Error Handling diff --git a/samples/vault-api/get-column-values.ts b/samples/vault-api/get-column-values.ts index c4e6016a..6ac545fc 100644 --- a/samples/vault-api/get-column-values.ts +++ b/samples/vault-api/get-column-values.ts @@ -1,13 +1,15 @@ -import { - Env, - GetOptions, - LogLevel, - Skyflow, - GetColumnRequest, - Credentials, - SkyflowConfig, - VaultConfig, - SkyflowError, +import { + Env, + GetOptions, + LogLevel, + OrderByEnum, + RedactionType, + Skyflow, + GetColumnRequest, + Credentials, + SkyflowConfig, + VaultConfig, + SkyflowError, GetResponse, GetResponseData } from 'skyflow-node'; @@ -62,7 +64,24 @@ async function performSecureColumnRetrieval() { // Step 6: Configure Get Options const getOptions: GetOptions = new GetOptions(); - getOptions.setReturnTokens(true); // Optional: Get tokens for retrieved data + + // Return tokens instead of plain-text values (default: false) + getOptions.setReturnTokens(true); + + // Control how sensitive data is redacted in the response + // getOptions.setRedactionType(RedactionType.PLAIN_TEXT); + + // Limit the response to specific field names + // getOptions.setFields(['card_number', 'cardholder_name']); + + // Pagination: skip the first N records + // getOptions.setOffset('10'); + + // Pagination: return at most N records + // getOptions.setLimit('20'); + + // Sort order for returned records + // getOptions.setOrderBy(OrderByEnum.ASCENDING); // Step 7: Perform Secure Retrieval const response: GetResponse = await skyflowClient diff --git a/samples/vault-api/get-records.ts b/samples/vault-api/get-records.ts index 9e0a8c8d..dc6697f8 100644 --- a/samples/vault-api/get-records.ts +++ b/samples/vault-api/get-records.ts @@ -1,13 +1,15 @@ -import { - Credentials, - Env, - GetOptions, - GetRequest, - LogLevel, - Skyflow, - VaultConfig, - SkyflowConfig, - SkyflowError, +import { + Credentials, + Env, + GetOptions, + GetRequest, + LogLevel, + OrderByEnum, + RedactionType, + Skyflow, + VaultConfig, + SkyflowConfig, + SkyflowError, GetResponse, GetResponseData } from 'skyflow-node'; @@ -59,11 +61,33 @@ async function performSecureDataRetrieval() { // Step 6: Configure Get Options const getOptions: GetOptions = new GetOptions(); + + // Return tokens instead of plain-text values (default: false) getOptions.setReturnTokens(true); - // NEW API (SK-2812): setDownloadUrl (camelCase) - getOptions.setDownloadUrl(false); + // Control how sensitive data is redacted in the response + // getOptions.setRedactionType(RedactionType.PLAIN_TEXT); + + // Limit the response to specific field names + // getOptions.setFields(['card_number', 'cardholder_name']); + + // Pagination: skip the first N records + // getOptions.setOffset('10'); + + // Pagination: return at most N records + // getOptions.setLimit('20'); + + // Sort order for returned records + // getOptions.setOrderBy(OrderByEnum.ASCENDING); + + // --- Alternative: query by column value instead of Skyflow IDs --- + // (use with a GetRequest that has no IDs; setColumnName + setColumnValues together) + // getOptions.setColumnName('card_number'); + // getOptions.setColumnValues(['4111111111111112']); + // Return a pre-signed download URL for file fields + // getOptions.setDownloadUrl(true); + // DEPRECATED API — still works, logs WARN: setDownloadURL (uppercase URL) // getOptions.setDownloadURL(false); diff --git a/samples/vault-api/insert-byot.ts b/samples/vault-api/insert-byot.ts index 32741701..020099d6 100644 --- a/samples/vault-api/insert-byot.ts +++ b/samples/vault-api/insert-byot.ts @@ -26,7 +26,7 @@ async function performSecureDataInsertionWithBYOT() { try { // Step 1: Configure Credentials const credentials: Credentials = { - token: 'bearer', // Bearer token authentication + token: '', }; // Step 2: Configure Vault @@ -48,7 +48,7 @@ async function performSecureDataInsertionWithBYOT() { // Step 4: Prepare Insertion Data const insertData: Record[] = [ - { card_number: 'skyflow_id1', card_cvv: 'skyflow_id2' }, + { card_number: '', card_cvv: '' }, ]; const tableName: string = 'your-table-name'; diff --git a/samples/vault-api/insert-records.ts b/samples/vault-api/insert-records.ts index 9af76183..98923f64 100644 --- a/samples/vault-api/insert-records.ts +++ b/samples/vault-api/insert-records.ts @@ -60,8 +60,19 @@ async function performSecureDataInsertion() { // Step 6: Configure Insertion Options const insertOptions: InsertOptions = new InsertOptions(); - insertOptions.setReturnTokens(true); // Optional: Get tokens for inserted data - // insertOptions.setContinueOnError(true); // Optional: Continue on partial errors + + // Return tokens for inserted fields (default: false) + insertOptions.setReturnTokens(true); + + // Continue inserting remaining records even when some fail (batch mode) + // insertOptions.setContinueOnError(true); + + // Upsert: update the record if a matching value exists in the specified column + // (the column must have the `unique` constraint in the vault schema) + // insertOptions.setUpsertColumn('card_number'); + + // Homogeneous insert: treat all records as the same schema for a bulk insert + // insertOptions.setHomogeneous(true); // Step 7: Perform Secure Insertion const response: InsertResponse = await skyflowClient diff --git a/samples/vault-api/update-record.ts b/samples/vault-api/update-record.ts index a7c9c84f..8230bace 100644 --- a/samples/vault-api/update-record.ts +++ b/samples/vault-api/update-record.ts @@ -1,14 +1,15 @@ -import { - Credentials, - Env, - LogLevel, - Skyflow, - VaultConfig, - SkyflowConfig, - UpdateRequest, - UpdateOptions, - UpdateResponse, - SkyflowError +import { + Credentials, + Env, + LogLevel, + Skyflow, + VaultConfig, + SkyflowConfig, + UpdateRequest, + UpdateOptions, + UpdateResponse, + TokenMode, + SkyflowError } from 'skyflow-node'; /** @@ -46,7 +47,6 @@ async function performSecureDataUpdate() { const skyflowClient: Skyflow = new Skyflow(skyflowConfig); // Step 4: Prepare Update Data - // SK-2812: data object uses camelCase skyflowId (was skyflow_id) const updateData: Record = { skyflowId: 'your-skyflow-id', // Skyflow ID of the record to update card_number: '1234567890123456' // Updated sensitive data @@ -60,7 +60,19 @@ async function performSecureDataUpdate() { // Step 6: Configure Update Options const updateOptions: UpdateOptions = new UpdateOptions(); - updateOptions.setReturnTokens(true); // Optional: Get tokens for updated data + + // Return tokens for the updated fields (default: false — returns skyflowId only) + updateOptions.setReturnTokens(true); + + // --- BYOT (Bring Your Own Token) options --- + // Provide pre-existing tokens to associate with the updated fields + // updateOptions.setTokens({ card_number: '' }); + + // Control tokenization mode when using BYOT: + // TokenMode.DISABLE — vault generates tokens (default) + // TokenMode.ENABLE — use provided tokens as-is + // TokenMode.ENABLE_STRICT — validate provided tokens before accepting + // updateOptions.setTokenMode(TokenMode.ENABLE); // Step 7: Perform Secure Update const response: UpdateResponse = await skyflowClient