From c178f511d8c5a745334c897239859b40d5fd4120 Mon Sep 17 00:00:00 2001 From: Joseph McCarron Date: Thu, 13 Nov 2025 23:41:46 -0600 Subject: [PATCH 01/15] feat: add spellcheck script and cspell dependency to package.json docs: update README.md for clarity and consistency in sample instructions fix: correct variable name in insert-continue-on-error.ts for accurate data insertion chore: add cspell configuration file for spell checking chore: add prettier configuration files to standardize code formatting refactor: move migration guide from V1 to V2 into dedicated file --- .cspell.json | 50 + .prettierignore | 3 + .prettierrc | 1 + CHANGELOG.md | 114 +- MIGRATE_TO_v2.md | 258 ++++ README.md | 380 ++---- package-lock.json | 1133 ++++++++++++++++- package.json | 6 +- samples/README.md | 115 +- .../deidentify-file-with-filepath.ts | 10 +- samples/detect-api/deidentify-file.ts | 10 +- samples/detect-api/deidentify-text.ts | 4 +- samples/detect-api/reidentify-text.ts | 4 +- samples/vault-api/insert-continue-on-error.ts | 2 +- 14 files changed, 1606 insertions(+), 484 deletions(-) create mode 100644 .cspell.json create mode 100644 .prettierignore create mode 100644 .prettierrc create mode 100644 MIGRATE_TO_v2.md diff --git a/.cspell.json b/.cspell.json new file mode 100644 index 00000000..a1278941 --- /dev/null +++ b/.cspell.json @@ -0,0 +1,50 @@ +{ + "version": "0.2", + "language": "en", + "words": [ + "Skyflow", + "de-identify", + "re-identify", + "deidentify", + "reidentify", + "De-identify", + "Re-identify", + "Deidentify", + "Reidentify", + "detokenize", + "skyflow", + "upserting", + "de-identified", + "DEIDENTIFIED", + "de-identification", + "de-identifying", + "re-identified", + "Re-identified", + "re-identification", + "Blackbox", + "binlookup", + "BYOT", + "ILIKE", + "Creds", + "QWPA", + "Ijoi", + "XVCJ" + ], + "ignorePaths": [ + "node_modules/**", + "dist/**", + "build/**", + "coverage/**", + "*.log", + "package-lock.json", + ".git/**", + "src/_generated_/**", + "src/ _generated_/**", + "test/vault/controller/detect.test.js" + ], + "ignoreRegExpList": [ + "/\\b[A-Z0-9]{20,}\\b/g", + "/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi", + "/\\b[A-Za-z0-9_]{7,}\\b(?=])/g" + ] +} diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..1b8ac889 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,3 @@ +# Ignore artifacts: +build +coverage diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/.prettierrc @@ -0,0 +1 @@ +{} diff --git a/CHANGELOG.md b/CHANGELOG.md index 75d09b2a..0d40eb52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,115 +1,5 @@ # Changelog -All notable changes to this project will be documented in this file. +All notable changes to this project will be documented as part of the release notes. -## [1.13.1] - 2024-01-25 -### Fixed -- Fixed multiple column names error with unique column values in `get` interface. - -## [1.13.0] - 2024-01-12 -### Added -- Removed get call from batch Insert. -- Continue on error support for batch Insert. - -## [1.12.0] - 2023-10-20 -### Added -- `tokens` option in `get` interface. -- `encodeURI` option in `get` interface. - -## [1.11.0] - 2023-07-19 -### Added -- Added new `delete` interface. -## [1.10.0] - 2023-06-08 -### Added -- `redaction` in detokenize interface. -### Changed -- Removed grace period logic for bearer token generation. -## [1.9.3] - 2023-03-17 -### Changed -- Removed grace period logic for bearer token generation. - -## [1.9.2] - 2023-03-01 -### Fixed -- Fixed grace period of token caching - -## [1.9.1] - 2023-01-11 -### Changed -- Upgraded jsonwebtoken from 8.5.1 to 9.0.0 - -## [1.9.0] - 2022-12-27 -### Added -- Added new `get` interface. -- Deprecated `getById` interface. - -## [1.8.0] - 2022-12-14 -### Added -- Added `update` interface. -- Added support for Get by Unique column values in `getById` interface. - -## [1.7.1] - 2022-11-24 -### Changed -- Rename context to 'ctx' in bearer token options. - -## [1.7.0] - 2022-11-22 - -### Added -- Upsert support for `insert` method -- Added support to generate skyflow bearer tokens with context. -- Added support to generate scoped skyflow bearer tokens. -- Added support to generate signed data tokens. - -## [1.6.1] - 2022-06-28 - -### Added -- Copyright header to all files -- Security email in README -## [1.6.0] - 2022-04-13 - -### Added -- support for application/x-www-form-urlencoded and multipart/form-data content-type's in connections. - -## [1.5.1] - 2022-03-29 - -### Changed -- Added validation to token from TokenProvider - -### Fixed -- requestHeaders are not case insensitive - -## [1.5.0] - 2022-03-15 - -### Changed -- deprecated `isValid` in favor of `isExpired` - -## [1.4.0] - 2022-02-24 - -## Added -- Request ID in error logs and error responses for API Errors -- `isValid` method for validating Service Account bearer token - -## [1.3.0] - 2022-01-11 - -### Added -- Logging functionality -- `setLogLevel` function for setting the package-level LogLevel -- `generateBearerTokenFromCreds` function which takes credentials as string - -### Changed -- Renamed and deprecated `generateToken` in favor of `generateBearerToken` -- Make `vaultID` and `vaultURL` optional in `Client` constructor - - -## [1.2.0] - 2021-11-10 - -### Added - -- insert vault API -- detokenize vault API -- getById vault API -- invokeConnection - -## [1.1.1] - 2021-10-20 - -### Added - -- Service Account Token generation +See [Github](https://github.com/skyflowapi/skyflow-node/releases) or [npm](https://www.npmjs.com/package/skyflow-node?activeTab=versions) for more details on each released version. diff --git a/MIGRATE_TO_v2.md b/MIGRATE_TO_v2.md new file mode 100644 index 00000000..5371874f --- /dev/null +++ b/MIGRATE_TO_v2.md @@ -0,0 +1,258 @@ +# Migrate from V1 to V2 + +This guide outlines the steps required to migrate the Skyflow Node SDK from version 1 (V1) to version 2 (V2). + +## Authentication + +In V2, multiple authentication options have been introduced. You can now provide credentials in the following ways: + +- **API Key** +- **Environment Variable** (`SKYFLOW_CREDENTIALS`) (**Recommended**) +- **Path to Credentials JSON File** +- **Stringified JSON of Credentials** +- **Bearer Token** + +These options allow you to choose the authentication method that best suits your use case. + +### v1 Authentication: Pass the auth function below as a parameter to the getBearerToken key + +```javascript +// sample function to retrieve a bearer token from an environment variable +// customize this according to your environment and security posture +const auth = function () { + return new Promise((resolve, reject) => { + resolve(process.env.VAULT_BEARER_TOKEN); + }); +}; +``` + +#### v2 Authentication: Credentials object + +```javascript +{ + apiKey: "" +} +``` + +// Option 2: Environment Variables (Recommended) +// Set SKYFLOW_CREDENTIALS in your environment + +// Option 3: Credentials File + +```js +const credentials = { path: "" }; // Replace with the path to credentials file +``` + +// Option 4: Stringified JSON + +```js +const credentials = { + credentialsString: JSON.stringify(process.env.SKYFLOW_CREDENTIALS), +}; +``` + +// Option 5: Bearer Token + +```js +const credentials = { token: "" }; +``` + +## Initializing the client + +V2 introduces TypeScript support and multi-vault support, allowing you to configure multiple vaults during client initialization. + +In V2, the log level is tied to each individual client instance. + +During client initialization, you can pass the following parameters: + +- **`vaultId`** and **`clusterId`**: These values are derived from the vault ID & vault URL. +- **`env`**: Specify the environment (e.g., SANDBOX or PROD). +- **`credentials`**: The necessary authentication credentials. + +#### V1 (Old) + +```javascript +// Initialize the Skyflow Vault client + +const vault = Skyflow.init({ + // Id of the vault that the client should connect to. + vaultID: "string", + // URL of the vault that the client should connect to. + + vaultURL: "string", + // Helper function generates a Skyflow bearer token. + getBearerToken: auth, +}); +``` + +#### V2 (New) + +```javascript +// Step 1: Configure Bearer Token Credentials +const credentials: Credentials = { apiKey: '' }; + +// Step 2: Configure Vault +const primaryVaultConfig: VaultConfig = { + vaultId: '', // Primary vault + clusterId: '', // ID from your vault URL e.g., https://{clusterId}.vault.skyflowapis.com + env: Env.PROD, // Deployment environment (PROD by default) + credentials: credentials, // Authentication method +}; + +// Step 3: Configure Skyflow Client +const skyflowConfig: SkyflowConfig = { + vaultConfigs: [primaryVaultConfig], + skyflowCredentials: credentials, // Skyflow credentials will be used if no individual credentials are passed + logLevel: LogLevel.INFO, // Recommended to use LogLevel.ERROR in production environment. +}; + +// Initialize Skyflow Client +const skyflowClient: Skyflow = new Skyflow(skyflowConfig); +``` + +### Key Changes: + +- `vaultURL` replaced with `clusterId`. +- Added environment specification (`env`). +- Instance-specific log levels. +- TypeScript support with type definitions + +--- + +### Request & Response Structure + +In V2, with the introduction of TypeScript support, you can now pass an **InsertRequest** of type **InsertRequest**. This request need + +- **`tableName`**: The name of the table. +- **`insertData`**: An array of objects containing the data to be inserted + The response will be of type InsertResponse, which contains insertedFields and errors. + +#### V1 (Old) - Request Building + +```javascript +const result = skyflow.insert({ + records: [ + { + fields: { + card_number: "411111111111111", + expiry_date: "11/22", + fullname: "firstNameTest", + }, + table: "cards", + }, + ], +}); +``` + +#### V2 (New) - Request Building + +```typescript +// Prepare Insertion Data +const insertData: Record[] = [ + { card_number: "4111111111111112" }, // Example sensitive data +]; + +// Create Insert Request +const insertReq: InsertRequest = new InsertRequest( + "", // Replace with your actual table name + insertData, +); + +// Perform Secure Insertion +const response: InsertResponse = await skyflowClient + .vault("") + .insert(insertReq); +``` + +#### V1 (Old) - Response Structure + +```json +{ + "records": [ + { + "table": "cards", + "fields": { + "card_number": "f37186-e7e2-466f-91e5-48e2bcbc1", + "expiry_date": "1989cb56-63a-4482-adf-1f74cd1a5" + } + } + ] +} +``` + +#### V2 (New) - Response Structure + +```javascript +InsertResponse( + insertedFields : [ + { + skyflowId : "ID1", + "": "", // removed tokens key + "": "" + }, + { + skyflowId : "ID2", + "": "", + "": "" + } + ], + errors: null +); +``` + +--- + +### Request Options + +In V2, we have introduced inbuilt **InsertOptions** classes. These allow you to use setters to configure options instead of passing a plain object with key-value pairs. + +#### V1 (Old) + +```javascript +const options = { + tokens: true, + // other options +}; +``` + +#### V2 (New) + +```javascript +const insertOptions: InsertOptions = new InsertOptions(); +insertOptions.setReturnTokens(true); // Optional: Get tokens for inserted data +insertOptions.setContinueOnError(true); // Optional: Continue on partial errors +``` + +--- + +### Error Structure + +In V2, we have enriched the error details to provide better debugging capabilities. +The error response now includes: + +- **`http_status`**: The HTTP status code. . +- **`grpc_code`**: The gRPC code associated with the error. +- **`details & message`**: A detailed description of the error. +- **`request_ID`**: A unique request identifier for easier debugging. + +#### V1 (Old) - Error Structure + +```javascript +{ + code: string | number, + description: string +} +``` + +#### V2 (New) - Error Structure + +```javascript +{ + http_status?: string | number | null, + grpc_code?: string | number | null, + http_code: string | number | null, + message: string, + request_ID?: string | null, + details?: Array | null, +} +``` diff --git a/README.md b/README.md index dcfae743..bc46aaf5 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Skyflow Node.js SDK -SDK for the Skyflow Data Privacy Vault. +The Skyflow SDK for Node.js, Deno, Bun, and Cloudflare Workers. [![CI](https://img.shields.io/static/v1?label=CI&message=passing&color=green?style=plastic&logo=github)](https://github.com/skyflowapi/skyflow-node/actions) [![GitHub release](https://badge.fury.io/js/skyflow-node.svg)](https://www.npmjs.com/package/skyflow-node) @@ -13,60 +13,85 @@ SDK for the Skyflow Data Privacy Vault. - [Skyflow Node.js SDK](#skyflow-nodejs-sdk) - [Table of contents](#table-of-contents) - [Overview](#overview) - - [Install](#installation) - - [Requirements](#requirements) + - [Install](#install) + - [Requirements](#requirements) - [Import / Require](#import--require) - [Require](#require) - [ES modules](#es-modules) - [All imports](#all-imports) - - [Migrate from v1 to v2](#migrate-from-v1-to-v2) - - [Authentication options](#authentication-options) - - [Initializing the client](#initializing-the-client) - - [Request & response structure](#request--response-structure) - - [Request options](#request-options) - - [Error structure](#error-structure) - [Quickstart](#quickstart) - - [Authenticate](#authenticate) - - [Initialize the client](#initialize-the-client) - - [Insert data into the vault](#insert-data-into-the-vault) - - [Vault](#vault) + - [Authenticate](#authenticate) + - [Initialize the client](#initialize-the-client) - [Insert data into the vault](#insert-data-into-the-vault) + - [Vault](#vault) + - [Insert data into the vault](#insert-data-into-the-vault-1) + - [Construct an insert request](#construct-an-insert-request) + - [Insert call example with `continueOnError` option](#insert-call-example-with-continueonerror-option) - [Detokenize](#detokenize) + - [Construct a detokenize request](#construct-a-detokenize-request) + - [An example of a detokenize call](#an-example-of-a-detokenize-call) + - [An example of a detokenize call with `continueOnError` option:](#an-example-of-a-detokenize-call-with-continueonerror-option) - [Tokenize](#tokenize) + - [Construct a tokenize request](#construct-a-tokenize-request) + - [An example of Tokenize call](#an-example-of-tokenize-call) - [Get](#get) - - [Get by skyflow IDs](#get-by-skyflow-ids) - - [Get tokens](#get-tokens) - - [Get by column name and column values](#get-by-column-name-and-column-values) - - [Redaction types](#redaction-types) + - [Construct a get request](#construct-a-get-request) + - [Get by skyflow IDs](#get-by-skyflow-ids) + - [Get tokens](#get-tokens) + - [An example of get call to retrieve tokens using Skyflow IDs:](#an-example-of-get-call-to-retrieve-tokens-using-skyflow-ids) + - [Get by column name and column values](#get-by-column-name-and-column-values) + - [An example of get call to retrieve data using column name and column values:](#an-example-of-get-call-to-retrieve-data-using-column-name-and-column-values) + - [Redaction Types](#redaction-types) - [Update](#update) + - [Construct an update request](#construct-an-update-request) + - [An example of update call](#an-example-of-update-call) - [Delete](#delete) - - [Invoke Connection](#invoke-a-connection) + - [Construct a delete request](#construct-a-delete-request) + - [An example of delete call](#an-example-of-delete-call) - [Query](#query) + - [Construct a query request](#construct-a-query-request) + - [An example of query call](#an-example-of-query-call) + - [Upload File](#upload-file) + - [An example of file upload call](#an-example-of-file-upload-call) - [Detect](#detect) - [Deidentify Text](#deidentify-text) + - [An example of a deidentify text call](#an-example-of-a-deidentify-text-call) - [Reidentify Text](#reidentify-text) + - [An example of a reidentify text call](#an-example-of-a-reidentify-text-call) - [Deidentify File](#deidentify-file) - - [Get Run](#get-run) + - [An example of a deidentify file](#an-example-of-a-deidentify-file) + - [Get run](#get-run) + - [An example of a get run function](#an-example-of-a-get-run-function) - [Connections](#connections) - - [Invoke a connection](#invoke-a-connection) + - [Invoke a connection](#invoke-a-connection) + - [Construct an invoke connection request](#construct-an-invoke-connection-request) + - [An example of Invoke Connection](#an-example-of-invoke-connection) - [Authenticate with bearer tokens](#authenticate-with-bearer-tokens) - - [Generate a bearer token](#generate-a-bearer-token) - - [Generate bearer tokens with context](#generate-bearer-tokens-with-context) - - [Generate scoped bearer tokens](#generate-scoped-bearer-tokens) - - [Generate signed data tokens](#generate-signed-data-tokens) - - [Bearer token expiry edge case](#bearer-token-expiry-edge-case) + - [Generate a bearer token](#generate-a-bearer-token) + - [Example:](#example) + - [Generate bearer tokens with context](#generate-bearer-tokens-with-context) + - [Example:](#example-1) + - [Generate scoped bearer tokens](#generate-scoped-bearer-tokens) + - [Example:](#example-2) + - [Generate signed data tokens](#generate-signed-data-tokens) + - [Example:](#example-3) + - [Bearer token expiry edge case](#bearer-token-expiry-edge-case) + - [Example:](#example-4) - [Logging](#logging) - - [Reporting a vulnerability](#reporting-a-vulnerability) + - [Reporting a Vulnerability](#reporting-a-vulnerability) -# Overview +## Overview -- Authenticate using a Skyflow service account and generate bearer tokens for secure access. -- Perform Vault API operations such as inserting, retrieving, and tokenizing sensitive data with ease. -- Invoke connections to third-party APIs without directly handling sensitive data, ensuring compliance and data protection. +The Skyflow SDK enables you to connect to your Skyflow Vault(s) to securely handle sensitive data at rest, in-transit, and in-use. + +> [!IMPORTANT] +> This readme covers version 2 of the SDK. +> For version 1 see the [v1.14.2 README](https://github.com/skyflowapi/skyflow-node/tree/1.14.2). +> For more information on how to migrate see [MIGRATE_TO_V2.md](MIGRATE_TO_v2.md). -# Install +## Install -#### Requirements +### Requirements - Node 12.22.12 and above @@ -100,254 +125,6 @@ import { } from 'skyflow-node' ``` -## Migrate from V1 to V2 - -This guide outlines the steps required to migrate the Node SDK from version 1 (V1) to version 2 (V2). - ---- - -### Authentication Options - -In V2, multiple authentication options have been introduced. You can now provide credentials in the following ways: - -- **API Key** -- **Environment Variable** (`SKYFLOW_CREDENTIALS`) (**Recommended**) -- **Path to Credentials JSON File** -- **Stringified JSON of Credentials** -- **Bearer Token** - -These options allow you to choose the authentication method that best suits your use case. - -#### V1 (Old): Passing the auth function below as a parameter to the getBearerToken key. - - -```javascript -// sample function to retrieve a bearer token from an environment variable -// customize this according to your environment and security posture -const auth = function () { - return new Promise((resolve, reject) => { - resolve(process.env.VAULT_BEARER_TOKEN); - }); -}; -``` - -#### V2 (New): Passing one of the following: - -```javascript -// Option 1: API Key (Recommended) -const credentials = { apiKey: "" }; - -// Option 2: Environment Variables (Recommended) -// Set SKYFLOW_CREDENTIALS in your environment - -// Option 3: Credentials File -const credentials = { path: "" }; // Replace with the path to credentials file - - -// Option 4: Stringified JSON -const credentials = { credentialsString: JSON.stringify(process.env.SKYFLOW_CREDENTIALS) }; - -// Option 5: Bearer Token -const credentials = { token: "" }; -``` - -### Notes: -- Use only ONE authentication method. -- API Key or Environment Variables are recommended for production use. -- Secure storage of credentials is essential. -- For overriding behavior and priority order of credentials, please refer to [Initialize the client](#initialize-the-client) section in [Quickstart](#quickstart). - ---- - -### Initializing the client - -V2 introduces TypeScript support and multi-vault support, allowing you to configure multiple vaults during client initialization. - -In V2, the log level is tied to each individual client instance. - -During client initialization, you can pass the following parameters: - -- **`vaultId`** and **`clusterId`**: These values are derived from the vault ID & vault URL. -- **`env`**: Specify the environment (e.g., SANDBOX or PROD). -- **`credentials`**: The necessary authentication credentials. - - -#### V1 (Old) -```javascript -// Initialize the Skyflow Vault client - -const vault = Skyflow.init({ - // Id of the vault that the client should connect to. - vaultID: 'string', - // URL of the vault that the client should connect to. - - vaultURL: 'string', - // Helper function generates a Skyflow bearer token. - getBearerToken: auth, -}); -``` - -#### V2 (New) -```javascript -// Step 1: Configure Bearer Token Credentials -const credentials: Credentials = { apiKey: '' }; - -// Step 2: Configure Vault -const primaryVaultConfig: VaultConfig = { - vaultId: '', // Primary vault - clusterId: '', // ID from your vault URL e.g., https://{clusterId}.vault.skyflowapis.com - env: Env.PROD, // Deployment environment (PROD by default) - credentials: credentials, // Authentication method -}; - -// Step 3: Configure Skyflow Client -const skyflowConfig: SkyflowConfig = { - vaultConfigs: [primaryVaultConfig], - skyflowCredentials: credentials, // Skyflow credentials will be used if no individual credentials are passed - logLevel: LogLevel.INFO, // Recommended to use LogLevel.ERROR in production environment. -}; - -// Initialize Skyflow Client -const skyflowClient: Skyflow = new Skyflow(skyflowConfig); -``` - -### Key Changes: -- `vaultURL` replaced with `clusterId`. -- Added environment specification (`env`). -- Instance-specific log levels. -- TypeScript support with type definitions - ---- - -### Request & Response Structure - -In V2, with the introduction of TypeScript support, you can now pass an **InsertRequest** of type **InsertRequest**. This request need -- **`tableName`**: The name of the table. -- **`insertData`**: An array of objects containing the data to be inserted -The response will be of type InsertResponse, which contains insertedFields and errors. - -#### V1 (Old) - Request Building -```javascript -const result = skyflow.insert({ - records: [ - { - fields: { - card_number: '411111111111111', - expiry_date: '11/22', - fullname: 'firstNameTest', - }, - table: 'cards', - }, - ], - }); -``` - -#### V2 (New) - Request Building -```typescript -// Prepare Insertion Data -const insertData: Record[] = [ - { card_number: '4111111111111112' } // Example sensitive data -]; - -// Create Insert Request -const insertReq: InsertRequest = new InsertRequest( - '', // Replace with your actual table name - insertData -); - -// Perform Secure Insertion -const response: InsertResponse = await skyflowClient - .vault("") - .insert(insertReq); -``` - -#### V1 (Old) - Response Structure -```json -{ - "records": [ - { - "table": "cards", - "fields": { - "card_number": "f37186-e7e2-466f-91e5-48e2bcbc1", - "expiry_date": "1989cb56-63a-4482-adf-1f74cd1a5" - } - } - ] -} -``` - -#### V2 (New) - Response Structure -```javascript -InsertResponse( - insertedFields : [ - { - skyflowId : "ID1", - "": "", // removed tokens key - "": "" - }, - { - skyflowId : "ID2", - "": "", - "": "" - } - ], - errors: null -); -``` - ---- - -### Request Options - -In V2, we have introduced inbuilt **InsertOptions** classes. These allow you to use setters to configure options instead of passing a plain object with key-value pairs. - - -#### V1 (Old) -```javascript -const options = { - tokens: true, - // other options -}; -``` - -#### V2 (New) -```javascript -const insertOptions: InsertOptions = new InsertOptions(); -insertOptions.setReturnTokens(true); // Optional: Get tokens for inserted data -insertOptions.setContinueOnError(true); // Optional: Continue on partial errors -``` - ---- - -### Error Structure -In V2, we have enriched the error details to provide better debugging capabilities. -The error response now includes: -- **`http_status`**: The HTTP status code. . -- **`grpc_code`**: The gRPC code associated with the error. -- **`details & message`**: A detailed description of the error. -- **`request_ID`**: A unique request identifier for easier debugging. - - -#### V1 (Old) - Error Structure -```javascript -{ - code: string | number, - description: string -} -``` - -#### V2 (New) - Error Structure -```javascript -{ - http_status?: string | number | null, - grpc_code?: string | number | null, - http_code: string | number | null, - message: string, - request_ID?: string | null, - details?: Array | null, -} -``` - ## Quickstart Get started quickly with the essential steps: authenticate, initialize the client, and perform a basic vault operation. This section provides a minimal setup to help you integrate the SDK efficiently. @@ -657,7 +434,7 @@ try { }, //Step 3: Create the second record with card number and cardholder name { - card_numbe: '4111111111111111', // Replace with actual card number (sensitive data) + card_number: '4111111111111111', // Replace with actual card number (sensitive data) cardholder_name: 'John Doe', // Replace with actual cardholder name (sensitive data) } ]; @@ -710,7 +487,7 @@ InsertResponse { errors: [ { requestIndex: 1, - error: 'Insert failed. Column card_numbe is invalid. Specify a valid column.' + error: 'Insert failed. Column card_number is invalid. Specify a valid column.' } ] } @@ -1038,13 +815,13 @@ import { try { // Initialize Skyflow Client // Step 1: Prepare Tokenization Data - const columnvalues: Array = [ + const columnValues: Array = [ { value: "", columnGroup: "" }, // Replace and with actual data { value: "", columnGroup: "" } // Replace and with actual data ]; - // Step 2: Build the TokenizeRequest with the column value2 - const tokenReq: TokenizeRequest = new TokenizeRequest(columnvalues); + // Step 2: Build the TokenizeRequest with the column values + const tokenReq: TokenizeRequest = new TokenizeRequest(columnValues); // Step 3: Call the Skyflow vault to tokenize the sensitive data const response: TokenizeResponse = await skyflowClient @@ -1091,12 +868,12 @@ This example demonstrates how to tokenize sensitive data (e.g., credit card info try { // Initialize Skyflow Client // Step 1: Prepare Tokenization Data - const columnvalues: Array = [ + const columnValues: Array = [ { value: "4111111111111111", columnGroup: "card_number_cg" } ]; - // Step 2: Build the TokenizeRequest with the column value2 - const tokenReq: TokenizeRequest = new TokenizeRequest(columnvalues); + // Step 2: Build the TokenizeRequest with the column values + const tokenReq: TokenizeRequest = new TokenizeRequest(columnValues); // Step 3: Call the Skyflow vault to tokenize the sensitive data const response: TokenizeResponse = await skyflowClient @@ -1958,8 +1735,8 @@ try { // Step 1: Prepare File Upload Data const tableName: string = 'cards'; const skyflowId: string = 'c9312531-2087-439a-bd26-74c41f24db83'; // Skyflow ID of the record - const columnName: string = 'licence'; // Column name to store file - const filePath: string = '/images/licence.png'; // Path to the file for upload + const columnName: string = 'license'; // Column name to store file + const filePath: string = '/images/license.png'; // Path to the file for upload // Step 2: Create File Upload Request const uploadReq: FileUploadRequest = new FileUploadRequest( @@ -2083,7 +1860,7 @@ import { * 1. Configure credentials * 2. Set up vault configuration * 3. Create a deidentify text request - * 4. Use all available options for deidentification + * 4. Use all available options for de-identification * 5. Handle response and errors */ @@ -2187,7 +1964,7 @@ Sample Response: ### Reidentify Text -To reidentify text, use the `reidentifyText` method. The `ReidentifyTextRequest` class creates a reidentify text request, which includes the redacted or deidentified text to be reidentified. Additionally, you can provide optional parameters using the `ReidentifyTextOptions` class to control how specific entities are returned (as redacted, masked, or plain text). +To reidentify text, use the `reidentifyText` method. The `ReidentifyTextRequest` class creates a reidentify text request, which includes the redacted or de-identified text to be re-identified. Additionally, you can provide optional parameters using the `ReidentifyTextOptions` class to control how specific entities are returned (as redacted, masked, or plain text). ```typescript @@ -2200,7 +1977,7 @@ import { } from 'skyflow-node'; try { - // Step 1: Prepare the redacted text to be reidentified + // Step 1: Prepare the redacted text to be re-identified const textReq = new ReidentifyTextRequest( '' ); @@ -2249,7 +2026,7 @@ import { * 1. Configure credentials * 2. Set up vault configuration * 3. Create a reidentify text request - * 4. Use all available options for reidentification + * 4. Use all available options for re-identification * 5. Handle response and errors */ @@ -2272,7 +2049,7 @@ async function performReidentifyText() { .reidentifyText(reidentifyTextRequest, options); // Step 5: Handle response - console.log('Reidentified Text Response:', response); + console.log('Re-identified Text Response:', response); } catch (error) { // Comprehensive Error Handling @@ -2304,7 +2081,7 @@ Sample Response: To deidentify files, use the `deidentifyFile` method. The `DeidentifyFileRequest` class creates a deidentify file request, which includes the file to be deidentified (such as images, PDFs, audio, documents, spreadsheets, or presentations). Additionally, you can provide optional parameters using the `DeidentifyFileOptions` class to control how entities are detected and deidentified, as well as how the output is generated for different file types. -**Note:** File deidentification requires Node.js version 20 or above. +**Note:** File de-identification requires Node.js version 20 or above. ```typescript import { @@ -2416,8 +2193,8 @@ import fs from 'fs'; /** * Skyflow Deidentify File Example - * - * This sample demonstrates how to use all available options for deidentifying files. + * + * This sample demonstrates how to use all available options for de-identifying files. * Supported file types: images (jpg, png, etc.), pdf, audio (mp3, wav), documents, spreadsheets, presentations, structured text. */ @@ -2555,9 +2332,10 @@ Sample response (when the API takes more than 64 seconds): } ``` -### Get run -To retrieve the results of a previously started file deidentification operation, use the `getDetectRun` method. -The `GetDetectRunRequest` class is initialized with the `runId` returned from a prior `deidentifyFile` call. +### Get run + +To retrieve the results of a previously started file de-identification operation, use the `getDetectRun` method. +The `GetDetectRunRequest` class is initialized with the `runId` returned from a prior `deidentifyFile` call. This method allows you to fetch the final results of the file processing operation once they are available. diff --git a/package-lock.json b/package-lock.json index 741e3553..0c5c5a1a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,9 +35,10 @@ "@types/qs": "^6.9.17", "@types/readable-stream": "^4.0.18", "@types/url-join": "4.0.1", + "cspell": "^9.3.1", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", - "prettier": "^3.4.2", + "prettier": "3.6.2", "ts-jest": "^29.1.1", "ts-loader": "^9.5.1", "typescript": "~5.7.2", @@ -1892,6 +1893,594 @@ "dev": true, "license": "MIT" }, + "node_modules/@cspell/cspell-bundled-dicts": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/@cspell/cspell-bundled-dicts/-/cspell-bundled-dicts-9.3.1.tgz", + "integrity": "sha512-vL94iLjEzPTBAoc4v4iY87jUNDYvhG7S3Lkxc9Jdcyk+aeXnoqYK7mCRFOSPSbB2pT2bugX6S6ZaLKVMpY73gA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspell/dict-ada": "^4.1.1", + "@cspell/dict-al": "^1.1.1", + "@cspell/dict-aws": "^4.0.15", + "@cspell/dict-bash": "^4.2.2", + "@cspell/dict-companies": "^3.2.7", + "@cspell/dict-cpp": "^6.0.14", + "@cspell/dict-cryptocurrencies": "^5.0.5", + "@cspell/dict-csharp": "^4.0.7", + "@cspell/dict-css": "^4.0.18", + "@cspell/dict-dart": "^2.3.1", + "@cspell/dict-data-science": "^2.0.11", + "@cspell/dict-django": "^4.1.5", + "@cspell/dict-docker": "^1.1.16", + "@cspell/dict-dotnet": "^5.0.10", + "@cspell/dict-elixir": "^4.0.8", + "@cspell/dict-en_us": "^4.4.24", + "@cspell/dict-en-common-misspellings": "^2.1.8", + "@cspell/dict-en-gb-mit": "^3.1.14", + "@cspell/dict-filetypes": "^3.0.14", + "@cspell/dict-flutter": "^1.1.1", + "@cspell/dict-fonts": "^4.0.5", + "@cspell/dict-fsharp": "^1.1.1", + "@cspell/dict-fullstack": "^3.2.7", + "@cspell/dict-gaming-terms": "^1.1.2", + "@cspell/dict-git": "^3.0.7", + "@cspell/dict-golang": "^6.0.24", + "@cspell/dict-google": "^1.0.9", + "@cspell/dict-haskell": "^4.0.6", + "@cspell/dict-html": "^4.0.12", + "@cspell/dict-html-symbol-entities": "^4.0.4", + "@cspell/dict-java": "^5.0.12", + "@cspell/dict-julia": "^1.1.1", + "@cspell/dict-k8s": "^1.0.12", + "@cspell/dict-kotlin": "^1.1.1", + "@cspell/dict-latex": "^4.0.4", + "@cspell/dict-lorem-ipsum": "^4.0.5", + "@cspell/dict-lua": "^4.0.8", + "@cspell/dict-makefile": "^1.0.5", + "@cspell/dict-markdown": "^2.0.12", + "@cspell/dict-monkeyc": "^1.0.11", + "@cspell/dict-node": "^5.0.8", + "@cspell/dict-npm": "^5.2.20", + "@cspell/dict-php": "^4.1.0", + "@cspell/dict-powershell": "^5.0.15", + "@cspell/dict-public-licenses": "^2.0.15", + "@cspell/dict-python": "^4.2.21", + "@cspell/dict-r": "^2.1.1", + "@cspell/dict-ruby": "^5.0.9", + "@cspell/dict-rust": "^4.0.12", + "@cspell/dict-scala": "^5.0.8", + "@cspell/dict-shell": "^1.1.2", + "@cspell/dict-software-terms": "^5.1.11", + "@cspell/dict-sql": "^2.2.1", + "@cspell/dict-svelte": "^1.0.7", + "@cspell/dict-swift": "^2.0.6", + "@cspell/dict-terraform": "^1.1.3", + "@cspell/dict-typescript": "^3.2.3", + "@cspell/dict-vue": "^3.0.5" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@cspell/cspell-json-reporter": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/@cspell/cspell-json-reporter/-/cspell-json-reporter-9.3.1.tgz", + "integrity": "sha512-XvMupq2jV3lRMEaiFXrsfR3xrvMQ4Im194dRZ02D2qdtYtKV9jErms/OhGmfs1YNLrQaTyDKAAyZLRxhJSmL3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspell/cspell-types": "9.3.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@cspell/cspell-pipe": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/@cspell/cspell-pipe/-/cspell-pipe-9.3.1.tgz", + "integrity": "sha512-MqCoUDwq2z4dn5fYMFrLYHjQyueqhvCNyztPS2ifhXJiEyr/YV61cLvQh/HoZlFmBSL7ViMXjejtL29LTLOEzA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/@cspell/cspell-resolver": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/@cspell/cspell-resolver/-/cspell-resolver-9.3.1.tgz", + "integrity": "sha512-HpgvmgZO+fCF9syPAX+XJRPYya4w3UFA5T8Uj0Ic19tjwoCgtj2F1SMAqr3iah97xH/9bh9tSHdfa7HIWD1J+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "global-directory": "^4.0.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@cspell/cspell-service-bus": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/@cspell/cspell-service-bus/-/cspell-service-bus-9.3.1.tgz", + "integrity": "sha512-mbCuHzcLIrvEOAcWxFmF+cgdIEWEs8bEkUTPA62EjQcQ8RzH82jVUPYDqPGJ7bThoinG/Xfk90EqHgh1b1kEOw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/@cspell/cspell-types": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/@cspell/cspell-types/-/cspell-types-9.3.1.tgz", + "integrity": "sha512-6KBVCN5dEk1+p0RP27DCjmtVNUmn0q+Zovthr35dmKOom2vNgAzFapneXIlir6jWSdKZ8b/5qbwbdhL0ATai5w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/@cspell/dict-ada": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-ada/-/dict-ada-4.1.1.tgz", + "integrity": "sha512-E+0YW9RhZod/9Qy2gxfNZiHJjCYFlCdI69br1eviQQWB8yOTJX0JHXLs79kOYhSW0kINPVUdvddEBe6Lu6CjGQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-al": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-al/-/dict-al-1.1.1.tgz", + "integrity": "sha512-sD8GCaZetgQL4+MaJLXqbzWcRjfKVp8x+px3HuCaaiATAAtvjwUQ5/Iubiqwfd1boIh2Y1/3EgM3TLQ7Q8e0wQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-aws": { + "version": "4.0.15", + "resolved": "https://registry.npmjs.org/@cspell/dict-aws/-/dict-aws-4.0.15.tgz", + "integrity": "sha512-aPY7VVR5Os4rz36EaqXBAEy14wR4Rqv+leCJ2Ug/Gd0IglJpM30LalF3e2eJChnjje3vWoEC0Rz3+e5gpZG+Kg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-bash": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@cspell/dict-bash/-/dict-bash-4.2.2.tgz", + "integrity": "sha512-kyWbwtX3TsCf5l49gGQIZkRLaB/P8g73GDRm41Zu8Mv51kjl2H7Au0TsEvHv7jzcsRLS6aUYaZv6Zsvk1fOz+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspell/dict-shell": "1.1.2" + } + }, + "node_modules/@cspell/dict-companies": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@cspell/dict-companies/-/dict-companies-3.2.7.tgz", + "integrity": "sha512-fEyr3LmpFKTaD0LcRhB4lfW1AmULYBqzg4gWAV0dQCv06l+TsA+JQ+3pZJbUcoaZirtgsgT3dL3RUjmGPhUH0A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-cpp": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/@cspell/dict-cpp/-/dict-cpp-6.0.14.tgz", + "integrity": "sha512-dkmpSwvVfVdtoZ4mW/CK2Ep1v8mJlp6uiKpMNbSMOdJl4kq28nQS4vKNIX3B2bJa0Ha5iHHu+1mNjiLeO3g7Xg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-cryptocurrencies": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@cspell/dict-cryptocurrencies/-/dict-cryptocurrencies-5.0.5.tgz", + "integrity": "sha512-R68hYYF/rtlE6T/dsObStzN5QZw+0aQBinAXuWCVqwdS7YZo0X33vGMfChkHaiCo3Z2+bkegqHlqxZF4TD3rUA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-csharp": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@cspell/dict-csharp/-/dict-csharp-4.0.7.tgz", + "integrity": "sha512-H16Hpu8O/1/lgijFt2lOk4/nnldFtQ4t8QHbyqphqZZVE5aS4J/zD/WvduqnLY21aKhZS6jo/xF5PX9jyqPKUA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-css": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@cspell/dict-css/-/dict-css-4.0.18.tgz", + "integrity": "sha512-EF77RqROHL+4LhMGW5NTeKqfUd/e4OOv6EDFQ/UQQiFyWuqkEKyEz0NDILxOFxWUEVdjT2GQ2cC7t12B6pESwg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-dart": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-dart/-/dict-dart-2.3.1.tgz", + "integrity": "sha512-xoiGnULEcWdodXI6EwVyqpZmpOoh8RA2Xk9BNdR7DLamV/QMvEYn8KJ7NlRiTSauJKPNkHHQ5EVHRM6sTS7jdg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-data-science": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@cspell/dict-data-science/-/dict-data-science-2.0.11.tgz", + "integrity": "sha512-Dt+83nVCcF+dQyvFSaZjCKt1H5KbsVJFtH2X7VUfmIzQu8xCnV1fUmkhBzGJ+NiFs99Oy9JA6I9EjeqExzXk7g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-django": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@cspell/dict-django/-/dict-django-4.1.5.tgz", + "integrity": "sha512-AvTWu99doU3T8ifoMYOMLW2CXKvyKLukPh1auOPwFGHzueWYvBBN+OxF8wF7XwjTBMMeRleVdLh3aWCDEX/ZWg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-docker": { + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/@cspell/dict-docker/-/dict-docker-1.1.16.tgz", + "integrity": "sha512-UiVQ5RmCg6j0qGIxrBnai3pIB+aYKL3zaJGvXk1O/ertTKJif9RZikKXCEgqhaCYMweM4fuLqWSVmw3hU164Iw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-dotnet": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/@cspell/dict-dotnet/-/dict-dotnet-5.0.10.tgz", + "integrity": "sha512-ooar8BP/RBNP1gzYfJPStKEmpWy4uv/7JCq6FOnJLeD1yyfG3d/LFMVMwiJo+XWz025cxtkM3wuaikBWzCqkmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-elixir": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@cspell/dict-elixir/-/dict-elixir-4.0.8.tgz", + "integrity": "sha512-CyfphrbMyl4Ms55Vzuj+mNmd693HjBFr9hvU+B2YbFEZprE5AG+EXLYTMRWrXbpds4AuZcvN3deM2XVB80BN/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-en_us": { + "version": "4.4.24", + "resolved": "https://registry.npmjs.org/@cspell/dict-en_us/-/dict-en_us-4.4.24.tgz", + "integrity": "sha512-JE+/H2YicHJTneRmgH4GSI21rS+1yGZVl1jfOQgl8iHLC+yTTMtCvueNDMK94CgJACzYAoCsQB70MqiFJJfjLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-en-common-misspellings": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@cspell/dict-en-common-misspellings/-/dict-en-common-misspellings-2.1.8.tgz", + "integrity": "sha512-vDsjRFPQGuAADAiitf82z9Mz3DcqKZi6V5hPAEIFkLLKjFVBcjUsSq59SfL59ElIFb76MtBO0BLifdEbBj+DoQ==", + "dev": true, + "license": "CC BY-SA 4.0" + }, + "node_modules/@cspell/dict-en-gb-mit": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@cspell/dict-en-gb-mit/-/dict-en-gb-mit-3.1.14.tgz", + "integrity": "sha512-b+vEerlHP6rnNf30tmTJb7JZnOq4WAslYUvexOz/L3gDna9YJN3bAnwRJ3At3bdcOcMG7PTv3Pi+C73IR22lNg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-filetypes": { + "version": "3.0.14", + "resolved": "https://registry.npmjs.org/@cspell/dict-filetypes/-/dict-filetypes-3.0.14.tgz", + "integrity": "sha512-KSXaSMYYNMLLdHEnju1DyRRH3eQWPRYRnOXpuHUdOh2jC44VgQoxyMU7oB3NAhDhZKBPCihabzECsAGFbdKfEA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-flutter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-flutter/-/dict-flutter-1.1.1.tgz", + "integrity": "sha512-UlOzRcH2tNbFhZmHJN48Za/2/MEdRHl2BMkCWZBYs+30b91mWvBfzaN4IJQU7dUZtowKayVIF9FzvLZtZokc5A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-fonts": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@cspell/dict-fonts/-/dict-fonts-4.0.5.tgz", + "integrity": "sha512-BbpkX10DUX/xzHs6lb7yzDf/LPjwYIBJHJlUXSBXDtK/1HaeS+Wqol4Mlm2+NAgZ7ikIE5DQMViTgBUY3ezNoQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-fsharp": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-fsharp/-/dict-fsharp-1.1.1.tgz", + "integrity": "sha512-imhs0u87wEA4/cYjgzS0tAyaJpwG7vwtC8UyMFbwpmtw+/bgss+osNfyqhYRyS/ehVCWL17Ewx2UPkexjKyaBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-fullstack": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@cspell/dict-fullstack/-/dict-fullstack-3.2.7.tgz", + "integrity": "sha512-IxEk2YAwAJKYCUEgEeOg3QvTL4XLlyArJElFuMQevU1dPgHgzWElFevN5lsTFnvMFA1riYsVinqJJX0BanCFEg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-gaming-terms": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@cspell/dict-gaming-terms/-/dict-gaming-terms-1.1.2.tgz", + "integrity": "sha512-9XnOvaoTBscq0xuD6KTEIkk9hhdfBkkvJAIsvw3JMcnp1214OCGW8+kako5RqQ2vTZR3Tnf3pc57o7VgkM0q1Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-git": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@cspell/dict-git/-/dict-git-3.0.7.tgz", + "integrity": "sha512-odOwVKgfxCQfiSb+nblQZc4ErXmnWEnv8XwkaI4sNJ7cNmojnvogYVeMqkXPjvfrgEcizEEA4URRD2Ms5PDk1w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-golang": { + "version": "6.0.24", + "resolved": "https://registry.npmjs.org/@cspell/dict-golang/-/dict-golang-6.0.24.tgz", + "integrity": "sha512-rY7PlC3MsHozmjrZWi0HQPUl0BVCV0+mwK0rnMT7pOIXqOe4tWCYMULDIsEk4F0gbIxb5badd2dkCPDYjLnDgA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-google": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@cspell/dict-google/-/dict-google-1.0.9.tgz", + "integrity": "sha512-biL65POqialY0i4g6crj7pR6JnBkbsPovB2WDYkj3H4TuC/QXv7Pu5pdPxeUJA6TSCHI7T5twsO4VSVyRxD9CA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-haskell": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@cspell/dict-haskell/-/dict-haskell-4.0.6.tgz", + "integrity": "sha512-ib8SA5qgftExpYNjWhpYIgvDsZ/0wvKKxSP+kuSkkak520iPvTJumEpIE+qPcmJQo4NzdKMN8nEfaeci4OcFAQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-html": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/@cspell/dict-html/-/dict-html-4.0.12.tgz", + "integrity": "sha512-JFffQ1dDVEyJq6tCDWv0r/RqkdSnV43P2F/3jJ9rwLgdsOIXwQbXrz6QDlvQLVvNSnORH9KjDtenFTGDyzfCaA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-html-symbol-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@cspell/dict-html-symbol-entities/-/dict-html-symbol-entities-4.0.4.tgz", + "integrity": "sha512-afea+0rGPDeOV9gdO06UW183Qg6wRhWVkgCFwiO3bDupAoyXRuvupbb5nUyqSTsLXIKL8u8uXQlJ9pkz07oVXw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-java": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/@cspell/dict-java/-/dict-java-5.0.12.tgz", + "integrity": "sha512-qPSNhTcl7LGJ5Qp6VN71H8zqvRQK04S08T67knMq9hTA8U7G1sTKzLmBaDOFhq17vNX/+rT+rbRYp+B5Nwza1A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-julia": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-julia/-/dict-julia-1.1.1.tgz", + "integrity": "sha512-WylJR9TQ2cgwd5BWEOfdO3zvDB+L7kYFm0I9u0s9jKHWQ6yKmfKeMjU9oXxTBxIufhCXm92SKwwVNAC7gjv+yA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-k8s": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/@cspell/dict-k8s/-/dict-k8s-1.0.12.tgz", + "integrity": "sha512-2LcllTWgaTfYC7DmkMPOn9GsBWsA4DZdlun4po8s2ysTP7CPEnZc1ZfK6pZ2eI4TsZemlUQQ+NZxMe9/QutQxg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-kotlin": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-kotlin/-/dict-kotlin-1.1.1.tgz", + "integrity": "sha512-J3NzzfgmxRvEeOe3qUXnSJQCd38i/dpF9/t3quuWh6gXM+krsAXP75dY1CzDmS8mrJAlBdVBeAW5eAZTD8g86Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-latex": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@cspell/dict-latex/-/dict-latex-4.0.4.tgz", + "integrity": "sha512-YdTQhnTINEEm/LZgTzr9Voz4mzdOXH7YX+bSFs3hnkUHCUUtX/mhKgf1CFvZ0YNM2afjhQcmLaR9bDQVyYBvpA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-lorem-ipsum": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@cspell/dict-lorem-ipsum/-/dict-lorem-ipsum-4.0.5.tgz", + "integrity": "sha512-9a4TJYRcPWPBKkQAJ/whCu4uCAEgv/O2xAaZEI0n4y1/l18Yyx8pBKoIX5QuVXjjmKEkK7hi5SxyIsH7pFEK9Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-lua": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@cspell/dict-lua/-/dict-lua-4.0.8.tgz", + "integrity": "sha512-N4PkgNDMu9JVsRu7JBS/3E/dvfItRgk9w5ga2dKq+JupP2Y3lojNaAVFhXISh4Y0a6qXDn2clA6nvnavQ/jjLA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-makefile": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@cspell/dict-makefile/-/dict-makefile-1.0.5.tgz", + "integrity": "sha512-4vrVt7bGiK8Rx98tfRbYo42Xo2IstJkAF4tLLDMNQLkQ86msDlYSKG1ZCk8Abg+EdNcFAjNhXIiNO+w4KflGAQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-markdown": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@cspell/dict-markdown/-/dict-markdown-2.0.12.tgz", + "integrity": "sha512-ufwoliPijAgWkD/ivAMC+A9QD895xKiJRF/fwwknQb7kt7NozTLKFAOBtXGPJAB4UjhGBpYEJVo2elQ0FCAH9A==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@cspell/dict-css": "^4.0.18", + "@cspell/dict-html": "^4.0.12", + "@cspell/dict-html-symbol-entities": "^4.0.4", + "@cspell/dict-typescript": "^3.2.3" + } + }, + "node_modules/@cspell/dict-monkeyc": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@cspell/dict-monkeyc/-/dict-monkeyc-1.0.11.tgz", + "integrity": "sha512-7Q1Ncu0urALI6dPTrEbSTd//UK0qjRBeaxhnm8uY5fgYNFYAG+u4gtnTIo59S6Bw5P++4H3DiIDYoQdY/lha8w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-node": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@cspell/dict-node/-/dict-node-5.0.8.tgz", + "integrity": "sha512-AirZcN2i84ynev3p2/1NCPEhnNsHKMz9zciTngGoqpdItUb2bDt1nJBjwlsrFI78GZRph/VaqTVFwYikmncpXg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-npm": { + "version": "5.2.20", + "resolved": "https://registry.npmjs.org/@cspell/dict-npm/-/dict-npm-5.2.20.tgz", + "integrity": "sha512-tJRv1qEdW3f8fxK/D2huoqkSvM6ogz55hAt9RTdB7tZy57wio9Tkj+xfi2DIeOlmf6e94c6pNPZIC/o5rclMhw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-php": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-php/-/dict-php-4.1.0.tgz", + "integrity": "sha512-dTDeabyOj7eFvn2Q4Za3uVXM2+SzeFMqX8ly2P0XTo4AzbCmI2hulFD/QIADwWmwiRrInbbf8cxwFHNIYrXl4w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-powershell": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/@cspell/dict-powershell/-/dict-powershell-5.0.15.tgz", + "integrity": "sha512-l4S5PAcvCFcVDMJShrYD0X6Huv9dcsQPlsVsBGbH38wvuN7gS7+GxZFAjTNxDmTY1wrNi1cCatSg6Pu2BW4rgg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-public-licenses": { + "version": "2.0.15", + "resolved": "https://registry.npmjs.org/@cspell/dict-public-licenses/-/dict-public-licenses-2.0.15.tgz", + "integrity": "sha512-cJEOs901H13Pfy0fl4dCD1U+xpWIMaEPq8MeYU83FfDZvellAuSo4GqWCripfIqlhns/L6+UZEIJSOZnjgy7Wg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-python": { + "version": "4.2.21", + "resolved": "https://registry.npmjs.org/@cspell/dict-python/-/dict-python-4.2.21.tgz", + "integrity": "sha512-M9OgwXWhpZqEZqKU2psB2DFsT8q5SwEahkQeIpNIRWIErjwG7I9yYhhfvPz6s5gMCMhhb3hqcPJTnmdgqGrQyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspell/dict-data-science": "^2.0.11" + } + }, + "node_modules/@cspell/dict-r": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-r/-/dict-r-2.1.1.tgz", + "integrity": "sha512-71Ka+yKfG4ZHEMEmDxc6+blFkeTTvgKbKAbwiwQAuKl3zpqs1Y0vUtwW2N4b3LgmSPhV3ODVY0y4m5ofqDuKMw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-ruby": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/@cspell/dict-ruby/-/dict-ruby-5.0.9.tgz", + "integrity": "sha512-H2vMcERMcANvQshAdrVx0XoWaNX8zmmiQN11dZZTQAZaNJ0xatdJoSqY8C8uhEMW89bfgpN+NQgGuDXW2vmXEw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-rust": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/@cspell/dict-rust/-/dict-rust-4.0.12.tgz", + "integrity": "sha512-z2QiH+q9UlNhobBJArvILRxV8Jz0pKIK7gqu4TgmEYyjiu1TvnGZ1tbYHeu9w3I/wOP6UMDoCBTty5AlYfW0mw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-scala": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@cspell/dict-scala/-/dict-scala-5.0.8.tgz", + "integrity": "sha512-YdftVmumv8IZq9zu1gn2U7A4bfM2yj9Vaupydotyjuc+EEZZSqAafTpvW/jKLWji2TgybM1L2IhmV0s/Iv9BTw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-shell": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@cspell/dict-shell/-/dict-shell-1.1.2.tgz", + "integrity": "sha512-WqOUvnwcHK1X61wAfwyXq04cn7KYyskg90j4lLg3sGGKMW9Sq13hs91pqrjC44Q+lQLgCobrTkMDw9Wyl9nRFA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-software-terms": { + "version": "5.1.11", + "resolved": "https://registry.npmjs.org/@cspell/dict-software-terms/-/dict-software-terms-5.1.11.tgz", + "integrity": "sha512-xwARdlp6o81BK7uNl4qR5CmLBXuc9xWyEeEwzeAw/8SkBdYheVQO6F1Fey2iqMRDT9LAb5Znbg83pJVpLjgBjg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-sql": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-sql/-/dict-sql-2.2.1.tgz", + "integrity": "sha512-qDHF8MpAYCf4pWU8NKbnVGzkoxMNrFqBHyG/dgrlic5EQiKANCLELYtGlX5auIMDLmTf1inA0eNtv74tyRJ/vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-svelte": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@cspell/dict-svelte/-/dict-svelte-1.0.7.tgz", + "integrity": "sha512-hGZsGqP0WdzKkdpeVLBivRuSNzOTvN036EBmpOwxH+FTY2DuUH7ecW+cSaMwOgmq5JFSdTcbTNFlNC8HN8lhaQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-swift": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@cspell/dict-swift/-/dict-swift-2.0.6.tgz", + "integrity": "sha512-PnpNbrIbex2aqU1kMgwEKvCzgbkHtj3dlFLPMqW1vSniop7YxaDTtvTUO4zA++ugYAEL+UK8vYrBwDPTjjvSnA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-terraform": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@cspell/dict-terraform/-/dict-terraform-1.1.3.tgz", + "integrity": "sha512-gr6wxCydwSFyyBKhBA2xkENXtVFToheqYYGFvlMZXWjviynXmh+NK/JTvTCk/VHk3+lzbO9EEQKee6VjrAUSbA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-typescript": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/@cspell/dict-typescript/-/dict-typescript-3.2.3.tgz", + "integrity": "sha512-zXh1wYsNljQZfWWdSPYwQhpwiuW0KPW1dSd8idjMRvSD0aSvWWHoWlrMsmZeRl4qM4QCEAjua8+cjflm41cQBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-vue": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@cspell/dict-vue/-/dict-vue-3.0.5.tgz", + "integrity": "sha512-Mqutb8jbM+kIcywuPQCCaK5qQHTdaByoEO2J9LKFy3sqAdiBogNkrplqUK0HyyRFgCfbJUgjz3N85iCMcWH0JA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dynamic-import": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/@cspell/dynamic-import/-/dynamic-import-9.3.1.tgz", + "integrity": "sha512-pjdCtlXio1Zov2Xd74CNdhwQ0OQU1+fYbT1YrdYJFplW+OeHze9eEPRgCKzMRSXr3s8La+dfrdtWVr0LhLTTvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspell/url": "9.3.1", + "import-meta-resolve": "^4.2.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@cspell/filetypes": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/@cspell/filetypes/-/filetypes-9.3.1.tgz", + "integrity": "sha512-8VghfXnR2SIBs7jFG0G2MI6ixQM0tcnFU/WqgxZJPOjPSX+kpCuzePijG3ueiMhIWztHg+NM+nQiQGREcuX0vA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/@cspell/strong-weak-map": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/@cspell/strong-weak-map/-/strong-weak-map-9.3.1.tgz", + "integrity": "sha512-HNFyN9AXI2b6pC6p/VhJgDPw0rg0CTVHhQcleb3e2RsU72QnNv9DltcYR59y1igwJ+w5VP2sYh2TWYvBPTeMlg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/@cspell/url": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/@cspell/url/-/url-9.3.1.tgz", + "integrity": "sha512-4MlTvq2neLV9IRDNIxcA6ef6bvUqqA8avbotnmD4X6p1IzMOvVLvQ8t6UMr4pKzpe+c5Ph33Y+C+mcwK3rk/BQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -2907,6 +3496,13 @@ "sprintf-js": "~1.0.2" } }, + "node_modules/array-timsort": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-timsort/-/array-timsort-1.0.3.tgz", + "integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==", + "dev": true, + "license": "MIT" + }, "node_modules/async": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", @@ -3309,6 +3905,35 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chalk-template": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-1.1.2.tgz", + "integrity": "sha512-2bxTP2yUH7AJj/VAXfcA+4IcWGdQ87HwBANLt5XxGTeomo8yG0y95N1um9i5StvhT/Bl0/2cARA5v1PpPXUxUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.2.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/chalk/chalk-template?sponsor=1" + } + }, + "node_modules/chalk-template/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/char-regex": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", @@ -3352,6 +3977,23 @@ "dev": true, "license": "MIT" }, + "node_modules/clear-module": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/clear-module/-/clear-module-4.1.2.tgz", + "integrity": "sha512-LWAxzHqdHsAZlPlEyJ2Poz6AIs384mPeqLVCru2p0BrP9G/kVGuhNyZYClLO6cXlnuJjzC8xtsJIuMjKqLXoAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^2.0.0", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -3424,6 +4066,21 @@ "dev": true, "license": "MIT" }, + "node_modules/comment-json": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.4.1.tgz", + "integrity": "sha512-r1To31BQD5060QdkC+Iheai7gHwoSZobzunqkf2/kQ6xIAfJyrKNAFUwdKvkK7Qgu7pVTKQEa7ok7Ed3ycAJgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-timsort": "^1.0.3", + "core-util-is": "^1.0.3", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -3452,6 +4109,13 @@ "url": "https://opencollective.com/core-js" } }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "license": "MIT" + }, "node_modules/create-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", @@ -3489,6 +4153,236 @@ "node": ">= 8" } }, + "node_modules/cspell": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/cspell/-/cspell-9.3.1.tgz", + "integrity": "sha512-E6hbLdBx0GO4AVm/MxXhw/k4rPCqlvTx4OQUT7VtRdM6DsAhf+CZzuyXlzfkXESlUUNj0VGaZPPMC0e0NLsfsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspell/cspell-json-reporter": "9.3.1", + "@cspell/cspell-pipe": "9.3.1", + "@cspell/cspell-types": "9.3.1", + "@cspell/dynamic-import": "9.3.1", + "@cspell/url": "9.3.1", + "chalk": "^5.6.2", + "chalk-template": "^1.1.2", + "commander": "^14.0.2", + "cspell-config-lib": "9.3.1", + "cspell-dictionary": "9.3.1", + "cspell-gitignore": "9.3.1", + "cspell-glob": "9.3.1", + "cspell-io": "9.3.1", + "cspell-lib": "9.3.1", + "fast-json-stable-stringify": "^2.1.0", + "flatted": "^3.3.3", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15" + }, + "bin": { + "cspell": "bin.mjs", + "cspell-esm": "bin.mjs" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/streetsidesoftware/cspell?sponsor=1" + } + }, + "node_modules/cspell-config-lib": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/cspell-config-lib/-/cspell-config-lib-9.3.1.tgz", + "integrity": "sha512-Mdm7FtXkiBzVigGY4jd/DVELai8XUkgV7E74l14VVnveyBHE1EnYD8g4COVE8qglCuSQnTtsuI1gqBlJkcLSzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspell/cspell-types": "9.3.1", + "comment-json": "^4.4.1", + "smol-toml": "^1.4.2", + "yaml": "^2.8.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cspell-dictionary": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/cspell-dictionary/-/cspell-dictionary-9.3.1.tgz", + "integrity": "sha512-px5qCUZqfCG2bBjkxSueLFRHCW0Vl2Joszfj36IPAyZJCO+OjBzHvXcitbFwwy5LDfxyXTTY307Asumzi5IAqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspell/cspell-pipe": "9.3.1", + "@cspell/cspell-types": "9.3.1", + "cspell-trie-lib": "9.3.1", + "fast-equals": "^5.3.2" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cspell-gitignore": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/cspell-gitignore/-/cspell-gitignore-9.3.1.tgz", + "integrity": "sha512-C56uKvx71QtsKu6JBxZDFYZHxx8ILh0mLYDStmXPRpGDYsDCC19sEnd+z8+HTXJZ1i5jxIqitQKtiCSXTREA+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspell/url": "9.3.1", + "cspell-glob": "9.3.1", + "cspell-io": "9.3.1" + }, + "bin": { + "cspell-gitignore": "bin.mjs" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cspell-glob": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/cspell-glob/-/cspell-glob-9.3.1.tgz", + "integrity": "sha512-pyo8ySo90U4WaayjrnefU7kPA1pFL8ok4BDnlKJ5MwRqzVPIwV003Op0hnRYEEUdNyjRR4kU6GshMEkTrSlB7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspell/url": "9.3.1", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cspell-glob/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/cspell-grammar": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/cspell-grammar/-/cspell-grammar-9.3.1.tgz", + "integrity": "sha512-SZR5IfrMZK0pgVP5U48yoHvkfiCbmGkwwTGGomEXpVYev/7fG9wupZKt2YXfvATiuQmcZ9hFW4fPLZbpJckPfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspell/cspell-pipe": "9.3.1", + "@cspell/cspell-types": "9.3.1" + }, + "bin": { + "cspell-grammar": "bin.mjs" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cspell-io": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/cspell-io/-/cspell-io-9.3.1.tgz", + "integrity": "sha512-ZL5IVJiNHU3bkJh1+Zgmx5i0NaUIondJZ7vIlYlO55Llz8mtIoSp7Cn2j9tURfRP/Q0BZOE6M841Tiich0mqPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspell/cspell-service-bus": "9.3.1", + "@cspell/url": "9.3.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cspell-lib": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/cspell-lib/-/cspell-lib-9.3.1.tgz", + "integrity": "sha512-3P+PW6EZgztP0eUDHeUzi4ro6IqH927n59BAR6djo58eAMgwbyZUYtXYXVOxlyhWqiVjL/hjb8hiqzTt1YQFEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspell/cspell-bundled-dicts": "9.3.1", + "@cspell/cspell-pipe": "9.3.1", + "@cspell/cspell-resolver": "9.3.1", + "@cspell/cspell-types": "9.3.1", + "@cspell/dynamic-import": "9.3.1", + "@cspell/filetypes": "9.3.1", + "@cspell/strong-weak-map": "9.3.1", + "@cspell/url": "9.3.1", + "clear-module": "^4.1.2", + "cspell-config-lib": "9.3.1", + "cspell-dictionary": "9.3.1", + "cspell-glob": "9.3.1", + "cspell-grammar": "9.3.1", + "cspell-io": "9.3.1", + "cspell-trie-lib": "9.3.1", + "env-paths": "^3.0.0", + "gensequence": "^8.0.8", + "import-fresh": "^3.3.1", + "resolve-from": "^5.0.0", + "vscode-languageserver-textdocument": "^1.0.12", + "vscode-uri": "^3.1.0", + "xdg-basedir": "^5.1.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cspell-trie-lib": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/cspell-trie-lib/-/cspell-trie-lib-9.3.1.tgz", + "integrity": "sha512-PfHk6hX2e+OF4t3qxA/Y95FScEAPM7fQGsDaq+U0AqT8vsdtVou+VVS43ILBiCDYBDn2WUjWBTKYBGk2t1oKGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspell/cspell-pipe": "9.3.1", + "@cspell/cspell-types": "9.3.1", + "gensequence": "^8.0.8" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cspell/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/cspell/node_modules/commander": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.2.tgz", + "integrity": "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/cspell/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/cssom": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", @@ -3729,6 +4623,19 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/env-paths": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz", + "integrity": "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -3979,6 +4886,16 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-equals": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.3.3.tgz", + "integrity": "sha512-/boTcHZeIAQ2r/tL11voclBHDeP9WPxLt+tyAbVSyyXuUFyh0Tne7gJZTqGbxnvj79TjLdCXLOY7UIPhyG5MTw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -4073,6 +4990,13 @@ "node": ">=8" } }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, "node_modules/form-data": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", @@ -4138,6 +5062,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gensequence": { + "version": "8.0.8", + "resolved": "https://registry.npmjs.org/gensequence/-/gensequence-8.0.8.tgz", + "integrity": "sha512-omMVniXEXpdx/vKxGnPRoO2394Otlze28TyxECbFVyoSpZ9H3EO7lemjcB12OpQJzRW4e5tt/dL1rOxry6aMHg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -4247,6 +5181,22 @@ "dev": true, "license": "BSD-2-Clause" }, + "node_modules/global-directory": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", + "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "4.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -4417,6 +5367,46 @@ ], "license": "BSD-3-Clause" }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/import-local": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", @@ -4437,6 +5427,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/import-meta-resolve": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -4466,6 +5467,16 @@ "dev": true, "license": "ISC" }, + "node_modules/ini": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", + "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -5882,6 +6893,19 @@ "node": ">=6" } }, + "node_modules/parent-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-2.0.0.tgz", + "integrity": "sha512-uo0Z9JJeWzv8BG+tRcapBKNJ0dro9cLyczGzulS6EfeyAdeC9sbojtW6XwvYxJkEne9En+J2XEl4zyglVeIwFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -5995,9 +7019,9 @@ } }, "node_modules/prettier": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", - "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", + "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", "dev": true, "license": "MIT", "bin": { @@ -6493,6 +7517,19 @@ "node": ">=8" } }, + "node_modules/smol-toml": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.5.0.tgz", + "integrity": "sha512-Jjsa8LZ+DyLbZ7gVi9d18bS8oxq0PQrTlVDfvYXgh7gxLwbW9QWgvakHD+hBLUtr5NahfStd8LQLGSPchaEJ8Q==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 18" + }, + "funding": { + "url": "https://github.com/sponsors/cyyynthia" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -6792,6 +7829,54 @@ "node": ">=8" } }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -7122,6 +8207,20 @@ "node": ">=10.12.0" } }, + "node_modules/vscode-languageserver-textdocument": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", + "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==", + "dev": true, + "license": "MIT" + }, + "node_modules/vscode-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz", + "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==", + "dev": true, + "license": "MIT" + }, "node_modules/w3c-xmlserializer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", @@ -7341,6 +8440,19 @@ } } }, + "node_modules/xdg-basedir": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", + "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/xml-name-validator": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", @@ -7375,6 +8487,19 @@ "dev": true, "license": "ISC" }, + "node_modules/yaml": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", + "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + } + }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", diff --git a/package.json b/package.json index d9a44646..672ee674 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "prettier": "prettier --list-different '**/*.{js,ts}'", "lint": "npm run prettier && npm run eslint", "lint-fix": "prettier --write '**/*.{js,ts}' && eslint --fix '**/*.js'", + "spellcheck": "cspell '**/*.{ts,js,md}'", "docs-gen": "typedoc && node scripts/docs-script/markdown-gen.js && npx ts-node scripts/docs-script/processMarkdown.ts" }, "repository": { @@ -58,12 +59,13 @@ "@types/qs": "^6.9.17", "@types/readable-stream": "^4.0.18", "@types/url-join": "4.0.1", + "cspell": "^9.3.1", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", - "prettier": "^3.4.2", + "prettier": "3.6.2", "ts-jest": "^29.1.1", "ts-loader": "^9.5.1", "typescript": "~5.7.2", "webpack": "^5.97.1" } -} \ No newline at end of file +} diff --git a/samples/README.md b/samples/README.md index 0b2cd320..4c9c6046 100644 --- a/samples/README.md +++ b/samples/README.md @@ -1,105 +1,120 @@ # Node.js SDK samples + Test the SDK by adding `VAULT-ID`, `VAULT-URL`, and `SERVICE-ACCOUNT` details in the required places for each sample. ## Prerequisites -- A Skylow account. If you don't have one, register for one on the [Try Skyflow](https://skyflow.com/try-skyflow) page. + +- A Skyflow account. If you don't have one, register for one on the [Try Skyflow](https://skyflow.com/try-skyflow) page. - [Node 7.6.0](https://nodejs.org/en/) and above. ## Prepare + - Install the Node SDK: + ```bash npm install skyflow-node ``` -### Create the vault +### Create a vault + 1. In a browser, navigate to Skyflow Studio. 2. Create a vault by clicking **Create Vault** > **Start With a Template** > **Quickstart vault**. 3. Once the vault is created, click the gear icon and select **Edit Vault Details**. 4. Note your **Vault URL** and **Vault ID** values, then click **Cancel**. You'll need these later. ### Create a service account + 1. In the side navigation click, **IAM** > **Service Accounts** > **New Service Account**. 2. For **Name**, enter "SDK Samples". For **Roles**, choose **Vault Editor**. 3. Click **Create**. Your browser downloads a **credentials.json** file. Keep this file secure. You'll need it for each of the samples. ## The samples + ### Detokenize + Detokenize a data token from the vault. Make sure the specified token is for data that exists in the vault. If you need a valid token, use [Insert.ts](./vault-api/Insert.ts) to insert the data, then use this data's token for detokenization. -#### Configure -1. Replace **** with **VAULT ID** -2. Replace **** with **VAULT URL**. -3. Replace **** with **COLUMN NAME**. -4. Replace **** with **Data Token 1**. -5. Replace **** with **Data Token 2**. -6. Replace **** with **Data Token 3**. -7. Replace **** with **Data Token 4**. -8. Replace **** with relative path of **SERVICE ACCOUNT CREDENTIAL FILE**. - -#### Run the sample + +1. Replace `` with **VAULT ID** +2. Replace `` with **VAULT URL**. +3. Replace `` with **COLUMN NAME**. +4. Replace `` with **Data Token 1**. +5. Replace `` with **Data Token 2**. +6. Replace `` with **Data Token 3**. +7. Replace `` with **Data Token 4**. +8. Replace `` with relative path of **SERVICE ACCOUNT CREDENTIAL FILE**. +9. Run the sample + ```bash ts-node Detokenize.ts -``` +``` ### GetById -Get data using skyflow id. -#### Configure -1. Replace **** with **VAULT ID** -2. Replace **** with **VAULT URL**. -3. Replace **** with **Skyflow Id 1**. -4. Replace **** with **Skyflow Id 2**. -5. Replace **** with **Skyflow Id 3**. -6. Replace **** with relative path of **SERVICE ACCOUNT CREDENTIAL FILE**. -7. Replace **** with **credit_cards**. -#### Run the sample + +Get data using skyflow id. + +1. Replace `` with **VAULT ID** +2. Replace `` with **VAULT URL**. +3. Replace `` with **Skyflow Id 1**. +4. Replace `` with **Skyflow Id 2**. +5. Replace `` with **Skyflow Id 3**. +6. Replace `` with relative path of **SERVICE ACCOUNT CREDENTIAL FILE**. +7. Replace `` with **credit_cards**. +8. Run the sample + ```bash ts-node GetById.ts -``` +``` ### Insert + Insert data in the vault. -#### Configure -1. Replace **** with **VAULT ID**. -2. Replace **** with **VAULT URL**. -3. Replace **** with relative path of **SERVICE ACCOUNT CREDENTIAL FILE**. -4. Replace **** with **credit_cards**. -5. Replace **** with **column name**. -6. Replace **** with **valid value corresponding to column name**. -#### Run the sample + +1. Replace `` with **VAULT ID**. +2. Replace `` with **VAULT URL**. +3. Replace `` with relative path of **SERVICE ACCOUNT CREDENTIAL FILE**. +4. Replace `` with **credit_cards**. +5. Replace `` with **column name**. +6. Replace `` with **valid value corresponding to column name**. +7. Run the sample + ```bash ts-node Insert.ts -``` +``` ### InvokeConnection + Skyflow Connections is a gateway service that uses Skyflow's underlying tokenization capabilities to securely connect to first-party and third-party services. This way, your infrastructure is never directly exposed to sensitive data, and you offload security and compliance requirements to Skyflow. -#### Configure -1. Replace **** with **VAULT ID**. -2. Replace **** with **VAULT URL**. -3. Replace **** with relative path of **SERVICE ACCOUNT CREDENTIAL FILE**. -4. Replace **** with **Connection url**. + +1. Replace `` with **VAULT ID**. +2. Replace `` with **VAULT URL**. +3. Replace `` with relative path of **SERVICE ACCOUNT CREDENTIAL FILE**. +4. Replace `` with **Connection url**. 5. Give **Authorization** value as the tokens. 6. Replace value of **requestBody** with your's request body content. +7. Run the sample -#### Run the sample ```bash ts-node InvokeConnection.ts -``` +``` ### Service account token generation + Generates a service account Bearer token using the file path of credentials.json. -#### Configure -1. Replace **** with relative path of **SERVICE ACCOUNT CREDENTIAL FILE**. -#### Run the sample +1. Replace `` with relative path of **SERVICE ACCOUNT CREDENTIAL FILE**. +2. Run the sample + ```bash ts-node TokenGenerationExample.ts ``` -### Generate Bearer Token From Credentails -Generates a service account bearer token using the JSON content of a credentials file. -#### Configure -1. Replace **credentials*** with json data of downloaded credentials file while creation Service account. +### Generate a Bearer Token From `credentials.json` + +Generates a service account bearer token using the JSON content of a `credentials.json` file. + +1. Replace **credentials\*** with json data of downloaded credentials file while creation Service account. +2. Run the sample -#### Run the sample ```bash ts-node TokenGenerationUsingCredContent.ts -``` \ No newline at end of file +``` diff --git a/samples/detect-api/deidentify-file-with-filepath.ts b/samples/detect-api/deidentify-file-with-filepath.ts index 1236dee0..cd02e309 100644 --- a/samples/detect-api/deidentify-file-with-filepath.ts +++ b/samples/detect-api/deidentify-file-with-filepath.ts @@ -22,11 +22,11 @@ import { /** * Skyflow Deidentify File Example - * - * This sample demonstrates how to use all available options for deidentifying files. + * + * This sample demonstrates how to use all available options for de-identifying files. * Supported file types: images (jpg, png, etc.), pdf, audio (mp3, wav), documents, spreadsheets, presentations, structured text. - * - * Note: File deidentification requires Node.js version 20 or above. + * + * Note: File de-identification requires Node.js version 20 or above. */ async function performDeidentifyFile() { @@ -74,7 +74,7 @@ import { // Allowlist regex patterns (entities matching these will NOT be deidentified) options.setAllowRegexList(['']); - // Restrict deidentification to entities matching these regex patterns + // Restrict de-identification to entities matching these regex patterns options.setRestrictRegexList(['']); // Token format for deidentified entities diff --git a/samples/detect-api/deidentify-file.ts b/samples/detect-api/deidentify-file.ts index b487b0d4..42299098 100644 --- a/samples/detect-api/deidentify-file.ts +++ b/samples/detect-api/deidentify-file.ts @@ -22,11 +22,11 @@ import fs from 'fs'; /** * Skyflow Deidentify File Example - * - * This sample demonstrates how to use all available options for deidentifying files. + * + * This sample demonstrates how to use all available options for de-identifying files. * Supported file types: images (jpg, png, etc.), pdf, audio (mp3, wav), documents, spreadsheets, presentations, structured text. - * - * Note: File deidentification requires Node.js version 20 or above. + * + * Note: File de-identification requires Node.js version 20 or above. */ async function performDeidentifyFile() { @@ -75,7 +75,7 @@ async function performDeidentifyFile() { // Allowlist regex patterns (entities matching these will NOT be deidentified) options.setAllowRegexList(['']); - // Restrict deidentification to entities matching these regex patterns + // Restrict de-identification to entities matching these regex patterns options.setRestrictRegexList(['']); // Token format for deidentified entities diff --git a/samples/detect-api/deidentify-text.ts b/samples/detect-api/deidentify-text.ts index f2dc53e4..1b97a882 100644 --- a/samples/detect-api/deidentify-text.ts +++ b/samples/detect-api/deidentify-text.ts @@ -22,7 +22,7 @@ import { * 1. Configure credentials * 2. Set up vault configuration * 3. Create a deidentify text request - * 4. Use all available options for deidentification + * 4. Use all available options for de-identification * 5. Handle response and errors */ @@ -64,7 +64,7 @@ async function performDeidentifyText() { // setAllowRegexList: Allowlist regex patterns (entities matching these will not be deidentified) // optionsText.setAllowRegexList(['']); - // setRestrictRegexList: Restrict deidentification to entities matching these regex patterns + // setRestrictRegexList: Restrict de-identification to entities matching these regex patterns // optionsText.setRestrictRegexList(['']); // setTokenFormat: Specify the token format for deidentified entities diff --git a/samples/detect-api/reidentify-text.ts b/samples/detect-api/reidentify-text.ts index 45cea4a4..df11d223 100644 --- a/samples/detect-api/reidentify-text.ts +++ b/samples/detect-api/reidentify-text.ts @@ -19,7 +19,7 @@ import { * 1. Configure credentials * 2. Set up vault configuration * 3. Create a reidentify text request - * 4. Use all available options for reidentification + * 4. Use all available options for re-identification * 5. Handle response and errors */ @@ -66,7 +66,7 @@ async function performReidentifyText() { .reidentifyText(reidentifyRequest, options); // Step 7: Handle response - console.log('Reidentified Text Response:', response); + console.log('Re-identified Text Response:', response); } catch (error) { // Comprehensive Error Handling diff --git a/samples/vault-api/insert-continue-on-error.ts b/samples/vault-api/insert-continue-on-error.ts index fc93d3b4..3a630864 100644 --- a/samples/vault-api/insert-continue-on-error.ts +++ b/samples/vault-api/insert-continue-on-error.ts @@ -51,7 +51,7 @@ async function performSecureDataInsertion() { // Step 4: Prepare Insertion Data const insertData: Record[] = [ { card_number: "41111111111111111", cvv: "111" }, // Example sensitive data - { card_numbe: "41111111111111111", cvv: "132" }, // Example incorrect data + { card_number: "41111111111111111", cvv: "132" }, // Example incorrect data ]; // Step 5: Create Insert Request From a6b8845ed8be19097d7e318cf7d3633f0d8341be Mon Sep 17 00:00:00 2001 From: Joseph McCarron Date: Fri, 14 Nov 2025 01:05:58 -0600 Subject: [PATCH 02/15] created docs directory with some extracted content and streamlined main readme by removing redundant examples and linking to the samples/ directory instead --- AUTH.md | 0 README.md | 2336 +++++++-------------- SECURITY.md | 4 +- docs/advanced_initialization.md | 146 ++ docs/generate_bearer_tokens.md | 0 MIGRATE_TO_v2.md => docs/migrate_to_v2.md | 0 6 files changed, 931 insertions(+), 1555 deletions(-) create mode 100644 AUTH.md create mode 100644 docs/advanced_initialization.md create mode 100644 docs/generate_bearer_tokens.md rename MIGRATE_TO_v2.md => docs/migrate_to_v2.md (100%) diff --git a/AUTH.md b/AUTH.md new file mode 100644 index 00000000..e69de29b diff --git a/README.md b/README.md index bc46aaf5..1fb4646d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ - # Skyflow Node.js SDK The Skyflow SDK for Node.js, Deno, Bun, and Cloudflare Workers. @@ -7,26 +6,23 @@ The Skyflow SDK for Node.js, Deno, Bun, and Cloudflare Workers. [![GitHub release](https://badge.fury.io/js/skyflow-node.svg)](https://www.npmjs.com/package/skyflow-node) [![License](https://img.shields.io/github/license/skyflowapi/skyflow-node)](https://github.com/skyflowapi/skyflow-node/blob/main/LICENSE) - ## Table of contents - [Skyflow Node.js SDK](#skyflow-nodejs-sdk) - [Table of contents](#table-of-contents) - [Overview](#overview) - - [Install](#install) - - [Requirements](#requirements) - - [Import / Require](#import--require) - - [Require](#require) - - [ES modules](#es-modules) - - [All imports](#all-imports) + - [Installation](#installation) + - [Require](#require) + - [ES modules](#es-modules) + - [All imports](#all-imports) - [Quickstart](#quickstart) - [Authenticate](#authenticate) - [Initialize the client](#initialize-the-client) - [Insert data into the vault](#insert-data-into-the-vault) - [Vault](#vault) - - [Insert data into the vault](#insert-data-into-the-vault-1) + - [Insert and tokenize data](#insert-and-tokenize-data) - [Construct an insert request](#construct-an-insert-request) - - [Insert call example with `continueOnError` option](#insert-call-example-with-continueonerror-option) + - [Insert example with `continueOnError` option](#insert-example-with-continueonerror-option) - [Detokenize](#detokenize) - [Construct a detokenize request](#construct-a-detokenize-request) - [An example of a detokenize call](#an-example-of-a-detokenize-call) @@ -37,7 +33,7 @@ The Skyflow SDK for Node.js, Deno, Bun, and Cloudflare Workers. - [Get](#get) - [Construct a get request](#construct-a-get-request) - [Get by skyflow IDs](#get-by-skyflow-ids) - - [Get tokens](#get-tokens) + - [Get tokens for records](#get-tokens-for-records) - [An example of get call to retrieve tokens using Skyflow IDs:](#an-example-of-get-call-to-retrieve-tokens-using-skyflow-ids) - [Get by column name and column values](#get-by-column-name-and-column-values) - [An example of get call to retrieve data using column name and column values:](#an-example-of-get-call-to-retrieve-data-using-column-name-and-column-values) @@ -54,7 +50,7 @@ The Skyflow SDK for Node.js, Deno, Bun, and Cloudflare Workers. - [Upload File](#upload-file) - [An example of file upload call](#an-example-of-file-upload-call) - [Detect](#detect) - - [Deidentify Text](#deidentify-text) + - [Deidentify Text `deidentifyText()`](#deidentify-text-deidentifytext) - [An example of a deidentify text call](#an-example-of-a-deidentify-text-call) - [Reidentify Text](#reidentify-text) - [An example of a reidentify text call](#an-example-of-a-reidentify-text-call) @@ -63,22 +59,21 @@ The Skyflow SDK for Node.js, Deno, Bun, and Cloudflare Workers. - [Get run](#get-run) - [An example of a get run function](#an-example-of-a-get-run-function) - [Connections](#connections) - - [Invoke a connection](#invoke-a-connection) + - [Invoke a connection](#invoke-a-connection) - [Construct an invoke connection request](#construct-an-invoke-connection-request) - - [An example of Invoke Connection](#an-example-of-invoke-connection) - - [Authenticate with bearer tokens](#authenticate-with-bearer-tokens) + - [Governance, identity, and access control](#governance-identity-and-access-control) + - [Generate bearer tokens for authentication \& authorization](#generate-bearer-tokens-for-authentication--authorization) - [Generate a bearer token](#generate-a-bearer-token) - - [Example:](#example) + - [`generateBearerToken(filepath)`](#generatebearertokenfilepath) + - [`generateBearerTokenFromCreds(credentials)`](#generatebearertokenfromcredscredentials) - [Generate bearer tokens with context](#generate-bearer-tokens-with-context) - - [Example:](#example-1) - [Generate scoped bearer tokens](#generate-scoped-bearer-tokens) - - [Example:](#example-2) - [Generate signed data tokens](#generate-signed-data-tokens) - - [Example:](#example-3) - - [Bearer token expiry edge case](#bearer-token-expiry-edge-case) - - [Example:](#example-4) - - [Logging](#logging) - - [Reporting a Vulnerability](#reporting-a-vulnerability) + - [Logging \& error handling](#logging--error-handling) + - [Example `skyflowConfig.logLevel: LogLevel.INFO`](#example-skyflowconfigloglevel-loglevelinfo) + - [Bearer token expiration edge cases](#bearer-token-expiration-edge-cases) + - [Security](#security) + - [Reporting a Vulnerability](#reporting-a-vulnerability) ## Overview @@ -87,277 +82,150 @@ The Skyflow SDK enables you to connect to your Skyflow Vault(s) to securely hand > [!IMPORTANT] > This readme covers version 2 of the SDK. > For version 1 see the [v1.14.2 README](https://github.com/skyflowapi/skyflow-node/tree/1.14.2). -> For more information on how to migrate see [MIGRATE_TO_V2.md](MIGRATE_TO_v2.md). - -## Install +> For more information on how to migrate see [MIGRATE_TO_V2.md](docs/migrate_to_v2.md). -### Requirements +## Installation -- Node 12.22.12 and above +Requires Node v12.22.12 and above. ```sh npm install skyflow-node ``` -#### Import / Require - Depending on your project setup, you may use either the `require` method (common in Node.js projects) or the `import` statement (common in projects using ES modules). -##### Require +### Require ```typescript -const { Skyflow } = require('skyflow-node'); +const { Skyflow } = require("skyflow-node"); ``` -##### ES modules +### ES modules ```typescript -import { Skyflow } from 'skyflow-node'; +import { Skyflow } from "skyflow-node"; ``` -##### All imports +### All imports ```typescript import { - Skyflow, // Vault client - isExpired, // JWT auth helpers - LogLevel, // logging options -} from 'skyflow-node' + Skyflow, // Vault client + isExpired, // JWT auth helpers + LogLevel, // logging options +} from "skyflow-node"; ``` ## Quickstart + Get started quickly with the essential steps: authenticate, initialize the client, and perform a basic vault operation. This section provides a minimal setup to help you integrate the SDK efficiently. ### Authenticate -You can use an API key to authenticate and authorize requests to an API. For authenticating via bearer tokens and different supported bearer token types, refer to the [Authenticate with bearer tokens](#authenticate-with-bearer-tokens) section. + +You can use an API key to authenticate and authorize requests to an API. For authenticating via bearer tokens and different supported bearer token types, refer to the [Authenticate with bearer tokens](#authenticate-with-bearer-tokens) section. ```javascript // create a new credentials object -const credentials = { apiKey: "" }; //add your API key in credentials +const credentials = { apiKey: "" }; //add your API key in credentials ``` ### Initialize the client -To get started, you must first initialize the skyflow client. While initializing the skyflow client, you can specify different types of credentials. +To get started, you must first initialize the skyflow client. While initializing the skyflow client, you can specify different types of credentials. + 1. **API keys** -A unique identifier used to authenticate and authorize requests to an API. + A unique identifier used to authenticate and authorize requests to an API. 2. **Bearer tokens** -A temporary access token used to authenticate API requests, typically included in the -Authorization header. + A temporary access token used to authenticate API requests, typically included in the + Authorization header. 3. **Service account credentials file path** -The file path pointing to a JSON file containing credentials for a service account, used -for secure API access. + The file path pointing to a JSON file containing credentials for a service account, used + for secure API access. 4. **Service account credentials string** -JSON-formatted string containing service account credentials, often used as an alternative to a file for programmatic authentication. + JSON-formatted string containing service account credentials, often used as an alternative to a file for programmatic authentication. Note: Only one type of credential can be used at a time. If multiple credentials are provided, the last one added will take precedence. - ```javascript -import { - Credentials, - Env, - LogLevel, - Skyflow, - VaultConfig, - SkyflowConfig, -} from 'skyflow-node'; +import { Skyflow, SkyflowConfig, VaultConfig, Env, LogLevel } from 'skyflow-node'; -/* -Example program to initialize the Skyflow client with various configurations. -The Skyflow client facilitates secure interactions with the Skyflow vault, -such as securely managing sensitive data. -*/ - -// Step 1: Define the primary credentials for authentication. -// Note: Only one type of credential can be used at a time. You can choose between: -// - API key -// - Bearer token -// - A credentials string (JSON-formatted) -// - A file path to a credentials file. - -// Initialize primary credentials using a Bearer token for authentication. -const primaryCredentials: Credentials = { ///////////////// - token: '', // Replace with your actual authentication token. +// Configure credentials +const skyflowCredentials = { + clientID: '', + clientName: '', + tokenURI: '', + keyID: '', + privateKey: '' }; -// Step 2: Configure the primary vault details. -// VaultConfig stores all necessary details to connect to a specific Skyflow vault. - -const primaryVaultConfig: VaultConfig = { - vaultId: '', // Replace with your primary vault ID - clusterId: '', // Replace with the cluster ID (part of the vault URL, e.g., https://{clusterId}.vault.skyflowapis.com). - env: Env.PROD, // Set the environment (PROD, SANDBOX, STAGE, DEV). - credentials: primaryCredentials // Attach the primary credentials to this vault configuration. +// Configure vault +const vaultConfig: VaultConfig = { + vaultId: '', + clusterId: '', + env: Env.PROD }; -// Step 3: Create credentials as a JSON object (if a Bearer Token is not provided). -// Demonstrates an alternate approach to authenticate with Skyflow using a credentials object. -const skyflowCredentials: object = { - clientID: '', // Replace with your Client ID. - clientName: '', // Replace with your Client Name. - tokenURI: '', // Replace with the Token URI. - keyID: '', // Replace with your Key ID. - privateKey: '' // Replace with your Private Key. -} - -// Step 4: Convert the JSON object to a string and use it as credentials. -// This approach allows the use of dynamically generated or pre-configured credentials. -const credentialsString: JSON.stringify(skyflowCredentials), // Converts JSON object to string for use as credentials. - -// Step 5: Define secondary credentials (API key-based authentication as an example). -// Demonstrates a different type of authentication mechanism for Skyflow vaults. -const secondaryCredentials: Credentials = { - apiKey: '', // Replace with your API Key for authentication. -} - -// Step 6: Configure the secondary vault details. -// A secondary vault configuration can be used for operations involving multiple vaults. -const secondaryVaultConfig: VaultConfig = { - vaultId: '', // Replace with your secondary vault's ID. - clusterId: '', // Replace with the corresponding cluster ID. - env: Env.PROD, // Set the environment for this vault. - credentials: secondaryCredentials // Attach the secondary credentials to this configuration. -} - -// Step 7: Define tertiary credentials using a path to a credentials JSON file. -// This method demonstrates an alternative authentication method. -const tertiaryCredentials: Credentials = { - path: '' // Replace with the path to your credentials file. -} - -// Step 8: Configure the tertiary vault details. -const tertiaryVaultConfig: VaultConfig = { - vaultId: '', // Replace with the tertiary vault ID. - clusterId: '', // Replace with the corresponding cluster ID. - env: Env.PROD, // Set the environment for this vault. - credentials: tertiaryCredentials // Attach the tertiary credentials. -} - -// Step 9: Build and initialize the Skyflow client after creating Skyflow Config -// Skyflow client is configured with multiple vaults and credentials. - +// Initialize Skyflow client const skyflowConfig: SkyflowConfig = { - vaultConfigs: [primaryVaultConfig, secondaryVaultConfig, tertiaryVaultConfig], // Add the primary, secondary and tertiary vault configurations. - skyflowCredentials: skyflowCredentials, // Add JSON-formatted credentials if applicable. - logLevel: LogLevel.INFO // Recommended to use LogLevel.ERROR in production environment. + vaultConfigs: [vaultConfig], + skyflowCredentials: skyflowCredentials, + logLevel: LogLevel.ERROR }; -// Step 10: Initialize Skyflow Client const skyflowClient: Skyflow = new Skyflow(skyflowConfig); - -// The Skyflow client is now fully initialized. -// Use the `skyflowClient` object to perform secure operations such as: -// - Inserting data -// - Retrieving data -// - Deleting data -// within the configured Skyflow vaults. - ``` +For advanced initialization examples including multiple vaults and different credential types, see [docs/advanced_initialization.md](docs/advanced_initialization.md). + Notes + - If both Skyflow common credentials and individual credentials at the configuration level are specified, the individual credentials at the configuration level will take precedence. -- If neither Skyflow common credentials nor individual configuration-level credentials are provided, the SDK attempts to retrieve credentials from the ```SKYFLOW_CREDENTIALS``` environment variable. +- If neither Skyflow common credentials nor individual configuration-level credentials are provided, the SDK attempts to retrieve credentials from the `SKYFLOW_CREDENTIALS` environment variable. - All Vault operations require a client instance. ### Insert data into the vault -To insert data into your vault, use the `insert` method. The `InsertRequest` class creates an insert request, which includes the values to be inserted as a list of records. Below is a simple example to get started. For advanced options, check out [Insert data into the vault](#insert-data-into-the-vault-1) section. - -```javascript -import { - InsertOptions, - InsertRequest, - SkyflowError, - InsertResponse -} from 'skyflow-node'; - -/* -* This example demonstrates how to insert sensitive data (e.g., card information) into a Skyflow vault using the Skyflow client. -* -* 1. Initializes the Skyflow client. -* 2. Prepares a record with sensitive data (e.g., card number and cardholder name). -* 3. Creates an insert request for inserting the data into the Skyflow vault. -* 4. Prints the response of the insert operation. -*/ -try{ - // Step 1: Initialize data to be inserted into the Skyflow vault - const insertData: Record[] = [ - { - card_number: '4111111111111112', // Replace with actual card number (sensitive data) - cardholder_name: 'John Doe', // Replace with actual cardholder name (sensitive data) - } - ]; +To insert data into your vault, use the `insert` method. The `InsertRequest` class creates an insert request, which includes the values to be inserted as a list of records. Below is a simple example to get started. For advanced options, check out [Insert data into the vault](#insert-data-into-the-vault-1) section. - // Step 2: Create Insert Request - const insertReq: InsertRequest = new InsertRequest( - 'table1', // Specify the table in the vault where the data should be inserted - insertData, // Attach the data (records) to be inserted - - ); +```javascript +import { InsertRequest, InsertOptions } from 'skyflow-node'; - // Step 3: Configure Insertion Options - const insertOptions: InsertOptions = new InsertOptions(); - insertOptions.setReturnTokens(true); // Optional: Specify if tokens should be returned upon successful insertion - insertOptions.setContinueOnError(true); // Optional: Continue on partial errors +// Insert sensitive data into the vault +const insertData = [{ card_number: '4111111111111112', cardholder_name: 'John Doe' }]; +const insertReq = new InsertRequest('table1', insertData); - // Step 4: Perform the insert operation using the Skyflow client - const insertResponse: InsertResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) - .insert(insertReq, insertOptions); - - // Step 5: Print the response from the insert operation - console.log('Insert response: ', insertResponse); +const insertOptions = new InsertOptions(); +insertOptions.setReturnTokens(true); -} catch(error) { - // Step 6: Comprehensive Error Handling - if (error instanceof SkyflowError) { - console.error('Skyflow Specific Error:', { - code: error.error?.http_code, - message: error.message, - details: error.error?.details - }); - } else { - console.error('Unexpected Error:', error); - } -} -``` -Skyflow returns tokens for the record that was just inserted. +const insertResponse = await skyflowClient + .vault(vaultId) + .insert(insertReq, insertOptions); -```javascript -InsertResponse { - insertedFields: { - skyflowId: 'a8f3ed5d-55eb-4f32-bf7e-2dbf4b9d9097', - card_number: '5484-7829-1702-9110', - cardholder_name: 'b2308e2a-c1f5-469b-97b7-1f193159399b' - }, - errors: null -} +console.log('Insert response:', insertResponse); ``` ---- - ## Vault -The [Vault](https://github.com/skyflowapi/skyflow-node/tree/v2/src/vault) performs operations on the vault such as inserting records, detokenizing tokens, retrieving tokens for list of `skyflow_id`'s and to invoke the Connection. -### Insert data into the vault +The [Vault](https://docs.skyflow.com/docs/vaults) performs operations on the vault such as inserting records, detokenizing tokens, retrieving tokens for list of `skyflow_id`'s and to invoke the Connection. + +### Insert and tokenize data -Apart from using the `insert` method to insert data into your vault covered in [Quickstart](#quickstart), you can also pass options to `insert` method, such as returning tokenized data, upserting records, or continuing the operation in case of errors. +Apart from using the `insert` method to insert data into your vault covered in [Quickstart](#quickstart), you can also pass options to `insert` method to enable additional functionality such as returning tokenized data, upserting records, or allowing bulk operations to continue despite errors. #### Construct an insert request ```typescript import { - InsertOptions, + InsertOptions, InsertRequest, - SkyflowError, + SkyflowError, InsertResponse } from 'skyflow-node'; -// Example program to demonstrate inserting data into a Skyflow vault, +// Example program to demonstrate inserting data into a Skyflow vault, // along with corresponding InsertRequest schema. try { @@ -379,10 +247,10 @@ try { 'table1', // Specify the table in the vault where the data will be inserted insertData, // Attach the data (records) to be inserted ); - + // Step 3: Perform the insert operation using the Skyflow client const insertResponse: InsertResponse = await skyflowClient - .vault('') + .vault('') .insert(insertReq, insertOptions); // Replace with your actual vault ID @@ -402,108 +270,23 @@ try { } ``` -#### Insert call example with `continueOnError` option -The `continueOnError` flag is a boolean that determines whether insert operation should proceed despite encountering partial errors. Set to `true` to allow the process to continue even if some errors occur. - -```typescript -import { - InsertOptions, - InsertRequest, - SkyflowError, - InsertResponse -} from 'skyflow-node'; - -/* -This example demonstrates how to insert sensitive data (e.g., card information) into a Skyflow vault using the Skyflow client. - -1. Initializes the Skyflow client. -2. Prepares a record with sensitive data (e.g., card number and cardholder name). -3. Creates an insert request for inserting the data into the Skyflow vault. -4. Specifies options to continue on error and return tokens. -5. Prints the response of the insert operation. -*/ - -try { - // Initialize Skyflow client - // Step 1: Initialize a list to hold the data records to be inserted into the vault - const insertData: Record[] = [ - // Step 2: Create the first record with card number and cardholder name - { - card_number: '4111111111111111', // Replace with actual card number (sensitive data) - cardholder_name: 'John Doe', // Replace with actual cardholder name (sensitive data) - }, - //Step 3: Create the second record with card number and cardholder name - { - card_number: '4111111111111111', // Replace with actual card number (sensitive data) - cardholder_name: 'John Doe', // Replace with actual cardholder name (sensitive data) - } - ]; - - // Step 4: Create Insert Request - const insertReq: InsertRequest = new InsertRequest( - 'table1', // Specify the table in the vault where the data should be inserted - insertData, // Attach the data (records) to be inserted - ); - - // Step 5: Configure Insertion Options - const insertOptions: InsertOptions = new InsertOptions(); - insertOptions.setReturnTokens(true); // Optional: Specify if tokens should be returned upon successful insertion - insertOptions.setContinueOnError(true); // Optional: Specify to continue inserting records even if an error occurs for some records partial errors - - // Step 6: Perform the insert operation using the Skyflow client - const insertResponse: InsertResponse = await skyflowClient - .vault('9f27764a10f7946fe56b3258e117') - .insert(insertReq, insertOptions); - // Replace the vault ID "9f27764a10f7946fe56b3258e117" with your actual Skyflow vault ID +#### Insert example with `continueOnError` option - // Step 7: Print the response from the insert operation - console.log('Insert response: ', insertResponse); -} catch(error) { - // Step 8: Comprehensive Error Handling - if (error instanceof SkyflowError) { - console.error('Skyflow Specific Error:', { - code: error.error?.http_code, - message: error.message, - details: error.error?.details - }); - } else { - console.error('Unexpected Error:', error); - } -} -``` +The `continueOnError` flag is a boolean that determines whether insert operation should proceed despite encountering partial errors. Set to `true` to allow the process to continue even if some errors occur. -Sample Response -```typescript -InsertResponse { - insertedFields: { - [ - { - card_number: '5484-7829-1702-9110', - requestIndex: 0, - skyflowId: '9fac9201-7b8a-4446-93f8-5244e1213bd1', - cardholder_name: 'b2308e2a-c1f5-469b-97b7-1f193159399' - } - ], - errors: [ - { - requestIndex: 1, - error: 'Insert failed. Column card_number is invalid. Specify a valid column.' - } - ] - } -} -``` +> [!TIP] +> See the full example in the samples directory: [insert-continue-on-error.ts](samples/vault-api/insert-continue-on-error.ts) **Insert call example with `upsert` option** An upsert operation checks for a record based on a unique column's value. If a match exists, the record is updated; otherwise, a new record is inserted. ```typescript import { - InsertOptions, - InsertRequest, - SkyflowError, - InsertResponse -} from 'skyflow-node'; + InsertOptions, + InsertRequest, + SkyflowError, + InsertResponse, +} from "skyflow-node"; /* This example demonstrates how to insert sensitive data (e.g., card information) into a Skyflow vault using the Skyflow client. @@ -521,38 +304,38 @@ try { const insertData: Record[] = [ // Step 2: Create a record with the field 'cardholder_name' to insert or upsert { - cardholder_name: 'John Doe', // Replace with actual cardholder name - } - ] + cardholder_name: "John Doe", // Replace with actual cardholder name + }, + ]; // Step 3: Create Insert Request const insertReq: InsertRequest = new InsertRequest( - 'table1', // Specify the table in the vault where the data will be inserted - insertData, // Attach the data (records) to be inserted + "table1", // Specify the table in the vault where the data will be inserted + insertData, // Attach the data (records) to be inserted ); - + // Step 4: Set upsert column by configuring the insertion options const insertOptions: InsertOptions = new InsertOptions(); - insertOptions.setReturnTokens(true); // Optional: Specify if tokens should be returned upon successful insertion - insertOptions.setUpsertColumn('cardholder_name'); + insertOptions.setReturnTokens(true); // Optional: Specify if tokens should be returned upon successful insertion + insertOptions.setUpsertColumn("cardholder_name"); // Step 5: Perform the insert/upsert operation using the Skyflow client const insertResponse: InsertResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) - .insert(insertReq, insertOptions); + .vault(primaryVaultConfig.vaultId) + .insert(insertReq, insertOptions); // Step 6: Print the response from the insert operation - console.log('Insert response: ', insertResponse); -} catch(error) { + console.log("Insert response: ", insertResponse); +} catch (error) { // Step 7: Comprehensive Error Handling if (error instanceof SkyflowError) { - console.error('Skyflow Specific Error:', { - code: error.error?.http_code, - message: error.message, - details: error.error?.details - }); + console.error("Skyflow Specific Error:", { + code: error.error?.http_code, + message: error.message, + details: error.error?.details, + }); } else { - console.error('Unexpected Error:', error); + console.error("Unexpected Error:", error); } } ``` @@ -576,14 +359,15 @@ InsertResponse { To retrieve tokens from your vault, use the `detokenize` method. The `DetokenizeRequest` class requires a list of detokenization data as input. Additionally, you can provide optional parameters, such as the redaction type and the option to continue on error. #### Construct a detokenize request + ```typescript import { - DetokenizeOptions, - DetokenizeRequest, - DetokenizeResponse, - DetokenizeData, - SkyflowError, -} from 'skyflow-node'; + DetokenizeOptions, + DetokenizeRequest, + DetokenizeResponse, + DetokenizeData, + SkyflowError, +} from "skyflow-node"; /* This example demonstrates how to detokenize sensitive data from tokens stored in a Skyflow vault, along with corresponding DetokenizeRequest schema. @@ -593,42 +377,42 @@ try { // Step 1: Prepare Detokenization Data const detokenizeData: DetokenizeData[] = [ { - token: "token1", // Token to be detokenized - redactionType: RedactionType.PLAIN_TEXT, // Redaction type + token: "token1", // Token to be detokenized + redactionType: RedactionType.PLAIN_TEXT, // Redaction type }, { - token: "token2", // Token to be detokenized - redactionType: RedactionType.PLAIN_TEXT, // Redaction type + token: "token2", // Token to be detokenized + redactionType: RedactionType.PLAIN_TEXT, // Redaction type }, - ]; + ]; // Step 2: Create the DetokenizeRequest object with the tokens data const detokenizeRequest: DetokenizeRequest = new DetokenizeRequest( - detokenizeData + detokenizeData, ); // Step 3: Configure Detokenize Options const detokenizeOptions: DetokenizeOptions = new DetokenizeOptions(); detokenizeOptions.setContinueOnError(true); // Continue processing on errors - detokenizeOptions.setDownloadURL(false); // Disable download URL generation + detokenizeOptions.setDownloadURL(false); // Disable download URL generation // Step 4: Perform Detokenization const response: DetokenizeResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) - .detokenize(detokenizeRequest, detokenizeOptions); + .vault(primaryVaultConfig.vaultId) + .detokenize(detokenizeRequest, detokenizeOptions); // Handle Successful Response - console.log('Detokenization response:', response); -} catch(error) { + console.log("Detokenization response:", response); +} catch (error) { // Comprehensive Error Handling if (error instanceof SkyflowError) { - console.error('Skyflow Specific Error:', { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); + console.error("Skyflow Specific Error:", { + code: error.error?.http_code, + message: error.message, + details: error.error?.details, + }); } else { - console.error('Unexpected Error:', error); + console.error("Unexpected Error:", error); } } ``` @@ -642,12 +426,12 @@ Notes: ```typescript import { - DetokenizeOptions, - DetokenizeRequest, - DetokenizeResponse, - DetokenizeData, - SkyflowError, -} from 'skyflow-node'; + DetokenizeOptions, + DetokenizeRequest, + DetokenizeResponse, + DetokenizeData, + SkyflowError, +} from "skyflow-node"; /* 1. Initializes the Skyflow client. @@ -661,18 +445,18 @@ try { // Step 1: Prepare Detokenization Data const detokenizeData: DetokenizeData[] = [ { - token: "9738-1683-0486-1480", // Replace with your actual token value - redactionType: RedactionType.PLAIN_TEXT, // Redaction type + token: "9738-1683-0486-1480", // Replace with your actual token value + redactionType: RedactionType.PLAIN_TEXT, // Redaction type }, { - token: "6184-6357-8409-6668", // Replace with your actual token value - redactionType: RedactionType.PLAIN_TEXT, // Redaction type + token: "6184-6357-8409-6668", // Replace with your actual token value + redactionType: RedactionType.PLAIN_TEXT, // Redaction type }, - ]; + ]; // Step 2: Create the DetokenizeRequest object with the tokens data const detokenizeRequest: DetokenizeRequest = new DetokenizeRequest( - detokenizeData + detokenizeData, ); // Step 3: Configure Detokenize Options @@ -681,21 +465,21 @@ try { // Step 4: Perform Detokenization const response: DetokenizeResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) - .detokenize(detokenizeRequest, detokenizeOptions); + .vault(primaryVaultConfig.vaultId) + .detokenize(detokenizeRequest, detokenizeOptions); // Handle Successful Response - console.log('Detokenization response:', response); -} catch(error) { + console.log("Detokenization response:", response); +} catch (error) { // Comprehensive Error Handling if (error instanceof SkyflowError) { - console.error('Skyflow Specific Error:', { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); + console.error("Skyflow Specific Error:", { + code: error.error?.http_code, + message: error.message, + details: error.error?.details, + }); } else { - console.error('Unexpected Error:', error); + console.error("Unexpected Error:", error); } } ``` @@ -716,12 +500,12 @@ DetokenizeResponse { ```typescript import { - DetokenizeOptions, - DetokenizeRequest, - DetokenizeResponse, - DetokenizeData, - SkyflowError, -} from 'skyflow-node'; + DetokenizeOptions, + DetokenizeRequest, + DetokenizeResponse, + DetokenizeData, + SkyflowError, +} from "skyflow-node"; /* 1. Initializes the Skyflow client. @@ -735,23 +519,23 @@ try { // Step 1: Prepare Detokenization Data const detokenizeData: DetokenizeData[] = [ { - token: "9738-1683-0486-1480", // Replace with your actual token value - redactionType: RedactionType.PLAIN_TEXT, // Redaction type + token: "9738-1683-0486-1480", // Replace with your actual token value + redactionType: RedactionType.PLAIN_TEXT, // Redaction type }, { - token: "6184-6357-8409-6668", // Replace with your actual token value - redactionType: RedactionType.PLAIN_TEXT, // Redaction type + token: "6184-6357-8409-6668", // Replace with your actual token value + redactionType: RedactionType.PLAIN_TEXT, // Redaction type }, { - token: "4914-9088-2814-3840", // Replace with your actual token value - redactionType: RedactionType.PLAIN_TEXT, // Redaction type + token: "4914-9088-2814-3840", // Replace with your actual token value + redactionType: RedactionType.PLAIN_TEXT, // Redaction type }, - ]; + ]; // Step 2: Create the DetokenizeRequest object with the tokens and redaction type const detokenizeRequest: DetokenizeRequest = new DetokenizeRequest( - detokenizeData, - redactionType + detokenizeData, + redactionType, ); // Step 3: Configure Detokenize Options @@ -760,21 +544,21 @@ try { // Step 5: Perform Detokenization const response: DetokenizeResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) - .detokenize(detokenizeRequest, detokenizeOptions); + .vault(primaryVaultConfig.vaultId) + .detokenize(detokenizeRequest, detokenizeOptions); // Handle Successful Response - console.log('Detokenization response:', response); -} catch(error) { + console.log("Detokenization response:", response); +} catch (error) { // Comprehensive Error Handling if (error instanceof SkyflowError) { - console.error('Skyflow Specific Error:', { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); + console.error("Skyflow Specific Error:", { + code: error.error?.http_code, + message: error.message, + details: error.error?.details, + }); } else { - console.error('Unexpected Error:', error); + console.error("Unexpected Error:", error); } } ``` @@ -806,18 +590,18 @@ To tokenize data, use the `tokenize` method. The `TokenizeRequest` class creates ```typescript import { - TokenizeRequest, - TokenizeResponse, - SkyflowError, - TokenizeRequestType -} from 'skyflow-node'; + TokenizeRequest, + TokenizeResponse, + SkyflowError, + TokenizeRequestType, +} from "skyflow-node"; try { // Initialize Skyflow Client // Step 1: Prepare Tokenization Data const columnValues: Array = [ - { value: "", columnGroup: "" }, // Replace and with actual data - { value: "", columnGroup: "" } // Replace and with actual data + { value: "", columnGroup: "" }, // Replace and with actual data + { value: "", columnGroup: "" }, // Replace and with actual data ]; // Step 2: Build the TokenizeRequest with the column values @@ -825,22 +609,22 @@ try { // Step 3: Call the Skyflow vault to tokenize the sensitive data const response: TokenizeResponse = await skyflowClient - .vault("") - .tokenize(tokenReq); + .vault("") + .tokenize(tokenReq); // Replace with your actual Skyflow vault ID // Step 4: Print the tokenization response, which contains the generated tokens or errors - console.log('Tokenization Result:', response); -} catch(error) { + console.log("Tokenization Result:", response); +} catch (error) { // Step 5: Handle any errors that occur during the tokenization process if (error instanceof SkyflowError) { - console.error('Skyflow Specific Error:', { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); + console.error("Skyflow Specific Error:", { + code: error.error?.http_code, + message: error.message, + details: error.error?.details, + }); } else { - console.error('Unexpected Error:', error); + console.error("Unexpected Error:", error); } } ``` @@ -849,11 +633,11 @@ try { ```typescript import { - TokenizeRequest, - TokenizeResponse, - SkyflowError, - TokenizeRequestType -} from 'skyflow-node'; + TokenizeRequest, + TokenizeResponse, + SkyflowError, + TokenizeRequestType, +} from "skyflow-node"; /* This example demonstrates how to tokenize sensitive data (e.g., credit card information) using the Skyflow client. @@ -869,7 +653,7 @@ try { // Initialize Skyflow Client // Step 1: Prepare Tokenization Data const columnValues: Array = [ - { value: "4111111111111111", columnGroup: "card_number_cg" } + { value: "4111111111111111", columnGroup: "card_number_cg" }, ]; // Step 2: Build the TokenizeRequest with the column values @@ -877,21 +661,21 @@ try { // Step 3: Call the Skyflow vault to tokenize the sensitive data const response: TokenizeResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) - .tokenize(tokenReq); + .vault(primaryVaultConfig.vaultId) + .tokenize(tokenReq); // Replace primaryVaultConfig.vaultId with your actual Skyflow vault ID // Step 4: Print the tokenization response, which contains the generated tokens or errors - console.log('Tokenization Result:', response); -} catch(error) { + console.log("Tokenization Result:", response); +} catch (error) { if (error instanceof SkyflowError) { - console.error('Skyflow Specific Error:', { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); + console.error("Skyflow Specific Error:", { + code: error.error?.http_code, + message: error.message, + details: error.error?.details, + }); } else { - console.error('Unexpected Error:', error); + console.error("Unexpected Error:", error); } } ``` @@ -917,22 +701,22 @@ To retrieve data using Skyflow IDs or unique column values, use the get method. ```typescript import { - GetOptions, - GetRequest, - GetColumnRequest, - SkyflowError, - GetResponse -} from 'skyflow-node'; + GetOptions, + GetRequest, + GetColumnRequest, + SkyflowError, + GetResponse, +} from "skyflow-node"; try { // Initialize Skyflow client // Step 1: Initialize a list of Skyflow IDs to retrieve records (replace with actual Skyflow IDs) - const getIds: Array = ['', '']; - + const getIds: Array = ["", ""]; + // Step 2: Create a GetRequest to retrieve records by Skyflow ID const getRequest: GetRequest = new GetRequest( - 'table1', // Replace with your actual table name - getIds + "table1", // Replace with your actual table name + getIds, ); // Step 3: Configure Get Options and specify not to return tokens @@ -941,16 +725,16 @@ try { // Step 4: Send the request to the Skyflow vault and retrieve the records const getResponse: GetResponse = await skyflowClient - .vault('') - .get(getRequest, getOptions); + .vault("") + .get(getRequest, getOptions); // Replace with your actual Skyflow vault ID - console.log('Data retrieval successful:', getResponse); + console.log("Data retrieval successful:", getResponse); // Step 5: Create another GetRequest to retrieve records by Skyflow ID with tokenized values const getTokensRequest: GetRequest = new GetRequest( - 'table1', // Replace with your actual table name - getIds + "table1", // Replace with your actual table name + getIds, ); // Step 6: Configure Get Options and specify to return tokens @@ -959,61 +743,62 @@ try { // Step 7: Send the request to the Skyflow vault and retrieve the tokenized records const getTokensResponse: GetResponse = await skyflowClient - .vault('') - .get(getRequest, getOptions); + .vault("") + .get(getRequest, getOptions); // Replace with your actual Skyflow vault ID - console.log('Data retrieval successful:', getTokensResponse); + console.log("Data retrieval successful:", getTokensResponse); // Prepare Column-Based Retrieval Data const columnValues: Array = [ - '', // Example Unique Column value 1 - '', // Example Unique Column value 2 + "", // Example Unique Column value 1 + "", // Example Unique Column value 2 ]; - const tableName: string = 'table-name'; // Replace with your actual table name - const columnName: string = 'column-name'; // Column name configured as unique in the schema + const tableName: string = "table-name"; // Replace with your actual table name + const columnName: string = "column-name"; // Column name configured as unique in the schema const getRequest: GetColumnRequest = new GetColumnRequest( - tableName, - columnName, - columnValues // Column values of the records to return - ); + tableName, + columnName, + columnValues, // Column values of the records to return + ); // Step 8: Configure Get Options and specify to return tokens const getOptions: GetOptions = new GetOptions(); getOptions.setReturnTokens(true); // Optional: Set to True to return tokenized values - + // Send the request to the Skyflow vault and retrieve the filtered records const response: GetResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) - .get(getRequest, getOptions); + .vault(primaryVaultConfig.vaultId) + .get(getRequest, getOptions); - console.log('Column-based retrieval successful:', response); -} catch(error) { + console.log("Column-based retrieval successful:", response); +} catch (error) { // Handle any errors that occur during the retrieval process if (error instanceof SkyflowError) { - console.error('Skyflow Specific Error:', { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); + console.error("Skyflow Specific Error:", { + code: error.error?.http_code, + message: error.message, + details: error.error?.details, + }); } else { - console.error('Unexpected Error:', error); + console.error("Unexpected Error:", error); } } ``` #### Get by skyflow IDs + Retrieve specific records using skyflow `ids`. Ideal for fetching exact records when IDs are known. ```typescript import { - GetOptions, - GetRequest, - SkyflowError, - GetResponse, - RedactionType -} from 'skyflow-node'; + GetOptions, + GetRequest, + SkyflowError, + GetResponse, + RedactionType, +} from "skyflow-node"; /* This example demonstrates how to retrieve data from the Skyflow vault using a list of Skyflow IDs. @@ -1028,12 +813,15 @@ This example demonstrates how to retrieve data from the Skyflow vault using a li try { // Initialize Skyflow client // Step 1: Initialize a list of Skyflow IDs to retrieve records (replace with actual Skyflow IDs) - const getIds: Array = ['a581d205-1969-4350-acbe-a2a13eb871a6', '5ff887c3-b334-4294-9acc-70e78ae5164a']; - + const getIds: Array = [ + "a581d205-1969-4350-acbe-a2a13eb871a6", + "5ff887c3-b334-4294-9acc-70e78ae5164a", + ]; + // Step 2: Create a GetRequest to retrieve records by Skyflow ID const getRequest: GetRequest = new GetRequest( - 'table1', // Replace with your actual table name - getIds + "table1", // Replace with your actual table name + getIds, ); // Step 3: Configure Get Options and specify not to return tokens and redaction type @@ -1043,21 +831,21 @@ try { // Step 4: Send the request to the Skyflow vault and retrieve the records const getResponse: GetResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) - .get(getRequest, getOptions); + .vault(primaryVaultConfig.vaultId) + .get(getRequest, getOptions); // Replace with your actual Skyflow vault ID - console.log('Data retrieval successful:', getResponse); -} catch(error) { + console.log("Data retrieval successful:", getResponse); +} catch (error) { // Step 5: Handle any errors that occur during the retrieval process if (error instanceof SkyflowError) { - console.error('Skyflow Specific Error:', { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); + console.error("Skyflow Specific Error:", { + code: error.error?.http_code, + message: error.message, + details: error.error?.details, + }); } else { - console.error('Unexpected Error:', error); + console.error("Unexpected Error:", error); } } ``` @@ -1084,60 +872,54 @@ GetResponse { } ``` -#### Get tokens +#### Get tokens for records + Return tokens for records. Ideal for securely processing sensitive data while maintaining data privacy. #### An [example](https://github.com/skyflowapi/skyflow-node/blob/v2/samples/vault-api/get-records.ts) of get call to retrieve tokens using Skyflow IDs: ```typescript import { - GetOptions, - GetRequest, - SkyflowError, - GetResponse, - RedactionType -} from 'skyflow-node'; + GetOptions, + GetRequest, + SkyflowError, + GetResponse, + RedactionType, +} from "skyflow-node"; -/* -This example demonstrates how to retrieve data from the Skyflow vault and return tokens along with the records. +try { + // Assemble your IDs + const getIds: Array = [ + "a581d205-1969-4350-acbe-a2a13eb871a6", + "5ff887c3-b334-4294-9acc-70e78ae5164a", + ]; -1. Initializes the Skyflow client with a given vault ID. -2. Creates a request to retrieve records based on Skyflow IDs and ensures tokens are returned. -3. Prints the response to display the retrieved records along with the tokens. -*/ + // Create a GetRequest to retrieve records by table name and Skyflow IDs + const getRequest: GetRequest = new GetRequest( + "table1", // Table name + getIds, // Array of ID strings + ); -try { - // Initialize Skyflow client - // Step 1: Initialize a list of Skyflow IDs to retrieve records (replace with actual Skyflow IDs) - const getIds: Array = ['a581d205-1969-4350-acbe-a2a13eb871a6', '5ff887c3-b334-4294-9acc-70e78ae5164a']; - - // Step 2: Create a GetRequest to retrieve records by Skyflow ID - const getRequest: GetRequest = new GetRequest( - 'table1', // Replace with your actual table name - getIds - ); - - // Step 3: Configure Get Options and specify not to return tokens and redaction type + // Create a GetOptions and request tokens const getOptions: GetOptions = new GetOptions(); - getOptions.setReturnTokens(false); // Optional: Set to true to get tokens + getOptions.setReturnTokens(true); // Optional: Set to true to get tokens - // Step 4: Send the request to the Skyflow vault and retrieve the records + // Send the request to the Skyflow vault and retrieve the records const getResponse: GetResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) - .get(getRequest, getOptions); - // Replace with your actual Skyflow vault ID + .vault(primaryVaultConfig.vaultId) + .get(getRequest, getOptions); - console.log('Data retrieval successful:', getResponse); -} catch(error) { - // Step 5: Handle any errors that occur during the retrieval process + console.log("Data retrieval successful:", getResponse); +} catch (error) { + // Handle any errors that occur during the retrieval process if (error instanceof SkyflowError) { - console.error('Skyflow Specific Error:', { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); + console.error("Skyflow Specific Error:", { + code: error.error?.http_code, + message: error.message, + details: error.error?.details, + }); } else { - console.error('Unexpected Error:', error); + console.error("Unexpected Error:", error); } } ``` @@ -1165,19 +947,20 @@ GetResponse { ``` #### Get by column name and column values + Retrieve records by unique column values. Ideal for querying data without knowing Skyflow IDs, using alternate unique identifiers. #### An [example](https://github.com/skyflowapi/skyflow-node/blob/v2/samples/vault-api/get-column-values.ts) of get call to retrieve data using column name and column values: ```typescript import { - GetOptions, - GetRequest, - SkyflowError, - GetResponse, - RedactionType, - GetColumnRequest -} from 'skyflow-node'; + GetOptions, + GetRequest, + SkyflowError, + GetResponse, + RedactionType, + GetColumnRequest, +} from "skyflow-node"; /* This example demonstrates how to retrieve data from the Skyflow vault based on column values. @@ -1191,39 +974,39 @@ try { // Initialize Skyflow client // Step 1: Initialize a list of column values (email addresses in this case) const columnValues: Array = [ - 'john.doe@gmail.com', // Example email address - 'jane.doe@gmail.com' , // Example email address + "john.doe@gmail.com", // Example email address + "jane.doe@gmail.com", // Example email address ]; - const tableName: string = 'table1'; // Replace with your actual table name - const columnName: string = 'email'; // Column name configured as unique in the schema + const tableName: string = "table1"; // Replace with your actual table name + const columnName: string = "email"; // Column name configured as unique in the schema // Step 2: Create a GetRequest to retrieve records based on column values const getRequest: GetColumnRequest = new GetColumnRequest( - tableName, - columnName, - columnValues // Column values of the records to return - ); + tableName, + columnName, + columnValues, // Column values of the records to return + ); // Step 3: Configure Get Options and specify redaction type const getOptions: GetOptions = new GetOptions(); getOptions.setRedactionType(RedactionType.PLAIN_TEXT); // Optional: Set the redaction type (e.g., PLAIN_TEXT) - + // Step 4: Send the request to the Skyflow vault and retrieve the filtered records const response: GetResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) - .get(getRequest, getOptions); + .vault(primaryVaultConfig.vaultId) + .get(getRequest, getOptions); - console.log('Column-based retrieval successful:', response); -} catch(error) { + console.log("Column-based retrieval successful:", response); +} catch (error) { // Step 5: Handle any errors that occur during the retrieval process if (error instanceof SkyflowError) { - console.error('Skyflow Specific Error:', { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); + console.error("Skyflow Specific Error:", { + code: error.error?.http_code, + message: error.message, + details: error.error?.details, + }); } else { - console.error('Unexpected Error:', error); + console.error("Unexpected Error:", error); } } ``` @@ -1250,8 +1033,9 @@ GetResponse { } ``` -#### Redaction Types -Redaction types determine how sensitive data is displayed when retrieved from the vault. +#### Redaction Types + +Redaction types determine how sensitive data is displayed when retrieved from the vault. **Available Redaction Types** @@ -1261,6 +1045,7 @@ Redaction types determine how sensitive data is displayed when retrieved from th - `PLAIN_TEXT`: Displays the full, unmasked data. **Choosing the Right Redaction Type** + - Use `REDACTED` for scenarios requiring maximum data protection to prevent exposure of sensitive information. - 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. @@ -1273,9 +1058,9 @@ To update data in your vault, use the `update` method. The `UpdateRequest` class ```typescript import { - UpdateRequest, - UpdateOptions, - UpdateResponse, + UpdateRequest, + UpdateOptions, + UpdateResponse, SkyflowError, TokenMode } from 'skyflow-node'; @@ -1313,7 +1098,7 @@ try { const response: UpdateResponse = await skyflowClient .vault(primaryVaultConfig.vaultId) .update(updateReq, updateOptions); - + // Step 6: Print the response to confirm the update result console.log('Update successful:', response); } catch(error) { @@ -1334,9 +1119,9 @@ try { ```typescript import { - UpdateRequest, - UpdateOptions, - UpdateResponse, + UpdateRequest, + UpdateOptions, + UpdateResponse, SkyflowError, TokenMode } from 'skyflow-node'; @@ -1380,7 +1165,7 @@ try { const response: UpdateResponse = await skyflowClient .vault(primaryVaultConfig.vaultId) .update(updateReq, updateOptions); - + // Step 6: Print the response to confirm the update result console.log('Update successful:', response); } catch(error) { @@ -1400,6 +1185,7 @@ try { Sample response: - When `returnTokens` is set to `True` + ```typescript UpdateResponse { updatedField: { @@ -1412,6 +1198,7 @@ UpdateResponse { ``` - When `returnTokens` is set to `False` + ```typescript UpdateResponse { updatedField: { @@ -1428,11 +1215,7 @@ To delete records using Skyflow IDs, use the `delete` method. The `DeleteRequest #### Construct a delete request ```typescript -import { - DeleteRequest, - DeleteResponse, - SkyflowError -} from 'skyflow-node'; +import { DeleteRequest, DeleteResponse, SkyflowError } from "skyflow-node"; /* This example demonstrates how to delete records from a Skyflow vault using specified Skyflow IDs, along with corresponding DeleteRequest schema. @@ -1442,43 +1225,41 @@ try { // Initialize Skyflow client // Step 1: Prepare a list of Skyflow IDs for the records to delete // The list stores the Skyflow IDs of the records that need to be deleted from the vault - const deleteIds: Array = ['', '', '']; // Replace with actual Skyflow IDs - const tableName: string = ''; // Replace with the actual table name from which to delete + const deleteIds: Array = [ + "", + "", + "", + ]; // Replace with actual Skyflow IDs + const tableName: string = ""; // Replace with the actual table name from which to delete // Step 2: Create a DeleteRequest to define the delete operation - const deleteRequest: DeleteRequest = new DeleteRequest( - tableName, - deleteIds - ); + const deleteRequest: DeleteRequest = new DeleteRequest(tableName, deleteIds); // Step 3: Send the delete request to the Skyflow vault const response: DeleteResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) - .delete(deleteRequest); + .vault(primaryVaultConfig.vaultId) + .delete(deleteRequest); - // Print the response to confirm the delete result - console.log('Deletion successful:', response); -} catch(error) { + // Print the response to confirm the delete result + console.log("Deletion successful:", response); +} catch (error) { // Step 4: Handle any exceptions that occur during the delete operation if (error instanceof SkyflowError) { - console.error('Skyflow Specific Error:', { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); + console.error("Skyflow Specific Error:", { + code: error.error?.http_code, + message: error.message, + details: error.error?.details, + }); } else { - console.error('Unexpected Error:', error); + console.error("Unexpected Error:", error); } } ``` + #### An [example](https://github.com/skyflowapi/skyflow-node/blob/v2/samples/vault-api/delete-records.ts) of delete call ```typescript -import { - DeleteRequest, - DeleteResponse, - SkyflowError -} from 'skyflow-node'; +import { DeleteRequest, DeleteResponse, SkyflowError } from "skyflow-node"; /* This example demonstrates how to delete records from a Skyflow vault using specified Skyflow IDs. @@ -1493,32 +1274,33 @@ try { // Initialize Skyflow client // Step 1: Prepare a list of Skyflow IDs for the records to delete // The list stores the Skyflow IDs of the records that need to be deleted from the vault - const deleteIds: Array = ['9cbf66df-6357-48f3-b77b-0f1acbb69280', 'ea74bef4-f27e-46fe-b6a0-a28e91b4477b', '47700796-6d3b-4b54-9153-3973e281cafb']; // Replace with actual Skyflow IDs - const tableName: string = 'table1'; // Replace with the actual table name from which to delete + const deleteIds: Array = [ + "9cbf66df-6357-48f3-b77b-0f1acbb69280", + "ea74bef4-f27e-46fe-b6a0-a28e91b4477b", + "47700796-6d3b-4b54-9153-3973e281cafb", + ]; // Replace with actual Skyflow IDs + const tableName: string = "table1"; // Replace with the actual table name from which to delete // Step 2: Create a DeleteRequest to define the delete operation - const deleteRequest: DeleteRequest = new DeleteRequest( - tableName, - deleteIds - ); + const deleteRequest: DeleteRequest = new DeleteRequest(tableName, deleteIds); // Step 3: Send the delete request to the Skyflow vault const response: DeleteResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) - .delete(deleteRequest); + .vault(primaryVaultConfig.vaultId) + .delete(deleteRequest); - // Print the response to confirm the delete result - console.log('Deletion successful:', response); -} catch(error) { + // Print the response to confirm the delete result + console.log("Deletion successful:", response); +} catch (error) { // Step 4: Handle any exceptions that occur during the delete operation if (error instanceof SkyflowError) { - console.error('Skyflow Specific Error:', { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); + console.error("Skyflow Specific Error:", { + code: error.error?.http_code, + message: error.message, + details: error.error?.details, + }); } else { - console.error('Unexpected Error:', error); + console.error("Unexpected Error:", error); } } ``` @@ -1541,14 +1323,11 @@ DeleteResponse { To retrieve data with SQL queries, use the `query` method. `QueryRequest` is class that takes the `query` parameter as follows: #### Construct a query request + Refer to [Query your data](https://docs.skyflow.com/query-data/) and [Execute Query](https://docs.skyflow.com/record/#QueryService_ExecuteQuery) for guidelines and restrictions on supported SQL statements, operators, and keywords. ```typescript -import { - QueryRequest, - QueryResponse, - SkyflowError, -} from 'skyflow-node'; +import { QueryRequest, QueryResponse, SkyflowError } from "skyflow-node"; /* This example demonstrates how to execute a custom SQL query on a Skyflow vault, along with QueryRequest schema. @@ -1559,27 +1338,27 @@ try { // Step 1: Define the SQL query to execute on the Skyflow vault // Replace "" with the actual SQL query you want to run const query: string = ""; // Example: "SELECT * FROM table1 WHERE column1 = 'value'" - + // Step 2: Create a QueryRequest with the specified SQL query const queryRequest: QueryRequest = new QueryRequest(query); // Step 3: Execute the query request on the specified Skyflow vault const response: QueryResponse = await skyflowClient - .vault('') // Replace with your actual Vault ID - .query(queryRequest); + .vault("") // Replace with your actual Vault ID + .query(queryRequest); // Step 4: Print the response containing the query results - console.log('Query Result:', response); -} catch(error) { + console.log("Query Result:", response); +} catch (error) { // Step 5: Handle any exceptions that occur during the query execution if (error instanceof SkyflowError) { - console.error('Skyflow Specific Error:', { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); + console.error("Skyflow Specific Error:", { + code: error.error?.http_code, + message: error.message, + details: error.error?.details, + }); } else { - console.error('Unexpected Error:', error); + console.error("Unexpected Error:", error); } } ``` @@ -1587,11 +1366,7 @@ try { #### An [example](https://github.com/skyflowapi/skyflow-node/blob/v2/samples/vault-api/query-records.ts) of query call ```typescript -import { - QueryRequest, - QueryResponse, - SkyflowError, -} from 'skyflow-node'; +import { QueryRequest, QueryResponse, SkyflowError } from "skyflow-node"; /* This example demonstrates how to execute a SQL query on a Skyflow vault to retrieve data. @@ -1606,28 +1381,29 @@ try { // Initialize Skyflow client // Step 1: Define the SQL query to execute on the Skyflow vault // Example query: Retrieve all records from the "cards" table with a specific skyflow_id - const query: string = "SELECT * FROM cards WHERE skyflow_id='3ea3861-x107-40w8-la98-106sp08ea83f'"; - + const query: string = + "SELECT * FROM cards WHERE skyflow_id='3ea3861-x107-40w8-la98-106sp08ea83f'"; + // Step 2: Create a QueryRequest with the specified SQL query const queryRequest: QueryRequest = new QueryRequest(query); // Step 3: Execute the query request on the specified Skyflow vault const response: QueryResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) // Replace with actual Vault ID - .query(queryRequest); + .vault(primaryVaultConfig.vaultId) // Replace with actual Vault ID + .query(queryRequest); // Step 4: Print the response containing the query results - console.log('Query Result:', response); -} catch(error) { + console.log("Query Result:", response); +} catch (error) { // Step 5: Handle any exceptions that occur during the query execution if (error instanceof SkyflowError) { - console.error('Skyflow Specific Error:', { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); + console.error("Skyflow Specific Error:", { + code: error.error?.http_code, + message: error.message, + details: error.error?.details, + }); } else { - console.error('Unexpected Error:', error); + console.error("Unexpected Error:", error); } } ``` @@ -1654,13 +1430,13 @@ To upload files to a Skyflow vault, use the `uploadFile` method. The `FileUpload ```typescript // Please use Node version 20 & above to run file upload -import { - FileUploadRequest, - FileUploadResponse, - FileUploadOptions, - SkyflowError -} from 'skyflow-node'; -import * as fs from 'fs'; +import { + FileUploadRequest, + FileUploadResponse, + FileUploadOptions, + SkyflowError, +} from "skyflow-node"; +import * as fs from "fs"; /* This example demonstrates how to upload file to Skyflow vault with FileUploadRequest and FileUploadOptions schema. @@ -1669,16 +1445,16 @@ This example demonstrates how to upload file to Skyflow vault with FileUploadReq try { // Initialize Skyflow client // Step 1: 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 + 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 2: Create File Upload Request const uploadReq: FileUploadRequest = new FileUploadRequest( - tableName, - skyflowId, - columnName, + tableName, + skyflowId, + columnName, ); // Step 3: Configure FileUpload Options @@ -1690,36 +1466,36 @@ try { // Step 4: Perform File Upload const response: FileUploadResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) - .uploadFile(uploadReq, uploadOptions); + .vault(primaryVaultConfig.vaultId) + .uploadFile(uploadReq, uploadOptions); // Handle Successful Response - console.log('File upload successful:', response); -} catch(error) { + console.log("File upload successful:", response); +} catch (error) { // Step 5: Handle any exceptions that occur during the query execution if (error instanceof SkyflowError) { - console.error('Skyflow Specific Error:', { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); + console.error("Skyflow Specific Error:", { + code: error.error?.http_code, + message: error.message, + details: error.error?.details, + }); } else { - console.error('Unexpected Error:', error); + console.error("Unexpected Error:", error); } } - ``` ### An [example](https://github.com/skyflowapi/skyflow-node/blob/main/samples/vault-api/file-upload.ts) of file upload call + ```typescript // Please use Node version 20 & above to run file upload -import { - FileUploadRequest, - FileUploadResponse, - FileUploadOptions, - SkyflowError -} from 'skyflow-node'; -import * as fs from 'fs'; +import { + FileUploadRequest, + FileUploadResponse, + FileUploadOptions, + SkyflowError, +} from "skyflow-node"; +import * as fs from "fs"; /* This example demonstrates how to upload file to Skyflow vault with FileUploadRequest and FileUploadOptions schema. @@ -1733,16 +1509,16 @@ This example demonstrates how to upload file to Skyflow vault with FileUploadReq try { // Initialize Skyflow client // Step 1: Prepare File Upload Data - const tableName: string = 'cards'; - const skyflowId: string = 'c9312531-2087-439a-bd26-74c41f24db83'; // Skyflow ID of the record - const columnName: string = 'license'; // Column name to store file - const filePath: string = '/images/license.png'; // Path to the file for upload + const tableName: string = "cards"; + const skyflowId: string = "c9312531-2087-439a-bd26-74c41f24db83"; // Skyflow ID of the record + const columnName: string = "license"; // Column name to store file + const filePath: string = "/images/license.png"; // Path to the file for upload // Step 2: Create File Upload Request const uploadReq: FileUploadRequest = new FileUploadRequest( - tableName, - skyflowId, - columnName, + tableName, + skyflowId, + columnName, ); // Step 3: Configure FileUpload Options @@ -1754,21 +1530,21 @@ try { // Step 4: Perform File Upload const response: FileUploadResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) - .uploadFile(uploadReq, uploadOptions); + .vault(primaryVaultConfig.vaultId) + .uploadFile(uploadReq, uploadOptions); // Handle Successful Response - console.log('File upload successful:', response); -} catch(error) { + console.log("File upload successful:", response); +} catch (error) { // Step 5: Handle any exceptions that occur during the query execution if (error instanceof SkyflowError) { - console.error('Skyflow Specific Error:', { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); + console.error("Skyflow Specific Error:", { + code: error.error?.http_code, + message: error.message, + details: error.error?.details, + }); } else { - console.error('Unexpected Error:', error); + console.error("Unexpected Error:", error); } } ``` @@ -1783,9 +1559,11 @@ FileUploadResponse { ``` ## Detect -Skyflow Detect enables you to deidentify and reidentify sensitive data in text and files, supporting advanced privacy-preserving workflows. The Detect API supports the following operations: -### Deidentify Text +Skyflow Detect enables you to deidentify and reidentify sensitive data in text and files, supporting advanced privacy-preserving workflows. + +### Deidentify Text `deidentifyText()` + To deidentify text, use the `deidentifyText` method. The `DeidentifyTextRequest` class creates a deidentify text request, which includes the text to be deidentified. Additionally, you can provide optional parameters using the `DeidentifyTextOptions` class. ```typescript @@ -1796,30 +1574,30 @@ import { TokenFormat, TokenType, Transformations, - DetectEntities -} from 'skyflow-node'; + DetectEntities, +} from "skyflow-node"; try { // Step 1: Prepare the text to be deidentified const deidentifyTextRequest = new DeidentifyTextRequest( - '' + "", ); // Step 2: Configure DeidentifyTextOptions const options = new DeidentifyTextOptions(); options.setEntities([DetectEntities.ACCOUNT_NUMBER, DetectEntities.SSN]); // Entities to deidentify - options.setAllowRegexList(['']); // Allowlist regex patterns - options.setRestrictRegexList(['']); // Restrict regex patterns + options.setAllowRegexList([""]); // Allowlist regex patterns + options.setRestrictRegexList([""]); // Restrict regex patterns - const tokenFormat = new TokenFormat(); // Specify the token format for deidentified entities + const tokenFormat = new TokenFormat(); // Specify the token format for deidentified entities tokenFormat.setDefault(TokenType.VAULT_TOKEN); optionsText.setTokenFormat(tokenFormat); const transformations = new Transformations(); // Specify custom transformations for entities 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 shift days + min: 30, // Minimum shift days + entities: [DetectEntities.ACCOUNT_NUMBER, DetectEntities.SSN], // Entities to apply the shift }); optionsText.setTransformations(transformations); @@ -1828,13 +1606,12 @@ try { .detect(primaryVaultConfig.vaultId) .deidentifyText(deidentifyTextRequest, options); - console.log('Deidentify Text Response:', response); - + console.log("Deidentify Text Response:", response); } catch (error) { if (error instanceof SkyflowError) { - console.error('Skyflow Error:', error.message); + console.error("Skyflow Error:", error.message); } else { - console.error('Unexpected Error:', JSON.stringify(error)); + console.error("Unexpected Error:", JSON.stringify(error)); } } ``` @@ -1843,19 +1620,19 @@ try { ```typescript import { - SkyflowError, - DeidentifyTextRequest, - DeidentifyTextOptions, - TokenFormat, - TokenType, - Transformations, - DetectEntities, - DeidentifyTextResponse -} from 'skyflow-node'; + SkyflowError, + DeidentifyTextRequest, + DeidentifyTextOptions, + TokenFormat, + TokenType, + Transformations, + DetectEntities, + DeidentifyTextResponse, +} from "skyflow-node"; /** * Skyflow Deidentify Text Example - * + * * This example demonstrates how to: * 1. Configure credentials * 2. Set up vault configuration @@ -1865,59 +1642,60 @@ import { */ async function performDeidentifyText() { - try { - - // Step 1: Prepare Deidentify Text Request - const textReq = new DeidentifyTextRequest( - 'My SSN is 123-45-6789 and my card is 4111 1111 1111 1111.', // Text to be deidentified - ); - - // Step 2: Configure DeidentifyTextOptions - const optionsText = new DeidentifyTextOptions(); - - // setEntities: Specify which entities to deidentify - optionsText.setEntities([DetectEntities.SSN, DetectEntities.CREDIT_CARD_NUMBER]); - - // setTokenFormat: Specify the token format for deidentified entities - const tokenFormat = new TokenFormat(); - tokenFormat.setDefault(TokenType.VAULT_TOKEN); - optionsText.setTokenFormat(tokenFormat); - - // setTransformations: Specify custom transformations for entities - const transformations = new Transformations(); - transformations.setShiftDays({ - max: 30, // Maximum shift days - min: 30, // Minimum shift days - entities: [DetectEntities.DOB], // Entities to apply the shift - }); - optionsText.setTransformations(transformations); - - // Step 3: Call deidentifyText API - const response: DeidentifyTextResponse = await skyflowClient - .detect(primaryVaultConfig.vaultId) - .deidentifyText(textReq, optionsText); - - // Handle Successful Response - console.log('Deidentify Text Response:', response); - - } catch (error) { - // Comprehensive Error Handling - if (error instanceof SkyflowError) { - console.error('Skyflow Specific Error:', { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); - } else { - console.error('Unexpected Error:', JSON.stringify(error)); - } + try { + // Step 1: Prepare Deidentify Text Request + const textReq = new DeidentifyTextRequest( + "My SSN is 123-45-6789 and my card is 4111 1111 1111 1111.", // Text to be deidentified + ); + + // Step 2: Configure DeidentifyTextOptions + const optionsText = new DeidentifyTextOptions(); + + // setEntities: Specify which entities to deidentify + optionsText.setEntities([ + DetectEntities.SSN, + DetectEntities.CREDIT_CARD_NUMBER, + ]); + + // setTokenFormat: Specify the token format for deidentified entities + const tokenFormat = new TokenFormat(); + tokenFormat.setDefault(TokenType.VAULT_TOKEN); + optionsText.setTokenFormat(tokenFormat); + + // setTransformations: Specify custom transformations for entities + const transformations = new Transformations(); + transformations.setShiftDays({ + max: 30, // Maximum shift days + min: 30, // Minimum shift days + entities: [DetectEntities.DOB], // Entities to apply the shift + }); + optionsText.setTransformations(transformations); + + // Step 3: Call deidentifyText API + const response: DeidentifyTextResponse = await skyflowClient + .detect(primaryVaultConfig.vaultId) + .deidentifyText(textReq, optionsText); + + // Handle Successful Response + console.log("Deidentify Text Response:", response); + } catch (error) { + // Comprehensive Error Handling + if (error instanceof SkyflowError) { + console.error("Skyflow Specific Error:", { + code: error.error?.http_code, + message: error.message, + details: error.error?.details, + }); + } else { + console.error("Unexpected Error:", JSON.stringify(error)); } + } } // Invoke the deidentify text function performDeidentifyText(); - ``` + Sample Response: ```typescript @@ -1966,21 +1744,18 @@ Sample Response: To reidentify text, use the `reidentifyText` method. The `ReidentifyTextRequest` class creates a reidentify text request, which includes the redacted or de-identified text to be re-identified. Additionally, you can provide optional parameters using the `ReidentifyTextOptions` class to control how specific entities are returned (as redacted, masked, or plain text). - ```typescript import { ReidentifyTextRequest, ReidentifyTextOptions, SkyflowError, DetectEntities, - ReidentifyTextResponse -} from 'skyflow-node'; + ReidentifyTextResponse, +} from "skyflow-node"; try { // Step 1: Prepare the redacted text to be re-identified - const textReq = new ReidentifyTextRequest( - '' - ); + const textReq = new ReidentifyTextRequest(""); // Step 2: Configure ReidentifyTextOptions const options = new ReidentifyTextOptions(); @@ -1993,19 +1768,18 @@ try { .detect(primaryVaultConfig.vaultId) .reidentifyText(textReq, options); - console.log('Reidentify Text Response:', response); - + console.log("Reidentify Text Response:", response); } catch (error) { - // Comprehensive Error Handling - if (error instanceof SkyflowError) { - console.error('Skyflow Specific Error:', { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); - } else { - console.error('Unexpected Error:', JSON.stringify(error)); - } + // Comprehensive Error Handling + if (error instanceof SkyflowError) { + console.error("Skyflow Specific Error:", { + code: error.error?.http_code, + message: error.message, + details: error.error?.details, + }); + } else { + console.error("Unexpected Error:", JSON.stringify(error)); + } } ``` @@ -2016,12 +1790,12 @@ import { ReidentifyTextRequest, ReidentifyTextOptions, DetectEntities, - ReidentifyTextResponse -} from 'skyflow-node'; + ReidentifyTextResponse, +} from "skyflow-node"; /** * Skyflow Reidentify Text Example - * + * * This example demonstrates how to: * 1. Configure credentials * 2. Set up vault configuration @@ -2034,34 +1808,36 @@ async function performReidentifyText() { try { // Step 1: Prepare Reidentify Text Request const reidentifyTextRequest = new ReidentifyTextRequest( - 'My SSN is [SSN_0ykQWPA] and my card is [CREDIT_CARD_N92QAVa].' // The redacted text to reidentify + "My SSN is [SSN_0ykQWPA] and my card is [CREDIT_CARD_N92QAVa].", // The redacted text to reidentify ); // Step 2: Configure ReidentifyTextOptions const options = new ReidentifyTextOptions(); // Specify which entities to reidentify as redacted, masked, or plain text - options.setPlainTextEntities([DetectEntities.CREDIT_CARD, DetectEntities.SSN]); + options.setPlainTextEntities([ + DetectEntities.CREDIT_CARD, + DetectEntities.SSN, + ]); // Step 4: Call reidentifyText const response: ReidentifyTextResponse = await skyflowClient - .detect(primaryVaultConfig.vaultId) - .reidentifyText(reidentifyTextRequest, options); + .detect(primaryVaultConfig.vaultId) + .reidentifyText(reidentifyTextRequest, options); // Step 5: Handle response - console.log('Re-identified Text Response:', response); - + console.log("Re-identified Text Response:", response); } catch (error) { - // Comprehensive Error Handling - if (error instanceof SkyflowError) { - console.error('Skyflow Specific Error:', { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); - } else { - console.error('Unexpected Error:', JSON.stringify(error)); - } + // Comprehensive Error Handling + if (error instanceof SkyflowError) { + console.error("Skyflow Specific Error:", { + code: error.error?.http_code, + message: error.message, + details: error.error?.details, + }); + } else { + console.error("Unexpected Error:", JSON.stringify(error)); + } } } @@ -2073,7 +1849,7 @@ Sample Response: ```typescript { - processedText: 'My SSN is 123-45-6789 and my card is 4111 1111 1111 1111.' + processedText: "My SSN is 123-45-6789 and my card is 4111 1111 1111 1111."; } ``` @@ -2143,7 +1919,7 @@ try { // options.setMaxResolution(2000); // Max resolution for PDF // ===== Audio Options (apply when file is audio) ===== - + // options.setOutputProcessedAudio(true); // Include processed audio in output // options.setOutputTranscription(DetectOutputTranscription.PLAINTEXT_TRANSCRIPTION); // Type of transcription @@ -2187,9 +1963,9 @@ import { TokenFormat, TokenType, Transformations, - DeidentifyFileResponse -} from 'skyflow-node'; -import fs from 'fs'; + DeidentifyFileResponse, +} from "skyflow-node"; +import fs from "fs"; /** * Skyflow Deidentify File Example @@ -2202,13 +1978,12 @@ async function performDeidentifyFile() { try { // Step 1: Prepare Deidentify File Request // Replace with your file object (e.g., from fs.readFileSync or browser File API) - const filePath: string = '/detect/sample.txt'; + const filePath: string = "/detect/sample.txt"; const buffer = fs.readFileSync(filePath); const file = new File([buffer], filePath); - //Step 2: Construct the file input by providing either file or filePath but not both - const fileInput: FileInput = { file: file } + const fileInput: FileInput = { file: file }; // const fileInput: FileInput = { filePath: filePath } const fileReq = new DeidentifyFileRequest(fileInput); @@ -2234,37 +2009,34 @@ async function performDeidentifyFile() { options.setTransformations(transformations); // Output directory for saving the deidentified file - options.setOutputDirectory('/home/user/output'); // Replace with your desired output directory. This is not supported in Cloudflare workers + options.setOutputDirectory("/home/user/output"); // Replace with your desired output directory. This is not supported in Cloudflare workers // Wait time for response (max 64 seconds) options.setWaitTime(15); - // Step 4: Call deidentifyFile API const response: DeidentifyFileResponse = await skyflowClient .detect(primaryVaultConfig.vaultId) .deidentifyFile(fileReq, options); // Handle Successful Response - console.log('Deidentify File Response:', response); - + console.log("Deidentify File Response:", response); } catch (error) { // Comprehensive Error Handling if (error instanceof SkyflowError) { - console.error('Skyflow Specific Error:', { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); + console.error("Skyflow Specific Error:", { + code: error.error?.http_code, + message: error.message, + details: error.error?.details, + }); } else { - console.error('Unexpected Error:', JSON.stringify(error)); + console.error("Unexpected Error:", JSON.stringify(error)); } } } // Invoke the deidentify file function performDeidentifyFile(); - ``` Sample Response: @@ -2297,7 +2069,8 @@ Sample Response: } ``` -**Supported file types:** +**Supported file types:** + - Documents: `doc`, `docx`, `pdf` - PDFs: `pdf` - Images: `bmp`, `jpeg`, `jpg`, `png`, `tif`, `tiff` @@ -2306,7 +2079,8 @@ Sample Response: - Presentations: `ppt`, `pptx` - Audio: `mp3`, `wav` -**Note:** +**Note:** + - Transformations cannot be applied to Documents, Images, or PDFs file formats. - The `waitTime` option must be ≤ 64 seconds; otherwise, an error is thrown. @@ -2314,6 +2088,7 @@ Sample Response: - If the API takes more than 64 seconds to process the file, it will return only the run ID in the response. Sample response (when the API takes more than 64 seconds): + ```typescript { @@ -2338,7 +2113,6 @@ To retrieve the results of a previously started file de-identification operation The `GetDetectRunRequest` class is initialized with the `runId` returned from a prior `deidentifyFile` call. This method allows you to fetch the final results of the file processing operation once they are available. - ```typescript import { GetDetectRunRequest, @@ -2373,21 +2147,21 @@ try { #### An example of a get run function ```typescript -import { - Credentials, - Env, - LogLevel, - Skyflow, - SkyflowConfig, - VaultConfig, - SkyflowError, - GetDetectRunRequest, - DeidentifyFileResponse -} from 'skyflow-node'; +import { + Credentials, + Env, + LogLevel, + Skyflow, + SkyflowConfig, + VaultConfig, + SkyflowError, + GetDetectRunRequest, + DeidentifyFileResponse, +} from "skyflow-node"; /** * Skyflow Get Detect Run Example - * + * * This example demonstrates how to: * 1. Configure credentials * 2. Set up vault configuration @@ -2397,54 +2171,53 @@ import { */ async function performGetDetectRun() { - try { - // Step 1: Configure Credentials - const credentials: Credentials = { - token: '', // Replace with your BEARER token - }; - - // Step 2: Configure Vault - const primaryVaultConfig: VaultConfig = { - vaultId: '', // Unique vault identifier - clusterId: '', // From vault URL - env: Env.PROD, // Deployment environment - credentials: credentials // Authentication method - }; - - // Step 3: Configure Skyflow Client - const skyflowConfig: SkyflowConfig = { - vaultConfigs: [primaryVaultConfig], - logLevel: LogLevel.INFO, // Recommended to use LogLevel.ERROR in production environment. - }; - - // Initialize Skyflow Client - const skyflowClient: Skyflow = new Skyflow(skyflowConfig); - - // Step 4: Prepare GetDetectRunRequest - const getDetectRunRequest = new GetDetectRunRequest({ - runId: '', // Replace with the runId from a previous deidentifyFile call - }); - - // Step 5: Call getDetectRun API - const response: DeidentifyFileResponse = await skyflowClient - .detect(primaryVaultConfig.vaultId) - .getDetectRun(getDetectRunRequest); - - // Handle Successful Response - console.log('Get Detect Run Response:', response); - - } catch (error) { - // Comprehensive Error Handling - if (error instanceof SkyflowError) { - console.error('Skyflow Specific Error:', { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); - } else { - console.error('Unexpected Error:', error); - } + try { + // Step 1: Configure Credentials + const credentials: Credentials = { + token: "", // Replace with your BEARER token + }; + + // Step 2: Configure Vault + const primaryVaultConfig: VaultConfig = { + vaultId: "", // Unique vault identifier + clusterId: "", // From vault URL + env: Env.PROD, // Deployment environment + credentials: credentials, // Authentication method + }; + + // Step 3: Configure Skyflow Client + const skyflowConfig: SkyflowConfig = { + vaultConfigs: [primaryVaultConfig], + logLevel: LogLevel.INFO, // Recommended to use LogLevel.ERROR in production environment. + }; + + // Initialize Skyflow Client + const skyflowClient: Skyflow = new Skyflow(skyflowConfig); + + // Step 4: Prepare GetDetectRunRequest + const getDetectRunRequest = new GetDetectRunRequest({ + runId: "", // Replace with the runId from a previous deidentifyFile call + }); + + // Step 5: Call getDetectRun API + const response: DeidentifyFileResponse = await skyflowClient + .detect(primaryVaultConfig.vaultId) + .getDetectRun(getDetectRunRequest); + + // Handle Successful Response + console.log("Get Detect Run Response:", response); + } catch (error) { + // Comprehensive Error Handling + if (error instanceof SkyflowError) { + console.error("Skyflow Specific Error:", { + code: error.error?.http_code, + message: error.message, + details: error.error?.details, + }); + } else { + console.error("Unexpected Error:", error); } + } } // Invoke the get detect run function @@ -2477,21 +2250,24 @@ Sample Response ## Connections Skyflow Connections is a gateway service that uses tokenization to securely send and receive data between your systems and first- or third-party services. The [connections](https://github.com/skyflowapi/skyflow-node/tree/v2/src/vault/controller/connections) module invokes both inbound and/or outbound connections. + - **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. -#### Invoke a connection +### Invoke a connection + To invoke a connection, use the `invoke` method of the Skyflow client. + #### Construct an invoke connection request ```typescript import { - InvokeConnectionRequest, - RequestMethod, - ConnectionConfig, - SkyflowError, - InvokeConnectionResponse -} from 'skyflow-node'; + InvokeConnectionRequest, + RequestMethod, + ConnectionConfig, + SkyflowError, + InvokeConnectionResponse, +} from "skyflow-node"; /* This example demonstrates how to invoke an external connection using the Skyflow SDK, along with corresponding InvokeConnectionRequest schema. @@ -2502,60 +2278,60 @@ try { // Step 1: Define the request body parameters // These are the values you want to send in the request body const requestBody = { - COLUMN_NAME_1: '', // Replace with actual key-value pairs - COLUMN_NAME_2: '', + COLUMN_NAME_1: "", // Replace with actual key-value pairs + COLUMN_NAME_2: "", }; // Step 2: Define the request headers // Add any required headers that need to be sent with the request const requestHeaders = { - HEADER_NAME_1: '', - HEADER_NAME_2: '', + HEADER_NAME_1: "", + HEADER_NAME_2: "", }; // Step 3: Define the path parameters // Path parameters are part of the URL and typically used in RESTful APIs const pathParams = { - YOUR_PATH_PARAM_KEY_1: '', - YOUR_PATH_PARAM_KEY_2: '' - } + YOUR_PATH_PARAM_KEY_1: "", + YOUR_PATH_PARAM_KEY_2: "", + }; // Step 4: Define the query parameters // Query parameters are included in the URL after a '?' and are used to filter or modify the response const queryParams = { - YOUR_QUERY_PARAM_KEY_1: '', - YOUR_QUERY_PARAM_KEY_2: '', - } + YOUR_QUERY_PARAM_KEY_1: "", + YOUR_QUERY_PARAM_KEY_2: "", + }; // Step 5: Define the request method const requestMethod: RequestMethod = RequestMethod.POST; // Step 6: Build the InvokeConnectionRequest using the provided parameters const invokeReq: InvokeConnectionRequest = new InvokeConnectionRequest( - requestMethod, - requestBody, - requestHeaders, - pathParams, - queryParams + requestMethod, + requestBody, + requestHeaders, + pathParams, + queryParams, ); // Step 7: Invoke the connection using the request const response: InvokeConnectionResponse = await skyflowClient - .connection() - .invoke(invokeReq); + .connection() + .invoke(invokeReq); // Step 8: Print the response from the invoked connection - console.log('Connection invocation successful:', response); -} catch(error) { + console.log("Connection invocation successful:", response); +} catch (error) { // Step 9: Handle any exceptions that occur during the connection invocation if (error instanceof SkyflowError) { - console.error('Skyflow Specific Error:', { - code: error.error?.http_code, - message: error.message, - details: error.error?.details - }); + console.error("Skyflow Specific Error:", { + code: error.error?.http_code, + message: error.message, + details: error.error?.details, + }); } else { - console.error('Unexpected Error:', error); + console.error("Unexpected Error:", error); } } ``` @@ -2570,704 +2346,156 @@ try { **pathParams, queryParams, header, body** are the JSON objects represented as dictionaries that will be sent through the connection integration url. -#### An [example](https://github.com/skyflowapi/skyflow-node/blob/v2/samples/vault-api/invoke-connection.ts) of Invoke Connection - -```typescript -import { - InvokeConnectionRequest, - RequestMethod, - ConnectionConfig, - SkyflowError, - InvokeConnectionResponse -} from 'skyflow-node'; - -/* -This example demonstrates how to invoke an external connection using the Skyflow SDK. -It configures a connection, sets up the request, and sends a POST request to the external service. - -1. Initialize Skyflow client with connection details. -2. Define the request body, headers, and method. -3. Execute the connection request. -4. Print the response from the invoked connection. -*/ - -try { - // Initialize Skyflow client - // Step 1: Set up credentials and connection configuration - // Load credentials from a JSON file (you need to provide the correct path) - const credentials: Credentials = { - path: '', - }; - - // Define the connection configuration (URL and credentials) - const connectionConfig: ConnectionConfig = { - connectionId: '', // Replace with actual connection ID - connectionUrl: 'https://connection.url.com', // Replace with actual connection URL - credentials: credentials // Set credentials for the connection - }; - - // Step 2: Configure Skyflow Client - const skyflowConfig: SkyflowConfig = { - connectionConfigs: [connectionConfig], // Add connection configuration to client - logLevel: LogLevel.INFO // Recommended to use LogLevel.ERROR in production environment. - }; - - // Step 3: Initialize Skyflow Client - const skyflowClient: Skyflow = new Skyflow(skyflowConfig); - - // Step 4: Define the request body parameters - const requestBody = { - card_number: '4337-1696-5866-0865', // Example card number - ssn: '524-41-4248', // Example SSN - }; - - // Step 5: Define the request headers - // Add any required headers that need to be sent with the request - const requestHeaders = { - 'content-type': 'application/json', // Set content type for the request - }; - - // Step 6: Define the request method - const requestMethod: RequestMethod = RequestMethod.POST; +> [!TIP] +> See the full example in the samples directory: [scoped-token-generation-example.ts](samples/vault-api/invoke-connection.ts) +> See [docs.skyflow.com](https://docs.skyflow.com) for more details on integrations with Connections, Functions, and Pipelines. - // Step 7: Build the InvokeConnectionRequest with required parameters - const invokeReq: InvokeConnectionRequest = new InvokeConnectionRequest( - requestMethod, - requestBody, - requestHeaders - ); +## Governance, identity, and access control - // Step 8: Invoke the connection using the request - const response: InvokeConnectionResponse = await skyflowClient - .connection() - .invoke(invokeReq); +### Generate bearer tokens for authentication & authorization - // Step 9: Print the response from the invoked connection - console.log('Connection invocation successful:', response); -} catch(error) { - // Step 9: Handle any exceptions that occur during the connection invocation - if (error instanceof SkyflowError) { - console.error('Skyflow Specific Error:', { - code: error.error?.http_code, - message: error.message, - details: error.error?.details - }); - } else { - console.error('Unexpected Error:', error); - } -} -``` - -Sample response: - -```typescript -InvokeConnectionResponse { - data: { - card_number: '4337-1696-5866-0865', - ssn: '524-41-4248', - }, - metadata: { - requestId: '801279ety19289899' - }, - errors: null -} -``` - -## Authenticate with bearer tokens -This section covers methods for generating and managing tokens to authenticate API calls: +This section covers methods for generating and managing bearer tokens to authenticate API calls: - **Generate a bearer token:** -Enable the creation of bearer tokens using service account credentials. These tokens, valid for 60 minutes, provide secure access to Vault services and management APIs based on the service account's permissions. Use this for general API calls when you only need basic authentication without additional context or role-based restrictions. + Enable the creation of bearer tokens using service account credentials. These tokens, valid for 60 minutes, provide secure access to Vault services and management APIs based on the service account's permissions. Use this for general API calls when you only need basic authentication without additional context or role-based restrictions. See: [token-generation-example.ts](http://github.com/skyflowapi/skyflow-node/blob/v2/samples/service-account/token-generation-example.ts) - **Generate a bearer token with context:** -Support embedding context values into bearer tokens, enabling dynamic access control and the ability to track end-user identity. These tokens include context claims and allow flexible authorization for Vault services. Use this when policies depend on specific contextual attributes or when tracking end-user identity is required. + Support embedding context values into bearer tokens, enabling dynamic access control and the ability to track end-user identity. These tokens include context claims and allow flexible authorization for Vault services. Use this when policies depend on specific contextual attributes or when tracking end-user identity is required. - **Generate a scoped bearer token:** -Facilitate the creation of bearer tokens with role-specific access, ensuring permissions are limited to the operations allowed by the designated role. This is particularly useful for service accounts with multiple roles. Use this to enforce fine-grained role-based access control, ensuring tokens only grant permissions for a specific role. + Facilitate the creation of bearer tokens with role-specific access, ensuring permissions are limited to the operations allowed by the designated role. This is particularly useful for service accounts with multiple roles. Use this to enforce fine-grained role-based access control, ensuring tokens only grant permissions for a specific role. - **Generate signed data tokens:** -Add an extra layer of security by digitally signing data tokens with the service account's private key. These signed tokens can be securely detokenized, provided the necessary bearer token and permissions are available. Use this to add cryptographic protection to sensitive data, enabling secure detokenization with verified integrity and authenticity. + Add an extra layer of security by digitally signing data tokens with the service account's private key. These signed tokens can be securely detokenized, provided the necessary bearer token and permissions are available. Use this to add cryptographic protection to sensitive data, enabling secure detokenization with verified integrity and authenticity. #### Generate a bearer token -The [Service Account](https://github.com/skyflowapi/skyflow-node/tree/v2/src/service-account) Node package generates service account tokens using a service account credentials file, which is provided when a service account is created. The tokens generated by this module are valid for 60 minutes and can be used to make API calls to the [Data](https://docs.skyflow.com/record/) and [Management](https://docs.skyflow.com/management/) APIs, depending on the permissions assigned to the service account. - -The `generateBearerToken(filepath)` function takes the credentials file path for token generation, alternatively, you can also send the entire credentials as string, by using `generateBearerTokenFromCreds(credentials)` -#### [Example](http://github.com/skyflowapi/skyflow-node/blob/v2/samples/service-account/token-generation-example.ts): +The [Service Account](https://github.com/skyflowapi/skyflow-node/tree/v2/src/service-account) Node package generates service account tokens using a service account credentials file, which is provided when a service account is created. The tokens generated by this module are valid for 60 minutes and can be used to make API calls to the [Data](https://docs.skyflow.com/record/) and [Management](https://docs.skyflow.com/management/) APIs, depending on the permissions assigned to the service account. -```javascript -import { - generateBearerToken, - generateBearerTokenFromCreds, - isExpired, - SkyflowError -} from 'skyflow-node'; +##### `generateBearerToken(filepath)` -/* -Example program to generate a Bearer Token using Skyflow's service account utilities. -The token can be generated in two ways: -1. Using the file path to a credentials.json file. -2. Using the JSON content of the credentials file as a string. -*/ +The `generateBearerToken(filepath)` function takes the `credentials.json` file path for token generation. -// Variable to store the generated token +```js let bearerToken: string = ''; - -// Specify the full file path to the credentials.json file -const filepath = 'CREDENTIALS_FILE_PATH'; - - -// Example 1: Generate Bearer Token using a credentials.json file -function getSkyflowBearerTokenFromFilePath() { - return new Promise((resolve, reject) => { - try { - // Check if the token is already generated and still valid - if (!isExpired(bearerToken)) resolve(bearerToken); - else { - // Generate a new Bearer Token from the credentials file - generateBearerToken(filepath) - .then(response => { - bearerToken = response.accessToken; - // Resolve the generated Bearer Token - resolve(bearerToken); - }) - .catch(error => { - // Handle any errors that occur during the generation process - reject(error); - }); - } - } catch (e) { - // Handle any other unexpected exceptions - reject(e); - } +generateBearerToken('path/to/credentials.json') + .then(response => { + bearerToken = response.accessToken; + // Resolve the generated Bearer Token + resolve(bearerToken); + }) + .catch(error => { + // Handle any errors that occur during the generation process + reject(error); }); -} +``` -// Example 2: Generate Bearer Token using the credentials JSON string -function getSkyflowBearerTokenFromCreds() { +##### `generateBearerTokenFromCreds(credentials)` - // To generate Bearer Token from credentials string. - const skyflowCredentials = { - clientID: '', - clientName: '', - keyID: '', - tokenURI: '', - privateKey: '', - }; +Alternatively, you can also send the entire credentials as string by using `generateBearerTokenFromCreds(credentials)`. - // Convert credentials dictionary to JSON string - const credentialsString = JSON.stringify(skyflowCredentials); - - return new Promise((resolve, reject) => { - try { - // Check if the token is already generated and still valid - if (!isExpired(bearerToken)) resolve(bearerToken); - else { - // Generate a new Bearer Token from the credentials string - generateBearerTokenFromCreds(credentialsString) - .then(response => { - bearerToken = response.accessToken; - // Resolve the generated Bearer Token - resolve(bearerToken); - }) - .catch(error => { - // Handle any errors that occur during the generation process - reject(error); - }); - } - } catch (e) { - // Handle any other unexpected exceptions - reject(e); - } +```js +let bearerToken: string = ''; +generateBearerTokenFromCreds(credentialsString) + .then(response => { + bearerToken = response.accessToken; + // Resolve the generated Bearer Token + resolve(bearerToken); + }) + .catch(error => { + // Handle any errors that occur during the generation process + reject(error); }); -} - -const tokens = async () => { - console.log(await getSkyflowBearerTokenFromFilePath()); - console.log(await getSkyflowBearerTokenFromCreds()); -}; - -tokens(); ``` +> [!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 with context + **Context-aware authorization** embeds context values into a bearer token during its generation and so you can reference those values in your policies. This enables more flexible access controls, such as helping you track end-user identity when making API calls using service accounts, and facilitates using signed data tokens during detokenization. A service account with the context_id identifier generates bearer tokens containing context information, represented as a JWT claim in a Skyflow-generated bearer token. Tokens generated from such service accounts include a context_identifier claim, are valid for 60 minutes, and can be used to make API calls to the Data and Management APIs, depending on the service account's permissions. -#### [Example](https://github.com/skyflowapi/skyflow-node/blob/v2/samples/service-account/token-generation-with-context-example.ts): - -```javascript -import { - generateBearerToken, - generateBearerTokenFromCreds, - isExpired, - SkyflowError -} from 'skyflow-node'; - -/* -Example program to generate a Bearer Token using Skyflow's BearerToken utility. -The token is generated using two approaches: -1. By providing the credentials.json file path. -2. By providing the contents of credentials.json as a string. -*/ - -// Variable to store the generated token -let bearerToken = ''; - -// Specify the full file path to the credentials.json file -const filepath = 'CREDENTIALS_FILE_PATH'; - -// Approach 1: Generate Bearer Token by specifying the path to the credentials.json file -function getSkyflowBearerTokenWithContextFromFilePath() { - return new Promise((resolve, reject) => { - try { - // Set context string (example: "context_id") - const options = { - ctx: 'context_id', - }; - // Check if the token is already generated and still valid - if (!isExpired(bearerToken)) resolve(bearerToken); - else { - // Generate a new Bearer Token from the credentials file - generateBearerToken(filepath, options) - .then(response => { - bearerToken = response.accessToken; - // Resolve the generated Bearer Token - resolve(bearerToken); - }) - .catch(error => { - // Handle any errors that occur during the generation process - reject(error); - }); - } - } catch (e) { - // Handle any other unexpected exceptions - reject(e); - } - }); -} - -// Approach 2: Generate Bearer Token by specifying the contents of credentials.json as a string -function getSkyflowBearerTokenWithContextFromCreds() { - - // To generate Bearer Token from credentials string. - const skyflowCredentials = { - clientID: '', - clientName: '', - keyID: '', - tokenURI: '', - privateKey: '', - }; - - // Convert credentials dictionary to JSON string - const credentialsString = JSON.stringify(skyflowCredentials); - - return new Promise((resolve, reject) => { - try { - // Set context string (example: "context_id") - const options = { - ctx: 'context_id', - }; - // Check if the token is already generated and still valid - if (!isExpired(bearerToken)) resolve(bearerToken); - else { - // Generate a new Bearer Token from the credentials string and options - generateBearerTokenFromCreds(credentialsString, options) - .then(response => { - bearerToken = response.accessToken; - // Resolve the generated Bearer Token - resolve(bearerToken); - }) - .catch(error => { - // Handle any errors that occur during the generation process - reject(error); - }); - } - } catch (e) { - // Handle any other unexpected exceptions - reject(e); - } - }); -} - -const tokens = async () => { - console.log(await getSkyflowBearerTokenWithContextFromFilePath()); - console.log(await getSkyflowBearerTokenWithContextFromCreds()); -}; - -tokens(); +```ts +generateBearerTokenFromCreds(JSON.stringify({ + clientID: '', + clientName: '', + keyID: '', + tokenURI: '', + privateKey: '', +}), { + ctx: 'context_id', // the user's context identifier +}) ``` -#### Generate scoped bearer tokens -A service account with multiple roles can generate bearer tokens with access limited to a specific role by specifying the appropriate roleID. This can be used to limit access to specific roles for services with multiple responsibilities, such as segregating access for billing and analytics. The generated bearer tokens are valid for 60 minutes and can only execute operations permitted by the permissions associated with the designated role. - -#### [Example](https://github.com/skyflowapi/skyflow-node/blob/v2/samples/service-account/scoped-token-generation-example.ts): +> [!TIP] +> See the full example in the samples directory: [token-generation-with-context-example.ts](samples/service-account/token-generation-with-context-example.ts) +> See [docs.skyflow.com](https://docs.skyflow.com) for more details on authentication, access control, and governance for Skyflow. -```javascript -import { - generateBearerToken, - generateBearerTokenFromCreds, - isExpired, - SkyflowError -} from 'skyflow-node'; - -/* -Example program to generate a Scoped Token using Skyflow's BearerToken utility. -The token is generated by providing the file path to the credentials.json file -and specifying roles associated with the token. -*/ - -// Variable to store the generated token -let bearerToken = ''; - -// Specify the full file path to the credentials.json file -const filepath = 'CREDENTIALS_FILE_PATH'; - -// Example: Generate Scoped Token by specifying the credentials.json file path -function getScopedBearerTokenFromFilePath() { - return new Promise((resolve, reject) => { - try { - // Set the role ids - const options = { - roleIDs: ['roleID1', 'roleID2'], - }; - // Check if the token is already generated and still valid - if (!isExpired(bearerToken)) resolve(bearerToken); - else { - // Generate a new Bearer Token from the credentials file and associated roles - generateBearerToken(filepath, options) - .then(response => { - bearerToken = response.accessToken; - // Resolve the generated Bearer Token - resolve(bearerToken); - }) - .catch(error => { - // Handle any errors that occur during the generation process - reject(error); - }); - } - } catch (e) { - // Handle any other unexpected exceptions - reject(e); - } - }); -} - -const tokens = async () => { - console.log(await getScopedBearerTokenFromFilePath()); -}; +#### Generate scoped bearer tokens -tokens(); +A service account with multiple roles can generate bearer tokens with access limited to a specific role by specifying the appropriate roleID. This can be used to limit access to specific roles for services with multiple responsibilities, such as segregating access for billing and analytics. The generated bearer tokens are valid for 60 minutes and can only execute operations permitted by the permissions associated with the designated role. -``` +> [!TIP] +> See the full example in the samples directory: [scoped-token-generation-example.ts](samples/service-account/scoped-token-generation-example.ts) +> See [docs.skyflow.com](https://docs.skyflow.com) for more details on authentication, access control, and governance for Skyflow. #### Generate signed data tokens + Skyflow generates data tokens when sensitive data is inserted into the vault. These data tokens can be digitally signed with a service account's private key, adding an extra layer of protection. Signed tokens can only be detokenized 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. -#### [Example](https://github.com/skyflowapi/skyflow-node/blob/v2/samples/service-account/signed-token-generation-example.ts): +- `generateSignedDataTokens(filepath, options);` +- `generateSignedDataTokensFromCreds(credentialsString, options)` -```javascript -import { - generateSignedDataTokens, - generateSignedDataTokensFromCreds - isExpired, - SkyflowError -} from 'skyflow-node'; +> [!TIP] +> 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. -/* -Example program to generate Signed Data Tokens using Skyflow's utilities. -Signed Data Tokens can be generated in two ways: -1. By specifying the file path to the credentials.json file. -2. By providing the credentials as a JSON string. -*/ +## Logging & error handling -// Specify the full file path to the credentials.json file -const filepath = 'CREDENTIALS_FILE_PATH'; - -// Example 1: Generate Signed Data Tokens using a credentials file -function getSignedTokenFromFilePath() { - return new Promise(async (resolve, reject) => { - try { - // Options for generating signed data tokens - const options = { - ctx: 'ctx', // Set the context value - dataTokens: ['dataToken1', 'dataToken2'], // Set the data tokens to be signed - timeToLive: 90 // Set the token's time-to-live (TTL) in seconds - }; - // Generate and retrieve the signed data tokens - let response = await generateSignedDataTokens(filepath, options); - resolve(response); - } catch (e) { - // Handle any errors that occur during the generation process - reject(e); - } - }); -} +The SDK provides useful logging. By default the logging level of the SDK is set to `LogLevel.ERROR`. This can be changed by setting the `logLevel` in Skyflow Config while creating the Skyflow Client as shown below: -// Example 2: Generate Signed Data Tokens using credentials as a JSON string -function getSignedTokenFromCreds() { +Currently, the following five log levels are supported: - // To generate Bearer Token from credentials string. - const skyflowCredentials = { - clientID: '', - clientName: '', - keyID: '', - tokenURI: '', - privateKey: '', - }; +- `DEBUG`: + When `LogLevel.DEBUG` is passed, logs at all levels will be printed (DEBUG, INFO, WARN, ERROR). +- `INFO`: + When `LogLevel.INFO` is passed, INFO logs for every event that occurs during SDK flow execution will be printed, along with WARN and ERROR logs. +- `WARN`: + When `LogLevel.WARN` is passed, only WARN and ERROR logs will be printed. +- `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. - // Convert credentials dictionary to JSON string - const credentialsString = JSON.stringify(skyflowCredentials); - - return new Promise(async (resolve, reject) => { - try { - // Options for generating signed data tokens - const options = { - ctx: 'ctx', // Set the context value - dataTokens: ['dataToken1', 'dataToken2'], // Set the data tokens to be signed - timeToLive: 90, // Set the token's time-to-live (TTL) in seconds - }; - // Generate and retrieve the signed data tokens - let response = await generateSignedDataTokensFromCreds( - credentialsString, - options - ); - resolve(response); - } catch (e) { - // Handle any errors that occur during the generation process - reject(e); - } - }); -} +**Note:** The ranking of logging levels is as follows: `DEBUG` < `INFO` < `WARN` < `ERROR` < `OFF`. -const tokens = async () => { - try { - const tokenResponseFromFilePath = await getSignedTokenFromFilePath(); - tokenResponseFromFilePath.forEach((response) => { - console.log(`Data Token: ${response.token}`); - console.log(`Signed Data Token: ${response.signedToken}`); - }); +### Example `skyflowConfig.logLevel: LogLevel.INFO` - const tokenResponseFromCreds = await getSignedTokenFromCreds(); - tokenResponseFromCreds.forEach((response) => { - console.log(`Data Token: ${response.token}`); - console.log(`Signed Data Token: ${response.signedToken}`); - }); - } catch (error) { - console.log(error); - } -}; +```ts + const skyflowConfig: SkyflowConfig = { + vaultConfigs: [vaultConfig], // Add the Vault configuration + skyflowCredentials: skyflowCredentials, // Use Skyflow credentials if no token is passed + logLevel: LogLevel.INFO, // Recommended to use LogLevel.ERROR in production environment. + }; -tokens(); + const skyflowClient: Skyflow = new Skyflow(skyflowConfig); ``` -Notes: -- The `timeToLive` (TTL) value should be specified in seconds. -- By default, the TTL value is set to 60 seconds. +#### Bearer token expiration edge cases -#### Bearer token expiry edge case When you use bearer tokens for authentication and API requests in SDKs, there's the potential for a token to expire after the token is verified as valid but before the actual API call is made, causing the request to fail unexpectedly due to the token's expiration. An error from this edge case would look something like this: ```txt message: Authentication failed. Bearer token is expired. Use a valid bearer token. See https://docs.skyflow.com/api-authentication/ ``` -If you encounter this kind of error, retry the request. During the retry, the SDK detects that the previous bearer token has expired and generates a new one for the current and subsequent requests. +If you encounter this kind of error, retry the request. During the retry the SDK detects that the previous bearer token has expired and generates a new one for the current and subsequent requests. -#### [Example](https://github.com/skyflowapi/skyflow-node/blob/v2/samples/service-account/bearer-token-expiry-example.ts.ts): +> [!TIP] +> 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. -```javascript -import { - Credentials, - DetokenizeOptions, - DetokenizeRequest, - DetokenizeResponse, - DetokenizeData, - Env, - LogLevel, - RedactionType, - Skyflow, - SkyflowError, - VaultConfig, - SkyflowConfig -} from 'skyflow-node'; - -/** -* This example demonstrates how to configure and use the Skyflow SDK -* to detokenize sensitive data stored in a Skyflow vault. -* It includes setting up credentials, configuring the vault, and -* making a detokenization request. The code also implements a retry -* mechanism to handle unauthorized access errors (HTTP 401). -*/ -async function detokenizeData(skyflowClient: Skyflow, vaultId: string) { - try { - // Creating a list of tokens to be detokenized - const detokenizeData: DetokenizeData[] = [ - { - token: "", // Replace with your actual token value - redactionType: RedactionType.MASKED, // Redaction type - }, - { - token: "", // Replace with your actual token value - redactionType: RedactionType.PLAIN_TEXT, // Redaction type - }, - ]; - - // Building a detokenization request - const detokenizeRequest: DetokenizeRequest = new DetokenizeRequest( - detokenizeData - ); - - // Configuring detokenization options - const detokenizeOptions: DetokenizeOptions = new DetokenizeOptions(); - detokenizeOptions.setContinueOnError(false); // Stop on error - detokenizeOptions.setDownloadURL(false); // Disable download URL generation - - // Sending the detokenization request and receiving the response - const response: DetokenizeResponse = await skyflowClient - .vault(vaultId) - .detokenize(detokenizeRequest, detokenizeOptions); - - // Printing the detokenized response - console.log('Detokenization successful:', response); - } catch (err) { - throw err; - } -} - -async function main() { - try { - // Setting up credentials for accessing the Skyflow vault - const credentials: Credentials = { - credentialsString: '', // Credentials string for authentication - }; - - // Configuring the Skyflow vault with necessary details - const primaryVaultConfig: VaultConfig = { - vaultId: '', // Vault ID - clusterId: '', // Cluster ID - env: Env.PROD, // Environment set to PROD - credentials: credentials // Setting credentials - }; - - // Creating a Skyflow client instance with the configured vault - const skyflowConfig: SkyflowConfig = { - vaultConfigs: [primaryVaultConfig], - logLevel: LogLevel.INFO, // Recommended to use LogLevel.ERROR in production environment. - }; - - const skyflowClient: Skyflow = new Skyflow(skyflowConfig); - - // Attempting to detokenize data using the Skyflow client - try { - await detokenizeData(skyflowClient, primaryVaultConfig.vaultId); - } catch (err) { - // Retry detokenization if the error is due to unauthorized access (HTTP 401) - if (err instanceof SkyflowError && err.error?.http_code === 401) { - console.warn('Unauthorized access detected. Retrying...'); - await detokenizeData(skyflowClient, primaryVaultConfig.vaultId); - } else { - // Rethrow the exception for other error codes - throw err; - } - } - } catch (err) { - // Handling any exceptions that occur during the process - console.error('An error occurred:', err); - } -} - -// Invoke the main function -main(); - -``` - -## Logging - -The SDK provides useful logging. By default the logging level of the SDK is set to `LogLevel.ERROR`. This can be changed by setting the `logLevel` in Skyflow Config while creating the Skyflow Client as shown below: - -Currently, the following five log levels are supported: -- `DEBUG`: -When `LogLevel.DEBUG` is passed, logs at all levels will be printed (DEBUG, INFO, WARN, ERROR). -- `INFO`: -When `LogLevel.INFO` is passed, INFO logs for every event that occurs during SDK flow execution will be printed, along with WARN and ERROR logs. -- `WARN`: -When `LogLevel.WARN` is passed, only WARN and ERROR logs will be printed. -- `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. - -**Note:** The ranking of logging levels is as follows: `DEBUG` < `INFO` < `WARN` < `ERROR` < `OFF`. - -```typescript -import { - Skyflow, - LogLevel, - SkyflowError -} from 'skyflow-node'; - -/* -This example demonstrates how to configure the Skyflow client with custom log levels and authentication credentials (either token, credentials string, or other methods). It also shows how to configure a vault connection using specific parameters. -1. Set up credentials with a Bearer token or credentials string. -2. Define the Vault configuration. -3. Build the Skyflow client with the chosen configuration and set log level. -4. Example of changing the log level from ERROR (default) to INFO. -*/ - -try { - // Step 1: Set up credentials - either pass token or use credentials string - // In this case, we are using a Bearer token for authentication - const credentials: Credentials = { - token: '', // Replace with actual Bearer token - }; - - // Step 2: Define the Vault configuration - // Configure the vault with necessary details like vault ID, cluster ID, and environment - const vaultConfig: VaultConfig = { - vaultId: '', // Replace with actual Vault ID (primary vault) - clusterId: '', // Replace with actual Cluster ID (from vault URL) - env: Env.PROD, // Set the environment (default is PROD) - credentials: credentials // Set credentials for the vault (either token or credentials) - }; - - // Step 3: Define additional Skyflow credentials (optional, if needed for credentials string) - const skyflowCredentials = { - clientID: '', - clientName: '', - keyID: '', - tokenURI: '', - privateKey: '', - }; - - // Convert the credentials object to a json string format to be used for generating a Bearer Token - const credentialsString = JSON.stringify(skyflowCredentials); - - // Step 9: Build and initialize the Skyflow client after creating Skyflow Config - // Skyflow client is configured with multiple vaults and credentials. - const skyflowConfig: SkyflowConfig = { - vaultConfigs: [vaultConfig], // Add the Vault configuration - skyflowCredentials: skyflowCredentials, // Use Skyflow credentials if no token is passed - logLevel: LogLevel.INFO // Recommended to use LogLevel.ERROR in production environment. - }; - - // Step 10: Initialize Skyflow Client - const skyflowClient: Skyflow = new Skyflow(skyflowConfig); - - // Now, the Skyflow client is ready to use with the specified log level and credentials - console.log('Skyflow client has been successfully configured with log level: INFO.') -} catch(error) { - // Step 11: Handle any exceptions that occur - if (error instanceof SkyflowError) { - console.error('Skyflow Specific Error:', { - code: error.error?.http_code, - message: error.message, - details: error.error?.details - }); - } else { - console.error('Unexpected Error:', error); - } -} -``` +## Security -## Reporting a Vulnerability +### Reporting a Vulnerability -If you discover a potential security issue in this project, please reach out to us at **security@skyflow.com**. Please do not create public GitHub issues or Pull Requests, as malicious actors could potentially view them. \ No newline at end of file +If you discover a potential security issue in this project, please reach out to us at **security@skyflow.com**. Please do not create public GitHub issues or Pull Requests, as malicious actors could potentially view them. diff --git a/SECURITY.md b/SECURITY.md index 3ce45cce..676e66b0 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,4 +2,6 @@ ## Reporting a Vulnerability -If you discover a potential security issue in this project, please reach out to us at security@skyflow.com. Please do not create public GitHub issues or Pull Requests, as malicious actors could potentially view them. \ No newline at end of file +If you discover a potential security issue in this project, please reach out to us at [mailto:security@skyflow.com](security@skyflow.com). + +Please do not create public GitHub issues or Pull Requests, as malicious actors could potentially view them. diff --git a/docs/advanced_initialization.md b/docs/advanced_initialization.md new file mode 100644 index 00000000..390cf0b4 --- /dev/null +++ b/docs/advanced_initialization.md @@ -0,0 +1,146 @@ +# Advanced Skyflow Client Initialization + +This guide demonstrates advanced initialization patterns for the Skyflow Node SDK, including multiple vault configurations and different credential types. + +## Multiple Vault Configuration Example + +```typescript +import { + Credentials, + Env, + LogLevel, + Skyflow, + VaultConfig, + SkyflowConfig, +} from 'skyflow-node'; + +/* +Example program to initialize the Skyflow client with various configurations. +The Skyflow client facilitates secure interactions with the Skyflow vault, +such as securely managing sensitive data. +*/ + +// Step 1: Define the primary credentials for authentication. +// Note: Only one type of credential can be used at a time. You can choose between: +// - API key +// - Bearer token +// - A credentials string (JSON-formatted) +// - A file path to a credentials file. + +// Initialize primary credentials using a Bearer token for authentication. +const primaryCredentials: Credentials = { + token: '', // Replace with your actual authentication token. +}; + +// Step 2: Configure the primary vault details. +// VaultConfig stores all necessary details to connect to a specific Skyflow vault. + +const primaryVaultConfig: VaultConfig = { + vaultId: '', // Replace with your primary vault ID + clusterId: '', // Replace with the cluster ID (part of the vault URL, e.g., https://{clusterId}.vault.skyflowapis.com). + env: Env.PROD, // Set the environment (PROD, SANDBOX, STAGE, DEV). + credentials: primaryCredentials // Attach the primary credentials to this vault configuration. +}; + +// Step 3: Create credentials as a JSON object (if a Bearer Token is not provided). +// Demonstrates an alternate approach to authenticate with Skyflow using a credentials object. +const skyflowCredentials: object = { + clientID: '', // Replace with your Client ID. + clientName: '', // Replace with your Client Name. + tokenURI: '', // Replace with the Token URI. + keyID: '', // Replace with your Key ID. + privateKey: '' // Replace with your Private Key. +} + +// Step 4: Convert the JSON object to a string and use it as credentials. +// This approach allows the use of dynamically generated or pre-configured credentials. +const credentialsString: string = JSON.stringify(skyflowCredentials); // Converts JSON object to string for use as credentials. + +// Step 5: Define secondary credentials (API key-based authentication as an example). +// Demonstrates a different type of authentication mechanism for Skyflow vaults. +const secondaryCredentials: Credentials = { + apiKey: '', // Replace with your API Key for authentication. +} + +// Step 6: Configure the secondary vault details. +// A secondary vault configuration can be used for operations involving multiple vaults. +const secondaryVaultConfig: VaultConfig = { + vaultId: '', // Replace with your secondary vault's ID. + clusterId: '', // Replace with the corresponding cluster ID. + env: Env.PROD, // Set the environment for this vault. + credentials: secondaryCredentials // Attach the secondary credentials to this configuration. +} + +// Step 7: Define tertiary credentials using a path to a credentials JSON file. +// This method demonstrates an alternative authentication method. +const tertiaryCredentials: Credentials = { + path: '' // Replace with the path to your credentials file. +} + +// Step 8: Configure the tertiary vault details. +const tertiaryVaultConfig: VaultConfig = { + vaultId: '', // Replace with the tertiary vault ID. + clusterId: '', // Replace with the corresponding cluster ID. + env: Env.PROD, // Set the environment for this vault. + credentials: tertiaryCredentials // Attach the tertiary credentials. +} + +// Step 9: Build and initialize the Skyflow client after creating Skyflow Config +// Skyflow client is configured with multiple vaults and credentials. + +const skyflowConfig: SkyflowConfig = { + vaultConfigs: [primaryVaultConfig, secondaryVaultConfig, tertiaryVaultConfig], // Add the primary, secondary and tertiary vault configurations. + skyflowCredentials: skyflowCredentials, // Add JSON-formatted credentials if applicable. + logLevel: LogLevel.INFO // Recommended to use LogLevel.ERROR in production environment. +}; + +// Step 10: Initialize Skyflow Client +const skyflowClient: Skyflow = new Skyflow(skyflowConfig); + +// The Skyflow client is now fully initialized. +// Use the `skyflowClient` object to perform secure operations such as: +// - Inserting data +// - Retrieving data +// - Deleting data +// within the configured Skyflow vaults. +``` + +## Credential Types + +The SDK supports multiple credential types: + +### Bearer Token +```typescript +const credentials: Credentials = { + token: '' +}; +``` + +### API Key +```typescript +const credentials: Credentials = { + apiKey: '' +}; +``` + +### Credentials Object +```typescript +const skyflowCredentials = { + clientID: '', + clientName: '', + tokenURI: '', + keyID: '', + privateKey: '' +}; +``` + +### Credentials File Path +```typescript +const credentials: Credentials = { + path: '' +}; +``` + +## Environment Variables + +If neither Skyflow common credentials nor individual configuration-level credentials are provided, the SDK attempts to retrieve credentials from the `SKYFLOW_CREDENTIALS` environment variable. diff --git a/docs/generate_bearer_tokens.md b/docs/generate_bearer_tokens.md new file mode 100644 index 00000000..e69de29b diff --git a/MIGRATE_TO_v2.md b/docs/migrate_to_v2.md similarity index 100% rename from MIGRATE_TO_v2.md rename to docs/migrate_to_v2.md From 6c490a043429cddeddd60469a6ddbb5a6037a41a Mon Sep 17 00:00:00 2001 From: Joseph McCarron Date: Fri, 14 Nov 2025 02:40:24 -0600 Subject: [PATCH 03/15] under 1000 lines ftw. slimmed down examples, removed duplicated code by factoring error handling into its own section and referencing rather than duplicating full examples. --- README.md | 2364 ++++++-------------------------- docs/generate_bearer_tokens.md | 20 + 2 files changed, 433 insertions(+), 1951 deletions(-) diff --git a/README.md b/README.md index 1fb4646d..729d36dd 100644 --- a/README.md +++ b/README.md @@ -18,60 +18,48 @@ The Skyflow SDK for Node.js, Deno, Bun, and Cloudflare Workers. - [Quickstart](#quickstart) - [Authenticate](#authenticate) - [Initialize the client](#initialize-the-client) - - [Insert data into the vault](#insert-data-into-the-vault) + - [Insert data into the vault, get tokens back](#insert-data-into-the-vault-get-tokens-back) - [Vault](#vault) - [Insert and tokenize data](#insert-and-tokenize-data) - [Construct an insert request](#construct-an-insert-request) - [Insert example with `continueOnError` option](#insert-example-with-continueonerror-option) - [Detokenize](#detokenize) - [Construct a detokenize request](#construct-a-detokenize-request) - - [An example of a detokenize call](#an-example-of-a-detokenize-call) - - [An example of a detokenize call with `continueOnError` option:](#an-example-of-a-detokenize-call-with-continueonerror-option) - - [Tokenize](#tokenize) - - [Construct a tokenize request](#construct-a-tokenize-request) - - [An example of Tokenize call](#an-example-of-tokenize-call) - - [Get](#get) + - [Get Record(s)](#get-records) - [Construct a get request](#construct-a-get-request) - - [Get by skyflow IDs](#get-by-skyflow-ids) + - [Get by Skyflow IDs](#get-by-skyflow-ids) - [Get tokens for records](#get-tokens-for-records) - - [An example of get call to retrieve tokens using Skyflow IDs:](#an-example-of-get-call-to-retrieve-tokens-using-skyflow-ids) - [Get by column name and column values](#get-by-column-name-and-column-values) - - [An example of get call to retrieve data using column name and column values:](#an-example-of-get-call-to-retrieve-data-using-column-name-and-column-values) - [Redaction Types](#redaction-types) - - [Update](#update) + - [Update Records](#update-records) - [Construct an update request](#construct-an-update-request) - - [An example of update call](#an-example-of-update-call) - - [Delete](#delete) - - [Construct a delete request](#construct-a-delete-request) - - [An example of delete call](#an-example-of-delete-call) + - [Delete Records](#delete-records) - [Query](#query) - - [Construct a query request](#construct-a-query-request) - - [An example of query call](#an-example-of-query-call) - [Upload File](#upload-file) - - [An example of file upload call](#an-example-of-file-upload-call) + - [Get Tokens by Values: `.tokenize(request)`](#get-tokens-by-values-tokenizerequest) + - [Construct a `.tokenize()` request](#construct-a-tokenize-request) - [Detect](#detect) - - [Deidentify Text `deidentifyText()`](#deidentify-text-deidentifytext) - - [An example of a deidentify text call](#an-example-of-a-deidentify-text-call) - - [Reidentify Text](#reidentify-text) - - [An example of a reidentify text call](#an-example-of-a-reidentify-text-call) - - [Deidentify File](#deidentify-file) - - [An example of a deidentify file](#an-example-of-a-deidentify-file) - - [Get run](#get-run) - - [An example of a get run function](#an-example-of-a-get-run-function) + - [De-identify Text: `.deidentifyText(request, options)`](#de-identify-text-deidentifytextrequest-options) + - [Re-identify Text: `.reidentifyText(request, options)`](#re-identify-text-reidentifytextrequest-options) + - [Deidentify File: `.deidentifyFile(fileReq, options)`](#deidentify-file-deidentifyfilefilereq-options) + - [Get Run: `.getDetectRun(request)`](#get-run-getdetectrunrequest) - [Connections](#connections) - [Invoke a connection](#invoke-a-connection) - [Construct an invoke connection request](#construct-an-invoke-connection-request) - - [Governance, identity, and access control](#governance-identity-and-access-control) + - [Authentication \& authorization](#authentication--authorization) + - [Types of `credentials`](#types-of-credentials) - [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) - - [Generate bearer tokens with context](#generate-bearer-tokens-with-context) - - [Generate scoped bearer tokens](#generate-scoped-bearer-tokens) - - [Generate signed data tokens](#generate-signed-data-tokens) - - [Logging \& error handling](#logging--error-handling) + - [Generate bearer tokens scoped to certain roles](#generate-bearer-tokens-scoped-to-certain-roles) + - [Generate a bearer tokens with `ctx`](#generate-a-bearer-tokens-with-ctx) + - [Generate signed data tokens: `generateSignedDataTokens(filepath, options)`](#generate-signed-data-tokens-generatesigneddatatokensfilepath-options) + - [Logging](#logging) - [Example `skyflowConfig.logLevel: LogLevel.INFO`](#example-skyflowconfigloglevel-loglevelinfo) - - [Bearer token expiration edge cases](#bearer-token-expiration-edge-cases) + - [Error handling](#error-handling) + - [Catching `SkyflowError` instances](#catching-skyflowerror-instances) + - [Bearer token expiration edge cases](#bearer-token-expiration-edge-cases) - [Security](#security) - [Reporting a Vulnerability](#reporting-a-vulnerability) @@ -133,32 +121,12 @@ const credentials = { apiKey: "" }; //add your API key in credenti To get started, you must first initialize the skyflow client. While initializing the skyflow client, you can specify different types of credentials. -1. **API keys** - A unique identifier used to authenticate and authorize requests to an API. - -2. **Bearer tokens** - A temporary access token used to authenticate API requests, typically included in the - Authorization header. - -3. **Service account credentials file path** - The file path pointing to a JSON file containing credentials for a service account, used - for secure API access. - -4. **Service account credentials string** - JSON-formatted string containing service account credentials, often used as an alternative to a file for programmatic authentication. - -Note: Only one type of credential can be used at a time. If multiple credentials are provided, the last one added will take precedence. - ```javascript import { Skyflow, SkyflowConfig, VaultConfig, Env, LogLevel } from 'skyflow-node'; -// Configure credentials +// Create a credentials object. We'll use an API key. const skyflowCredentials = { - clientID: '', - clientName: '', - tokenURI: '', - keyID: '', - privateKey: '' + apiKey: "" }; // Configure vault @@ -186,16 +154,22 @@ Notes - If neither Skyflow common credentials nor individual configuration-level credentials are provided, the SDK attempts to retrieve credentials from the `SKYFLOW_CREDENTIALS` environment variable. - All Vault operations require a client instance. -### Insert data into the vault +### Insert data into the vault, get tokens back -To insert data into your vault, use the `insert` method. The `InsertRequest` class creates an insert request, which includes the values to be inserted as a list of records. Below is a simple example to get started. For advanced options, check out [Insert data into the vault](#insert-data-into-the-vault-1) section. +To insert data into your vault use the `insert` method. Make sure to set `insertOptions.setReturnTokens(true)` to ensure values are tokenized in the response. + +The `InsertRequest` class creates an insert request, which includes the values to be inserted as a list of records. + +Below is a simple example to get started. For advanced options, check out [Insert data into the vault](#insert-data-into-the-vault-1) section. ```javascript -import { InsertRequest, InsertOptions } from 'skyflow-node'; +import { InsertRequest, InsertOptions } from "skyflow-node"; // Insert sensitive data into the vault -const insertData = [{ card_number: '4111111111111112', cardholder_name: 'John Doe' }]; -const insertReq = new InsertRequest('table1', insertData); +const insertData = [ + { card_number: "4111111111111112", cardholder_name: "John Doe" }, +]; +const insertReq = new InsertRequest("table1", insertData); const insertOptions = new InsertOptions(); insertOptions.setReturnTokens(true); @@ -204,7 +178,7 @@ const insertResponse = await skyflowClient .vault(vaultId) .insert(insertReq, insertOptions); -console.log('Insert response:', insertResponse); +console.log("Insert response:", insertResponse); ``` ## Vault @@ -218,56 +192,24 @@ Apart from using the `insert` method to insert data into your vault covered in [ #### Construct an insert request ```typescript -import { - InsertOptions, - InsertRequest, - SkyflowError, - InsertResponse -} from 'skyflow-node'; +import { InsertRequest, InsertResponse } from 'skyflow-node'; + +const insertRequest = new InsertRequest('table1', [ + { + : '', + : '', + }, + { + : '', + : '', + }, +]); -// Example program to demonstrate inserting data into a Skyflow vault, -// along with corresponding InsertRequest schema. +const response: InsertResponse = await skyflowClient + .vault('') + .insert(insertRequest); -try { - // Initialize Skyflow client - // Step 1: Prepare the data to be inserted into the Skyflow vault - const insertData: Record[] = [ - { - : '', // Replace with actual field name and value - : '', // Replace with actual field name and value - }, - { - : '', // Replace with actual field name and value - : '', // Replace with actual field name and value - }, - ] - - // Step 2: Build an InsertRequest object with the table name and the data to insert - const insertReq: InsertRequest = new InsertRequest( - 'table1', // Specify the table in the vault where the data will be inserted - insertData, // Attach the data (records) to be inserted - ); - - // Step 3: Perform the insert operation using the Skyflow client - const insertResponse: InsertResponse = await skyflowClient - .vault('') - .insert(insertReq, insertOptions); - // Replace with your actual vault ID - - // Step 4: Print the response from the insert operation - console.log('Insert response: ', insertResponse); -} catch(error) { - // Step 5: Comprehensive Error Handling - if (error instanceof SkyflowError) { - console.error('Skyflow Specific Error:', { - code: error.error?.http_code, - message: error.message, - details: error.error?.details - }); - } else { - console.error('Unexpected Error:', error); - } -} +console.log('Insert response:', response); ``` #### Insert example with `continueOnError` option @@ -288,506 +230,86 @@ import { InsertResponse, } from "skyflow-node"; -/* -This example demonstrates how to insert sensitive data (e.g., card information) into a Skyflow vault using the Skyflow client. +const insertData: Record[] = [ + { + cardholder_name: "John Doe", + }, +]; -1. Initializes the Skyflow client. -2. Prepares a record with sensitive data (e.g., card number and cardholder name). -3. Creates an insert request for inserting the data into the Skyflow vault. -4. Specifies the field (cardholder_name) for upsert operations. -5. Prints the response of the insert operation. -*/ +const insertReq: InsertRequest = new InsertRequest( + "table1", // Specify the table in the vault where the data will be inserted + insertData, // Attach the data (records) to be inserted +); -try { - // Initialize Skyflow client - // Step 1: Initialize a list to hold the data records for the insert/upsert operation - const insertData: Record[] = [ - // Step 2: Create a record with the field 'cardholder_name' to insert or upsert - { - cardholder_name: "John Doe", // Replace with actual cardholder name - }, - ]; - - // Step 3: Create Insert Request - const insertReq: InsertRequest = new InsertRequest( - "table1", // Specify the table in the vault where the data will be inserted - insertData, // Attach the data (records) to be inserted - ); - - // Step 4: Set upsert column by configuring the insertion options - const insertOptions: InsertOptions = new InsertOptions(); - insertOptions.setReturnTokens(true); // Optional: Specify if tokens should be returned upon successful insertion - insertOptions.setUpsertColumn("cardholder_name"); - - // Step 5: Perform the insert/upsert operation using the Skyflow client - const insertResponse: InsertResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) - .insert(insertReq, insertOptions); - - // Step 6: Print the response from the insert operation - console.log("Insert response: ", insertResponse); -} catch (error) { - // Step 7: Comprehensive Error Handling - if (error instanceof SkyflowError) { - console.error("Skyflow Specific Error:", { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); - } else { - console.error("Unexpected Error:", error); - } -} -``` +const insertOptions: InsertOptions = new InsertOptions(); +insertOptions.setReturnTokens(true); // Optional: Specify if tokens should be returned upon successful insertion +insertOptions.setUpsertColumn("cardholder_name"); -Skyflow returns tokens, with `upsert` support, for the record you just inserted. +const insertResponse: InsertResponse = await skyflowClient + .vault(primaryVaultConfig.vaultId) + .insert(insertReq, insertOptions); -```typescript -InsertResponse { - insertedFields: [ - { - skyflowId: "9fac9201-7b8a-4446-93f8-5244e1213bd1", - cardholder_name: "73ce45ce-20fd-490e-9310-c1d4f603ee83" - } - ], - errors: null -} +console.log("Insert response: ", insertResponse); ``` ### Detokenize -To retrieve tokens from your vault, use the `detokenize` method. The `DetokenizeRequest` class requires a list of detokenization data as input. Additionally, you can provide optional parameters, such as the redaction type and the option to continue on error. +To convert tokens back into the plaintext values (or masked values), use the `.detokenize()` method. Detokenization accepts tokens and returns values. -#### Construct a detokenize request +The `DetokenizeRequest` class requires a list of tokens and column groups as input. -```typescript -import { - DetokenizeOptions, - DetokenizeRequest, - DetokenizeResponse, - DetokenizeData, - SkyflowError, -} from "skyflow-node"; - -/* -This example demonstrates how to detokenize sensitive data from tokens stored in a Skyflow vault, along with corresponding DetokenizeRequest schema. -*/ - -try { - // Step 1: Prepare Detokenization Data - const detokenizeData: DetokenizeData[] = [ - { - token: "token1", // Token to be detokenized - redactionType: RedactionType.PLAIN_TEXT, // Redaction type - }, - { - token: "token2", // Token to be detokenized - redactionType: RedactionType.PLAIN_TEXT, // Redaction type - }, - ]; - - // Step 2: Create the DetokenizeRequest object with the tokens data - const detokenizeRequest: DetokenizeRequest = new DetokenizeRequest( - detokenizeData, - ); - - // Step 3: Configure Detokenize Options - const detokenizeOptions: DetokenizeOptions = new DetokenizeOptions(); - detokenizeOptions.setContinueOnError(true); // Continue processing on errors - detokenizeOptions.setDownloadURL(false); // Disable download URL generation - - // Step 4: Perform Detokenization - const response: DetokenizeResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) - .detokenize(detokenizeRequest, detokenizeOptions); - - // Handle Successful Response - console.log("Detokenization response:", response); -} catch (error) { - // Comprehensive Error Handling - if (error instanceof SkyflowError) { - console.error("Skyflow Specific Error:", { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); - } else { - console.error("Unexpected Error:", error); - } -} -``` - -Notes: - -- `redactionType` defaults to `RedactionType.PLAIN_TEXT`. -- `continueOnError` default value is `False`. - -#### An [example](https://github.com/skyflowapi/skyflow-node/blob/v2/samples/vault-api/detokenzie-records.ts) of a detokenize call - -```typescript -import { - DetokenizeOptions, - DetokenizeRequest, - DetokenizeResponse, - DetokenizeData, - SkyflowError, -} from "skyflow-node"; +Additionally, you can provide optional parameters, such as the redaction type and the option to continue on error. -/* -1. Initializes the Skyflow client. -2. Creates a list of tokens (e.g., credit card tokens) that represent the sensitive data. -3. Builds a detokenization request using the provided tokens and specifies how the redacted data should be returned. -4. Calls the Skyflow vault to detokenize the tokens and retrieves the detokenized data. -5. Prints the detokenization response, which contains the detokenized values or errors. -*/ - -try { - // Step 1: Prepare Detokenization Data - const detokenizeData: DetokenizeData[] = [ - { - token: "9738-1683-0486-1480", // Replace with your actual token value - redactionType: RedactionType.PLAIN_TEXT, // Redaction type - }, - { - token: "6184-6357-8409-6668", // Replace with your actual token value - redactionType: RedactionType.PLAIN_TEXT, // Redaction type - }, - ]; - - // Step 2: Create the DetokenizeRequest object with the tokens data - const detokenizeRequest: DetokenizeRequest = new DetokenizeRequest( - detokenizeData, - ); - - // Step 3: Configure Detokenize Options - const detokenizeOptions: DetokenizeOptions = new DetokenizeOptions(); - detokenizeOptions.setContinueOnError(false); // Stop the process if any token cannot be detokenized - - // Step 4: Perform Detokenization - const response: DetokenizeResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) - .detokenize(detokenizeRequest, detokenizeOptions); - - // Handle Successful Response - console.log("Detokenization response:", response); -} catch (error) { - // Comprehensive Error Handling - if (error instanceof SkyflowError) { - console.error("Skyflow Specific Error:", { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); - } else { - console.error("Unexpected Error:", error); - } -} -``` - -Sample response: - -```typescript -DetokenizeResponse { - detokenizedFields: [ - {token: '9738-1683-0486-1480', value: '4111111111111115', type: 'STRING'}, - {token: '6184-6357-8409-6668', value: '4111111111111119', type: 'STRING'}, - ], - errors: null -} -``` - -#### An example of a detokenize call with `continueOnError` option: +#### Construct a detokenize request ```typescript import { DetokenizeOptions, DetokenizeRequest, DetokenizeResponse, - DetokenizeData, - SkyflowError, } from "skyflow-node"; -/* -1. Initializes the Skyflow client. -2. Creates a list of tokens (e.g., credit card tokens) that represent the sensitive data. -3. Builds a detokenization request using the provided tokens and specifies how the redacted data should be returned. -4. Calls the Skyflow vault to detokenize the tokens and retrieves the detokenized data. -5. Prints the detokenization response, which contains the detokenized values or errors. -*/ +const detokenizeRequest = new DetokenizeRequest([ + { token: "token1", redactionType: RedactionType.PLAIN_TEXT }, + { token: "token2", redactionType: RedactionType.PLAIN_TEXT }, +]); -try { - // Step 1: Prepare Detokenization Data - const detokenizeData: DetokenizeData[] = [ - { - token: "9738-1683-0486-1480", // Replace with your actual token value - redactionType: RedactionType.PLAIN_TEXT, // Redaction type - }, - { - token: "6184-6357-8409-6668", // Replace with your actual token value - redactionType: RedactionType.PLAIN_TEXT, // Redaction type - }, - { - token: "4914-9088-2814-3840", // Replace with your actual token value - redactionType: RedactionType.PLAIN_TEXT, // Redaction type - }, - ]; - - // Step 2: Create the DetokenizeRequest object with the tokens and redaction type - const detokenizeRequest: DetokenizeRequest = new DetokenizeRequest( - detokenizeData, - redactionType, - ); - - // Step 3: Configure Detokenize Options - const detokenizeOptions: DetokenizeOptions = new DetokenizeOptions(); - detokenizeOptions.setContinueOnError(true); // Continue even if some tokens cannot be detokenized - - // Step 5: Perform Detokenization - const response: DetokenizeResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) - .detokenize(detokenizeRequest, detokenizeOptions); - - // Handle Successful Response - console.log("Detokenization response:", response); -} catch (error) { - // Comprehensive Error Handling - if (error instanceof SkyflowError) { - console.error("Skyflow Specific Error:", { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); - } else { - console.error("Unexpected Error:", error); - } -} -``` +const detokenizeOptions = new DetokenizeOptions(); +detokenizeOptions.setContinueOnError(true); +detokenizeOptions.setDownloadURL(false); -Sample response: +const response: DetokenizeResponse = await skyflowClient + .vault(primaryVaultConfig.vaultId) + .detokenize(detokenizeRequest, detokenizeOptions); -```typescript -DetokenizeResponse { - detokenizedFields: [ - {token: '9738-1683-0486-1480', value: '4111111111111115', type: 'STRING'}, - {token: '6184-6357-8409-6668', value: '4111111111111119', type: 'STRING'} - ], - errors: [ - { - token: '4914-9088-2814-3840', - error: 'Token Not Found' - } - ] -} +console.log("Detokenization response:", response); ``` -### Tokenize - -Tokenization replaces sensitive data with unique identifier tokens. This approach protects sensitive information by securely storing the original data while allowing the use of tokens within your application. - -To tokenize data, use the `tokenize` method. The `TokenizeRequest` class creates a tokenize request. In this request, you specify the values parameter, which is a list of column values objects. Each column value contains two properties: `value` and `columnGroup`. - -#### Construct a tokenize request - -```typescript -import { - TokenizeRequest, - TokenizeResponse, - SkyflowError, - TokenizeRequestType, -} from "skyflow-node"; - -try { - // Initialize Skyflow Client - // Step 1: Prepare Tokenization Data - const columnValues: Array = [ - { value: "", columnGroup: "" }, // Replace and with actual data - { value: "", columnGroup: "" }, // Replace and with actual data - ]; - - // Step 2: Build the TokenizeRequest with the column values - const tokenReq: TokenizeRequest = new TokenizeRequest(columnValues); - - // Step 3: Call the Skyflow vault to tokenize the sensitive data - const response: TokenizeResponse = await skyflowClient - .vault("") - .tokenize(tokenReq); - // Replace with your actual Skyflow vault ID - - // Step 4: Print the tokenization response, which contains the generated tokens or errors - console.log("Tokenization Result:", response); -} catch (error) { - // Step 5: Handle any errors that occur during the tokenization process - if (error instanceof SkyflowError) { - console.error("Skyflow Specific Error:", { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); - } else { - console.error("Unexpected Error:", error); - } -} -``` - -#### An [example](https://github.com/skyflowapi/skyflow-node/blob/v2/samples/vault-api/tokenize-records.ts) of Tokenize call - -```typescript -import { - TokenizeRequest, - TokenizeResponse, - SkyflowError, - TokenizeRequestType, -} from "skyflow-node"; - -/* -This example demonstrates how to tokenize sensitive data (e.g., credit card information) using the Skyflow client. +> [!TIP] +> See the full example in the samples directory: [detokenzie-records.ts](samples/vault-api/detokenzie-records.ts) -1. Initializes the Skyflow client. -2. Creates a column value for sensitive data (e.g., credit card number). -3. Builds a tokenize request with the column value to be tokenized. -4. Sends the request to the Skyflow vault for tokenization. -5. Prints the tokenization response, which includes the token or errors. -*/ +### Get Record(s) -try { - // Initialize Skyflow Client - // Step 1: Prepare Tokenization Data - const columnValues: Array = [ - { value: "4111111111111111", columnGroup: "card_number_cg" }, - ]; - - // Step 2: Build the TokenizeRequest with the column values - const tokenReq: TokenizeRequest = new TokenizeRequest(columnValues); - - // Step 3: Call the Skyflow vault to tokenize the sensitive data - const response: TokenizeResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) - .tokenize(tokenReq); - // Replace primaryVaultConfig.vaultId with your actual Skyflow vault ID - - // Step 4: Print the tokenization response, which contains the generated tokens or errors - console.log("Tokenization Result:", response); -} catch (error) { - if (error instanceof SkyflowError) { - console.error("Skyflow Specific Error:", { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); - } else { - console.error("Unexpected Error:", error); - } -} -``` +To retrieve data using Skyflow IDs or unique column values, use the get method. The `GetRequest` class creates a get request, where you specify parameters such as the table name, redaction type, Skyflow IDs, column names, column values. If you specify Skyflow IDs, you can't use column names and column values, and the inverse is true—if you specify column names and column values, you can't use Skyflow IDs. And `GetOptions` class creates a get options object through which you specify whether to return tokens or not. -Sample response: +#### Construct a get request ```typescript -TokenizeResponse { - tokens: [ - { - token: '5479-4229-4622-1393' - } - ], - errors: null -} -``` - -### Get +import { GetRequest, GetOptions, GetResponse } from "skyflow-node"; -To retrieve data using Skyflow IDs or unique column values, use the get method. The `GetRequest` class creates a get request, where you specify parameters such as the table name, redaction type, Skyflow IDs, column names, column values. If you specify Skyflow IDs, you can't use column names and column values, and the inverse is true—if you specify column names and column values, you can't use Skyflow IDs. And `GetOptions` class creates a get options object through which you specify whether to return tokens or not. +const getRequest = new GetRequest("table1", ["", ""]); -#### Construct a get request +const getOptions = new GetOptions(); +getOptions.setReturnTokens(false); -```typescript -import { - GetOptions, - GetRequest, - GetColumnRequest, - SkyflowError, - GetResponse, -} from "skyflow-node"; +const response: GetResponse = await skyflowClient + .vault("") + .get(getRequest, getOptions); -try { - // Initialize Skyflow client - // Step 1: Initialize a list of Skyflow IDs to retrieve records (replace with actual Skyflow IDs) - const getIds: Array = ["", ""]; - - // Step 2: Create a GetRequest to retrieve records by Skyflow ID - const getRequest: GetRequest = new GetRequest( - "table1", // Replace with your actual table name - getIds, - ); - - // Step 3: Configure Get Options and specify not to return tokens - const getOptions: GetOptions = new GetOptions(); - getOptions.setReturnTokens(false); // Optional: Set to false to avoid returning tokens - - // Step 4: Send the request to the Skyflow vault and retrieve the records - const getResponse: GetResponse = await skyflowClient - .vault("") - .get(getRequest, getOptions); - // Replace with your actual Skyflow vault ID - - console.log("Data retrieval successful:", getResponse); - - // Step 5: Create another GetRequest to retrieve records by Skyflow ID with tokenized values - const getTokensRequest: GetRequest = new GetRequest( - "table1", // Replace with your actual table name - getIds, - ); - - // Step 6: Configure Get Options and specify to return tokens - const getOptions: GetOptions = new GetOptions(); - getOptions.setReturnTokens(true); // Optional: Set to True to return tokenized values - - // Step 7: Send the request to the Skyflow vault and retrieve the tokenized records - const getTokensResponse: GetResponse = await skyflowClient - .vault("") - .get(getRequest, getOptions); - // Replace with your actual Skyflow vault ID - - console.log("Data retrieval successful:", getTokensResponse); - - // Prepare Column-Based Retrieval Data - const columnValues: Array = [ - "", // Example Unique Column value 1 - "", // Example Unique Column value 2 - ]; - const tableName: string = "table-name"; // Replace with your actual table name - const columnName: string = "column-name"; // Column name configured as unique in the schema - - const getRequest: GetColumnRequest = new GetColumnRequest( - tableName, - columnName, - columnValues, // Column values of the records to return - ); - - // Step 8: Configure Get Options and specify to return tokens - const getOptions: GetOptions = new GetOptions(); - getOptions.setReturnTokens(true); // Optional: Set to True to return tokenized values - - // Send the request to the Skyflow vault and retrieve the filtered records - const response: GetResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) - .get(getRequest, getOptions); - - console.log("Column-based retrieval successful:", response); -} catch (error) { - // Handle any errors that occur during the retrieval process - if (error instanceof SkyflowError) { - console.error("Skyflow Specific Error:", { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); - } else { - console.error("Unexpected Error:", error); - } -} +console.log("Get response:", response); ``` -#### Get by skyflow IDs +#### Get by Skyflow IDs Retrieve specific records using skyflow `ids`. Ideal for fetching exact records when IDs are known. @@ -800,238 +322,57 @@ import { RedactionType, } from "skyflow-node"; -/* -This example demonstrates how to retrieve data from the Skyflow vault using a list of Skyflow IDs. +// Initialize a list of Skyflow IDs to retrieve records (replace with actual Skyflow IDs) +const getIds: Array = [ + "a581d205-1969-4350-acbe-a2a13eb871a6", + "5ff887c3-b334-4294-9acc-70e78ae5164a", +]; -1. Initializes the Skyflow client with a given vault ID. -2. Creates a request to retrieve records based on Skyflow IDs. -3. Specifies that the response should not return tokens. -4. Uses plain text redaction type for the retrieved records. -5. Prints the response to display the retrieved records. -*/ +// Step 2: Create a GetRequest to retrieve records by Skyflow ID +const getRequest: GetRequest = new GetRequest( + "table1", // Replace with your actual table name + getIds, +); -try { - // Initialize Skyflow client - // Step 1: Initialize a list of Skyflow IDs to retrieve records (replace with actual Skyflow IDs) - const getIds: Array = [ - "a581d205-1969-4350-acbe-a2a13eb871a6", - "5ff887c3-b334-4294-9acc-70e78ae5164a", - ]; - - // Step 2: Create a GetRequest to retrieve records by Skyflow ID - const getRequest: GetRequest = new GetRequest( - "table1", // Replace with your actual table name - getIds, - ); - - // Step 3: Configure Get Options and specify not to return tokens and redaction type - const getOptions: GetOptions = new GetOptions(); - getOptions.setReturnTokens(false); // Optional: Set to false to avoid returning tokens - getOptions.setRedactionType(RedactionType.PLAIN_TEXT); - - // Step 4: Send the request to the Skyflow vault and retrieve the records - const getResponse: GetResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) - .get(getRequest, getOptions); - // Replace with your actual Skyflow vault ID - - console.log("Data retrieval successful:", getResponse); -} catch (error) { - // Step 5: Handle any errors that occur during the retrieval process - if (error instanceof SkyflowError) { - console.error("Skyflow Specific Error:", { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); - } else { - console.error("Unexpected Error:", error); - } -} -``` +// Step 3: Configure Get Options and specify not to return tokens and redaction type +const getOptions: GetOptions = new GetOptions(); +getOptions.setReturnTokens(false); // Optional: Set to false to avoid returning tokens +getOptions.setRedactionType(RedactionType.PLAIN_TEXT); -Sample response: +// Step 4: Send the request to the Skyflow vault and retrieve the records +const getResponse: GetResponse = await skyflowClient + .vault(primaryVaultConfig.vaultId) + .get(getRequest, getOptions); +// Replace with your actual Skyflow vault ID -```typescript -GetResponse { - data: [ - { - card_number: '4555555555555553', - email: 'john.doe@gmail.com', - name: 'john doe', - skyflow_id: 'a581d205-1969-4350-acbe-a2a13eb871a6' - }, - { - card_number: '4555555555555559', - email: 'jane.doe@gmail.com', - name: 'jane doe', - skyflow_id: '5ff887c3-b334-4294-9acc-70e78ae5164a' - } - ], - errors: null -} +console.log("Data retrieval successful:", getResponse); ``` #### Get tokens for records Return tokens for records. Ideal for securely processing sensitive data while maintaining data privacy. -#### An [example](https://github.com/skyflowapi/skyflow-node/blob/v2/samples/vault-api/get-records.ts) of get call to retrieve tokens using Skyflow IDs: - -```typescript -import { - GetOptions, - GetRequest, - SkyflowError, - GetResponse, - RedactionType, -} from "skyflow-node"; - -try { - // Assemble your IDs - const getIds: Array = [ - "a581d205-1969-4350-acbe-a2a13eb871a6", - "5ff887c3-b334-4294-9acc-70e78ae5164a", - ]; - - // Create a GetRequest to retrieve records by table name and Skyflow IDs - const getRequest: GetRequest = new GetRequest( - "table1", // Table name - getIds, // Array of ID strings - ); - - // Create a GetOptions and request tokens - const getOptions: GetOptions = new GetOptions(); - getOptions.setReturnTokens(true); // Optional: Set to true to get tokens - - // Send the request to the Skyflow vault and retrieve the records - const getResponse: GetResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) - .get(getRequest, getOptions); - - console.log("Data retrieval successful:", getResponse); -} catch (error) { - // Handle any errors that occur during the retrieval process - if (error instanceof SkyflowError) { - console.error("Skyflow Specific Error:", { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); - } else { - console.error("Unexpected Error:", error); - } -} +```ts +getOptions.setReturnTokens(true); // Optional: Set to true to get tokens ``` -Sample response: - -```typescript -GetResponse { - data: [ - { - card_number: '3998-2139-0328-0697', - email: 'c9a6c9555060@82c092e7.bd52', - name: '82c092e7-74c0-4e60-bd52-c9a6c9555060', - skyflow_id: 'a581d205-1969-4350-acbe-a2a13eb871a6' - }, - { - card_number: '3562-0140-8820-7499', - email: '6174366e2bc6@59f82e89.93fc', - name: '59f82e89-138e-4f9b-93fc-6174366e2bc6', - skyflow_id: '5ff887c3-b334-4294-9acc-70e78ae5164a' - } - ], - errors: null -} -``` +> [!TIP] +> See the full example in the samples directory: [get-records.ts](samples/vault-api/get-records.ts) #### Get by column name and column values Retrieve records by unique column values. Ideal for querying data without knowing Skyflow IDs, using alternate unique identifiers. -#### An [example](https://github.com/skyflowapi/skyflow-node/blob/v2/samples/vault-api/get-column-values.ts) of get call to retrieve data using column name and column values: - -```typescript -import { - GetOptions, - GetRequest, - SkyflowError, - GetResponse, - RedactionType, - GetColumnRequest, -} from "skyflow-node"; - -/* -This example demonstrates how to retrieve data from the Skyflow vault based on column values. - -1. Initializes the Skyflow client with a given vault ID. -2. Creates a request to retrieve records based on specific column values (e.g., email addresses). -3. Prints the response to display the retrieved records after redacting sensitive data based on the specified redaction type. -*/ - -try { - // Initialize Skyflow client - // Step 1: Initialize a list of column values (email addresses in this case) - const columnValues: Array = [ - "john.doe@gmail.com", // Example email address - "jane.doe@gmail.com", // Example email address - ]; - const tableName: string = "table1"; // Replace with your actual table name - const columnName: string = "email"; // Column name configured as unique in the schema - - // Step 2: Create a GetRequest to retrieve records based on column values - const getRequest: GetColumnRequest = new GetColumnRequest( - tableName, - columnName, - columnValues, // Column values of the records to return - ); - - // Step 3: Configure Get Options and specify redaction type - const getOptions: GetOptions = new GetOptions(); - getOptions.setRedactionType(RedactionType.PLAIN_TEXT); // Optional: Set the redaction type (e.g., PLAIN_TEXT) - - // Step 4: Send the request to the Skyflow vault and retrieve the filtered records - const response: GetResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) - .get(getRequest, getOptions); - - console.log("Column-based retrieval successful:", response); -} catch (error) { - // Step 5: Handle any errors that occur during the retrieval process - if (error instanceof SkyflowError) { - console.error("Skyflow Specific Error:", { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); - } else { - console.error("Unexpected Error:", error); - } -} +```ts +const getRequest: GetColumnRequest = new GetColumnRequest( + tableName, + columnName, + columnValues, // Column values of the records to return +); ``` -Sample response: - -```typescript -GetResponse { - data: [ - { - card_number: '4555555555555553', - email: 'john.doe@gmail.com', - name: 'john doe', - skyflow_id: 'a581d205-1969-4350-acbe-a2a13eb871a6' - }, - { - card_number: '4555555555555559', - email: 'jane.doe@gmail.com', - name: 'jane doe', - skyflow_id: '5ff887c3-b334-4294-9acc-70e78ae5164a' - } - ], - errors: null -} -``` +> [!TIP] +> See the full example in the samples directory: [get-column-values.ts](samples/vault-api/get-column-values.ts) #### Redaction Types @@ -1050,442 +391,80 @@ Redaction types determine how sensitive data is displayed when retrieved from th - 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. -### Update +### Update Records To update data in your vault, use the `update` method. The `UpdateRequest` class is used to create an update request, where you specify parameters such as the table name, data (as a dictionary). The `UpdateOptions` class is used to configure update options to returnTokens, tokens, and tokenMode. If `returnTokens` is set to True, Skyflow returns tokens for the updated records. If `returnTokens` is set to False, Skyflow returns IDs for the updated records. #### Construct an update request ```typescript -import { - UpdateRequest, - UpdateOptions, - UpdateResponse, - SkyflowError, - TokenMode -} from 'skyflow-node'; - -// This example demonstrates how to update records in the Skyflow vault by providing new data and/or tokenized values, along with the corresponding UpdateRequest schema. - -try { - // Initialize Skyflow client - // Step 1: Prepare the data to update in the vault - // Use a dictionary to store the data that will be updated in the specified table - const updateData: Record = { - skyflowId: 'your-skyflow-id', // Skyflow ID for identifying the record to update - COLUMN_NAME1: '' //Example of a column name and its value to update - COLUMN_NAME2: ''// Another example of a column name and its value to update - }; - - // Step 2: Prepare the tokens (if necessary) for certain columns that require tokenization - const tokens: Record = { - COLUMN_NAME_2: '' // Example of a column name that should be tokenized - } - - // Step 3: Create an UpdateRequest to specify the update operation - const updateReq: UpdateRequest = new UpdateRequest( - 'sensitive_data_table', // Replace with your actual table name - updateData - ); - - // Step 4: Configure Update Options - const updateOptions: UpdateOptions = new UpdateOptions(); - updateOptions.setReturnTokens(true); // Specify whether to return tokens in the response - updateOptions.setTokens(tokens); // The tokens associated with specific columns - updateOptions.setTokenMode(TokenMode.ENABLE); // Specifies the tokenization mode (ENABLE means tokenization is applied) - - // Step 5: Send the request to the Skyflow vault and update the record - const response: UpdateResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) - .update(updateReq, updateOptions); - - // Step 6: Print the response to confirm the update result - console.log('Update successful:', response); -} catch(error) { - // Step 7: Handle any errors that occur during the update operation - if (error instanceof SkyflowError) { - console.error('Skyflow Specific Error:', { - code: error.error?.http_code, - message: error.message, - details: error.error?.details - }); - } else { - console.error('Unexpected Error:', error); - } -} -``` - -#### An [example](https://github.com/skyflowapi/skyflow-node/blob/v2/samples/vault-api/update-record.ts) of update call - -```typescript -import { - UpdateRequest, - UpdateOptions, - UpdateResponse, - SkyflowError, - TokenMode -} from 'skyflow-node'; - -/* -This example demonstrates how to update a record in the Skyflow vault with specified data and tokens. +import { UpdateRequest, UpdateResponse } from 'skyflow-node'; -1. Initializes the Skyflow client with a given vault ID. -2. Constructs an update request with data to modify and tokens to include. -3. Sends the request to update the record in the vault. -4. Prints the response to confirm the success or failure of the update operation. -*/ +const updateRequest = new UpdateRequest('table1', { + skyflowId: '', + : '', + : '' +}); -try { - // Initialize Skyflow client - // Step 1: Prepare the data to update in the vault - // Use a dictionary to store the data that will be updated in the specified table - const updateData: Record = { - skyflowId: '5b699e2c-4301-4f9f-bcff-0a8fd3057413', // Skyflow ID for identifying the record to update - name: 'john doe' //Example of a column name and its value to update - card_number: '4111111111111115'// Another example of a column name and its value to update - }; - - // Step 2: Prepare the tokens (if necessary) for certain columns that require tokenization - const tokens: Record = { - name: '72b8ffe3-c8d3-4b4f-8052-38b2a7405b5a' // Example of a column name that should be tokenized - } +const response: UpdateResponse = await skyflowClient + .vault('') + .update(updateRequest); - // Step 3: Create an UpdateRequest to specify the update operation - const updateReq: UpdateRequest = new UpdateRequest( - 'table1', // Replace with your actual table name - updateData - ); - - // Step 4: Configure Update Options - const updateOptions: UpdateOptions = new UpdateOptions(); - updateOptions.setTokens(tokens); // The tokens associated with specific columns - updateOptions.setTokenMode(TokenMode.ENABLE); // Specifies the tokenization mode (ENABLE means tokenization is applied) - - // Step 5: Send the request to the Skyflow vault and update the record - const response: UpdateResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) - .update(updateReq, updateOptions); - - // Step 6: Print the response to confirm the update result - console.log('Update successful:', response); -} catch(error) { - // Step 7: Handle any errors that occur during the update operation - if (error instanceof SkyflowError) { - console.error('Skyflow Specific Error:', { - code: error.error?.http_code, - message: error.message, - details: error.error?.details - }); - } else { - console.error('Unexpected Error:', error); - } -} +console.log('Update response:', response); ``` -Sample response: - -- When `returnTokens` is set to `True` - -```typescript -UpdateResponse { - updatedField: { - skyflowId: '5b699e2c-4301-4f9f-bcff-0a8fd3057413', - name: '72b8ffe3-c8d3-4b4f-8052-38b2a7405b5a', - card_number: '4131-1751-0217-8491' - }, - errors: null -} -``` - -- When `returnTokens` is set to `False` - -```typescript -UpdateResponse { - updatedField: { - skyflowId: '5b699e2c-4301-4f9f-bcff-0a8fd3057413', - }, - errors: null -} -``` +> [!TIP] +> See the full example in the samples directory: [update-record.ts](samples/vault-api/update-record.ts) -### Delete +### Delete Records To delete records using Skyflow IDs, use the `delete` method. The `DeleteRequest` class accepts a list of Skyflow IDs that you want to delete, as shown below: -#### Construct a delete request - ```typescript -import { DeleteRequest, DeleteResponse, SkyflowError } from "skyflow-node"; +import { DeleteRequest, DeleteResponse } from "skyflow-node"; -/* -This example demonstrates how to delete records from a Skyflow vault using specified Skyflow IDs, along with corresponding DeleteRequest schema. -*/ +const deleteRequest = new DeleteRequest("table1", [ + "", + "", + "", +]); -try { - // Initialize Skyflow client - // Step 1: Prepare a list of Skyflow IDs for the records to delete - // The list stores the Skyflow IDs of the records that need to be deleted from the vault - const deleteIds: Array = [ - "", - "", - "", - ]; // Replace with actual Skyflow IDs - const tableName: string = ""; // Replace with the actual table name from which to delete - - // Step 2: Create a DeleteRequest to define the delete operation - const deleteRequest: DeleteRequest = new DeleteRequest(tableName, deleteIds); - - // Step 3: Send the delete request to the Skyflow vault - const response: DeleteResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) - .delete(deleteRequest); - - // Print the response to confirm the delete result - console.log("Deletion successful:", response); -} catch (error) { - // Step 4: Handle any exceptions that occur during the delete operation - if (error instanceof SkyflowError) { - console.error("Skyflow Specific Error:", { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); - } else { - console.error("Unexpected Error:", error); - } -} -``` - -#### An [example](https://github.com/skyflowapi/skyflow-node/blob/v2/samples/vault-api/delete-records.ts) of delete call - -```typescript -import { DeleteRequest, DeleteResponse, SkyflowError } from "skyflow-node"; +const response: DeleteResponse = await skyflowClient + .vault("") + .delete(deleteRequest); -/* -This example demonstrates how to delete records from a Skyflow vault using specified Skyflow IDs. - -1. Initializes the Skyflow client with a given Vault ID. -2. Constructs a delete request by specifying the IDs of the records to delete. -3. Sends the delete request to the Skyflow vault to delete the specified records. -4. Prints the response to confirm the success or failure of the delete operation. -*/ - -try { - // Initialize Skyflow client - // Step 1: Prepare a list of Skyflow IDs for the records to delete - // The list stores the Skyflow IDs of the records that need to be deleted from the vault - const deleteIds: Array = [ - "9cbf66df-6357-48f3-b77b-0f1acbb69280", - "ea74bef4-f27e-46fe-b6a0-a28e91b4477b", - "47700796-6d3b-4b54-9153-3973e281cafb", - ]; // Replace with actual Skyflow IDs - const tableName: string = "table1"; // Replace with the actual table name from which to delete - - // Step 2: Create a DeleteRequest to define the delete operation - const deleteRequest: DeleteRequest = new DeleteRequest(tableName, deleteIds); - - // Step 3: Send the delete request to the Skyflow vault - const response: DeleteResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) - .delete(deleteRequest); - - // Print the response to confirm the delete result - console.log("Deletion successful:", response); -} catch (error) { - // Step 4: Handle any exceptions that occur during the delete operation - if (error instanceof SkyflowError) { - console.error("Skyflow Specific Error:", { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); - } else { - console.error("Unexpected Error:", error); - } -} +console.log("Delete response:", response); ``` -Sample response: - -```typescript -DeleteResponse { - deletedIds: [ - '9cbf66df-6357-48f3-b77b-0f1acbb69280', - 'ea74bef4-f27e-46fe-b6a0-a28e91b4477b', - '47700796-6d3b-4b54-9153-3973e281cafb' - ], - errors: null -} -``` +> [!TIP] +> See the full example in the samples directory: [delete-records.ts](samples/vault-api/delete-records.ts) ### Query To retrieve data with SQL queries, use the `query` method. `QueryRequest` is class that takes the `query` parameter as follows: -#### Construct a query request - Refer to [Query your data](https://docs.skyflow.com/query-data/) and [Execute Query](https://docs.skyflow.com/record/#QueryService_ExecuteQuery) for guidelines and restrictions on supported SQL statements, operators, and keywords. -```typescript -import { QueryRequest, QueryResponse, SkyflowError } from "skyflow-node"; - -/* -This example demonstrates how to execute a custom SQL query on a Skyflow vault, along with QueryRequest schema. -*/ - -try { - // Initialize Skyflow client - // Step 1: Define the SQL query to execute on the Skyflow vault - // Replace "" with the actual SQL query you want to run - const query: string = ""; // Example: "SELECT * FROM table1 WHERE column1 = 'value'" - - // Step 2: Create a QueryRequest with the specified SQL query - const queryRequest: QueryRequest = new QueryRequest(query); - - // Step 3: Execute the query request on the specified Skyflow vault - const response: QueryResponse = await skyflowClient - .vault("") // Replace with your actual Vault ID - .query(queryRequest); - - // Step 4: Print the response containing the query results - console.log("Query Result:", response); -} catch (error) { - // Step 5: Handle any exceptions that occur during the query execution - if (error instanceof SkyflowError) { - console.error("Skyflow Specific Error:", { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); - } else { - console.error("Unexpected Error:", error); - } -} -``` - -#### An [example](https://github.com/skyflowapi/skyflow-node/blob/v2/samples/vault-api/query-records.ts) of query call - -```typescript -import { QueryRequest, QueryResponse, SkyflowError } from "skyflow-node"; - -/* -This example demonstrates how to execute a SQL query on a Skyflow vault to retrieve data. - -1. Initializes the Skyflow client with the Vault ID. -2. Constructs a query request with a specified SQL query. -3. Executes the query against the Skyflow vault. -4. Prints the response from the query execution. -*/ - -try { - // Initialize Skyflow client - // Step 1: Define the SQL query to execute on the Skyflow vault - // Example query: Retrieve all records from the "cards" table with a specific skyflow_id - const query: string = - "SELECT * FROM cards WHERE skyflow_id='3ea3861-x107-40w8-la98-106sp08ea83f'"; - - // Step 2: Create a QueryRequest with the specified SQL query - const queryRequest: QueryRequest = new QueryRequest(query); - - // Step 3: Execute the query request on the specified Skyflow vault - const response: QueryResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) // Replace with actual Vault ID - .query(queryRequest); - - // Step 4: Print the response containing the query results - console.log("Query Result:", response); -} catch (error) { - // Step 5: Handle any exceptions that occur during the query execution - if (error instanceof SkyflowError) { - console.error("Skyflow Specific Error:", { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); - } else { - console.error("Unexpected Error:", error); - } -} -``` - -Sample Response: - -```typescript -QueryResponse { - fields: [ - { - card_number: 'XXXXXXXXXXXX1112', - name: 'S***ar', - skyflow_id: '3ea3861-x107-40w8-la98-106sp08ea83f', - tokenizedData: {} - } - ], - errors: null, -} -``` - -### Upload File - -To upload files to a Skyflow vault, use the `uploadFile` method. The `FileUploadRequest` class accepts parameters such as the table name, column name and skyflow ID. And `FileUploadOptions` class accepts the file object as shown below: - -```typescript -// Please use Node version 20 & above to run file upload -import { - FileUploadRequest, - FileUploadResponse, - FileUploadOptions, - SkyflowError, -} from "skyflow-node"; -import * as fs from "fs"; +```typescript +import { QueryRequest, QueryResponse } from "skyflow-node"; -/* -This example demonstrates how to upload file to Skyflow vault with FileUploadRequest and FileUploadOptions schema. -*/ +const queryRequest = new QueryRequest( + "SELECT * FROM table1 WHERE column1 = 'value'", +); -try { - // Initialize Skyflow client - // Step 1: 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 2: Create File Upload Request - const uploadReq: FileUploadRequest = new FileUploadRequest( - tableName, - skyflowId, - columnName, - ); - - // Step 3: Configure FileUpload Options - const uploadOptions: FileUploadOptions = new FileUploadOptions(); - // Set any one of FilePath, Base64 or FileObject in FileUploadOptions - - const buffer = fs.readFileSync(filePath); - uploadOptions.setFileObject(new File([buffer], filePath)); // Set a File object - - // Step 4: Perform File Upload - const response: FileUploadResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) - .uploadFile(uploadReq, uploadOptions); - - // Handle Successful Response - console.log("File upload successful:", response); -} catch (error) { - // Step 5: Handle any exceptions that occur during the query execution - if (error instanceof SkyflowError) { - console.error("Skyflow Specific Error:", { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); - } else { - console.error("Unexpected Error:", error); - } -} +const response: QueryResponse = await skyflowClient + .vault("") + .query(queryRequest); + +console.log("Query response:", response); ``` -### An [example](https://github.com/skyflowapi/skyflow-node/blob/main/samples/vault-api/file-upload.ts) of file upload call +> [!TIP] +> See the full example in the samples directory: [query-records.ts](samples/vault-api/query-records.ts) + +### Upload File + +To upload files to a Skyflow vault, use the `uploadFile` method. The `FileUploadRequest` class accepts parameters such as the table name, column name and skyflow ID. And `FileUploadOptions` class accepts the file object as shown below: ```typescript // Please use Node version 20 & above to run file upload @@ -1497,74 +476,71 @@ import { } from "skyflow-node"; import * as fs from "fs"; -/* -This example demonstrates how to upload file to Skyflow vault with FileUploadRequest and FileUploadOptions schema. +// 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 -1. Initializes the Skyflow client with the Vault ID. -2. Constructs a file upload request and file upload options with specified filepath or file object -3. Uploads the file to the Skyflow vault. -4. Prints the response from the file upload operation -*/ +// Create File Upload Request +const uploadReq: FileUploadRequest = new FileUploadRequest( + tableName, + skyflowId, + columnName, +); -try { - // Initialize Skyflow client - // Step 1: Prepare File Upload Data - const tableName: string = "cards"; - const skyflowId: string = "c9312531-2087-439a-bd26-74c41f24db83"; // Skyflow ID of the record - const columnName: string = "license"; // Column name to store file - const filePath: string = "/images/license.png"; // Path to the file for upload - - // Step 2: Create File Upload Request - const uploadReq: FileUploadRequest = new FileUploadRequest( - tableName, - skyflowId, - columnName, - ); - - // Step 3: Configure FileUpload Options - const uploadOptions: FileUploadOptions = new FileUploadOptions(); - // Set any one of FilePath, Base64 or FileObject in FileUploadOptions - - const buffer = fs.readFileSync(filePath); - uploadOptions.setFileObject(new File([buffer], filePath)); // Set a File object - - // Step 4: Perform File Upload - const response: FileUploadResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) - .uploadFile(uploadReq, uploadOptions); - - // Handle Successful Response - console.log("File upload successful:", response); -} catch (error) { - // Step 5: Handle any exceptions that occur during the query execution - if (error instanceof SkyflowError) { - console.error("Skyflow Specific Error:", { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); - } else { - console.error("Unexpected Error:", error); - } -} +// Configure FileUpload Options +const uploadOptions: FileUploadOptions = new FileUploadOptions(); +const buffer = fs.readFileSync(filePath); +// Set any one of FilePath, Base64 or FileObject in FileUploadOptions +uploadOptions.setFileObject(new File([buffer], filePath)); // Set a File object + +// Perform File Upload +const response: FileUploadResponse = await skyflowClient + .vault(primaryVaultConfig.vaultId) + .uploadFile(uploadReq, uploadOptions); + +console.log("File upload:", response); ``` -Sample Response: +> [!TIP] +> See the full example in the samples directory: [file-upload.ts](samples/vault-api/file-upload.ts) + +### Get Tokens by Values: `.tokenize(request)` + +The `.tokenize()` method is used to retrieve tokens for values which already exist in the vault. Think of it as a "Get Tokens by Value" action. + +This method does not generate new tokens, only returns existing tokens from the vault. + +#### Construct a `.tokenize()` request ```typescript -FileUploadResponse { - skyflowId: 'c9312531-2087-439a-bd26-74c41f24db83', - errors: null -} +import { TokenizeRequest, TokenizeResponse } from "skyflow-node"; + +const tokenizeRequest = new TokenizeRequest([ + { value: "", columnGroup: "" }, + { value: "", columnGroup: "" }, +]); + +const response: TokenizeResponse = await skyflowClient + .vault("") + .tokenize(tokenizeRequest); + +console.log("Tokenization Result:", response); ``` +> [!TIP] +> See the full example in the samples directory: [tokenize-records.ts](samples/vault-api/tokenize-records.ts) + ## Detect Skyflow Detect enables you to deidentify and reidentify sensitive data in text and files, supporting advanced privacy-preserving workflows. -### Deidentify Text `deidentifyText()` +### De-identify Text: `.deidentifyText(request, options)` -To deidentify text, use the `deidentifyText` method. The `DeidentifyTextRequest` class creates a deidentify text request, which includes the text to be deidentified. Additionally, you can provide optional parameters using the `DeidentifyTextOptions` class. +To de-identify or _anonymize_ text, use the `deidentifyText` method. + +The `DeidentifyTextRequest` class creates a deidentify text request, which includes the text to be deidentified. Additionally, you can provide optional parameters using the `DeidentifyTextOptions` class. ```typescript import { @@ -1577,170 +553,41 @@ import { DetectEntities, } from "skyflow-node"; -try { - // Step 1: Prepare the text to be deidentified - const deidentifyTextRequest = new DeidentifyTextRequest( - "", - ); - - // Step 2: Configure DeidentifyTextOptions - const options = new DeidentifyTextOptions(); - options.setEntities([DetectEntities.ACCOUNT_NUMBER, DetectEntities.SSN]); // Entities to deidentify - 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 transformations = new Transformations(); // Specify custom transformations for entities - transformations.setShiftDays({ - max: 30, // Maximum shift days - min: 30, // Minimum shift days - entities: [DetectEntities.ACCOUNT_NUMBER, DetectEntities.SSN], // Entities to apply the shift - }); - optionsText.setTransformations(transformations); - - // Step 3: Call deidentifyText - const response = await skyflowClient - .detect(primaryVaultConfig.vaultId) - .deidentifyText(deidentifyTextRequest, options); +// Prepare the text to be deidentified +const deidentifyTextRequest = new DeidentifyTextRequest( + "", +); - console.log("Deidentify Text Response:", response); -} catch (error) { - if (error instanceof SkyflowError) { - console.error("Skyflow Error:", error.message); - } else { - console.error("Unexpected Error:", JSON.stringify(error)); - } -} -``` +// Configure DeidentifyTextOptions +const options = new DeidentifyTextOptions(); +options.setEntities([DetectEntities.ACCOUNT_NUMBER, DetectEntities.SSN]); // Entities to deidentify +options.setAllowRegexList([""]); // Allowlist regex patterns +options.setRestrictRegexList([""]); // Restrict regex patterns -#### An example of a deidentify text call +const tokenFormat = new TokenFormat(); // Specify the token format for deidentified entities +tokenFormat.setDefault(TokenType.VAULT_TOKEN); +optionsText.setTokenFormat(tokenFormat); -```typescript -import { - SkyflowError, - DeidentifyTextRequest, - DeidentifyTextOptions, - TokenFormat, - TokenType, - Transformations, - DetectEntities, - DeidentifyTextResponse, -} from "skyflow-node"; +const transformations = new Transformations(); // Specify custom transformations for entities +transformations.setShiftDays({ + max: 30, // Maximum shift days + min: 30, // Minimum shift days + entities: [DetectEntities.ACCOUNT_NUMBER, DetectEntities.SSN], // Entities to apply the shift +}); +optionsText.setTransformations(transformations); -/** - * Skyflow Deidentify Text Example - * - * This example demonstrates how to: - * 1. Configure credentials - * 2. Set up vault configuration - * 3. Create a deidentify text request - * 4. Use all available options for de-identification - * 5. Handle response and errors - */ - -async function performDeidentifyText() { - try { - // Step 1: Prepare Deidentify Text Request - const textReq = new DeidentifyTextRequest( - "My SSN is 123-45-6789 and my card is 4111 1111 1111 1111.", // Text to be deidentified - ); - - // Step 2: Configure DeidentifyTextOptions - const optionsText = new DeidentifyTextOptions(); - - // setEntities: Specify which entities to deidentify - optionsText.setEntities([ - DetectEntities.SSN, - DetectEntities.CREDIT_CARD_NUMBER, - ]); - - // setTokenFormat: Specify the token format for deidentified entities - const tokenFormat = new TokenFormat(); - tokenFormat.setDefault(TokenType.VAULT_TOKEN); - optionsText.setTokenFormat(tokenFormat); - - // setTransformations: Specify custom transformations for entities - const transformations = new Transformations(); - transformations.setShiftDays({ - max: 30, // Maximum shift days - min: 30, // Minimum shift days - entities: [DetectEntities.DOB], // Entities to apply the shift - }); - optionsText.setTransformations(transformations); - - // Step 3: Call deidentifyText API - const response: DeidentifyTextResponse = await skyflowClient - .detect(primaryVaultConfig.vaultId) - .deidentifyText(textReq, optionsText); - - // Handle Successful Response - console.log("Deidentify Text Response:", response); - } catch (error) { - // Comprehensive Error Handling - if (error instanceof SkyflowError) { - console.error("Skyflow Specific Error:", { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); - } else { - console.error("Unexpected Error:", JSON.stringify(error)); - } - } -} +// Call deidentifyText +const response = await skyflowClient + .detect(primaryVaultConfig.vaultId) + .deidentifyText(deidentifyTextRequest, options); -// Invoke the deidentify text function -performDeidentifyText(); +console.log("Deidentify Text Response:", response); ``` -Sample Response: - -```typescript -{ - "processedText": "My SSN is [SSN_0ykQWPA] and my card is [CREDIT_CARD_N92QAVa].", - "entities": [ - { - "token": "SSN_0ykQWPA", - "value": "123-45-6789", - "textIndex": { - "start": 10, - "end": 21 - }, - "processedIndex": { - "start": 10, - "end": 23 - }, - "entity": "SSN", - "scores": { - "SSN": 0.9383999705314636 - } - }, - { - "token": "CREDIT_CARD_N92QAVa", - "value": "4111 1111 1111 1111", - "textIndex": { - "start": 37, - "end": 56 - }, - "processedIndex": { - "start": 39, - "end": 60 - }, - "entity": "CREDIT_CARD", - "scores": { - "CREDIT_CARD": 0.9050999879837 - } - } - ], - "wordCount": 9, - "charCount": 57 -} -``` +> [!TIP] +> See the full example in the samples directory: [deidentify-text.ts](samples/detect-api/deidentify-text.ts) -### Reidentify Text +### Re-identify Text: `.reidentifyText(request, options)` To reidentify text, use the `reidentifyText` method. The `ReidentifyTextRequest` class creates a reidentify text request, which includes the redacted or de-identified text to be re-identified. Additionally, you can provide optional parameters using the `ReidentifyTextOptions` class to control how specific entities are returned (as redacted, masked, or plain text). @@ -1753,111 +600,31 @@ import { ReidentifyTextResponse, } from "skyflow-node"; -try { - // Step 1: Prepare the redacted text to be re-identified - const textReq = new ReidentifyTextRequest(""); - - // Step 2: Configure ReidentifyTextOptions - const options = new ReidentifyTextOptions(); - options.setRedactedEntities([DetectEntities.SSN]); // Entities to keep redacted - options.setMaskedEntities([DetectEntities.CREDIT_CARD_NUMBER]); // Entities to mask - options.setPlainTextEntities([DetectEntities.NAME]); // Entities to return as plain text - - // Step 3: Call reidentifyText - const response: ReidentifyTextResponse = await skyflowClient - .detect(primaryVaultConfig.vaultId) - .reidentifyText(textReq, options); - - console.log("Reidentify Text Response:", response); -} catch (error) { - // Comprehensive Error Handling - if (error instanceof SkyflowError) { - console.error("Skyflow Specific Error:", { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); - } else { - console.error("Unexpected Error:", JSON.stringify(error)); - } -} -``` - -#### An example of a reidentify text call +// Prepare the redacted text to be re-identified +const request = new ReidentifyTextRequest(""); -```typescript -import { - ReidentifyTextRequest, - ReidentifyTextOptions, - DetectEntities, - ReidentifyTextResponse, -} from "skyflow-node"; +// Configure ReidentifyTextOptions +const options = new ReidentifyTextOptions(); +options.setRedactedEntities([DetectEntities.SSN]); // Entities to keep redacted +options.setMaskedEntities([DetectEntities.CREDIT_CARD_NUMBER]); // Entities to mask +options.setPlainTextEntities([DetectEntities.NAME]); // Entities to return as plain text -/** - * Skyflow Reidentify Text Example - * - * This example demonstrates how to: - * 1. Configure credentials - * 2. Set up vault configuration - * 3. Create a reidentify text request - * 4. Use all available options for re-identification - * 5. Handle response and errors - */ - -async function performReidentifyText() { - try { - // Step 1: Prepare Reidentify Text Request - const reidentifyTextRequest = new ReidentifyTextRequest( - "My SSN is [SSN_0ykQWPA] and my card is [CREDIT_CARD_N92QAVa].", // The redacted text to reidentify - ); - - // Step 2: Configure ReidentifyTextOptions - const options = new ReidentifyTextOptions(); - - // Specify which entities to reidentify as redacted, masked, or plain text - options.setPlainTextEntities([ - DetectEntities.CREDIT_CARD, - DetectEntities.SSN, - ]); - - // Step 4: Call reidentifyText - const response: ReidentifyTextResponse = await skyflowClient - .detect(primaryVaultConfig.vaultId) - .reidentifyText(reidentifyTextRequest, options); - - // Step 5: Handle response - console.log("Re-identified Text Response:", response); - } catch (error) { - // Comprehensive Error Handling - if (error instanceof SkyflowError) { - console.error("Skyflow Specific Error:", { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); - } else { - console.error("Unexpected Error:", JSON.stringify(error)); - } - } -} +// Call reidentifyText +const response: ReidentifyTextResponse = await skyflowClient + .detect(primaryVaultConfig.vaultId) + .reidentifyText(request, options); -// Invoke the reidentify text function -performReidentifyText(); +console.log("Reidentify Text Response:", response); ``` -Sample Response: - -```typescript -{ - processedText: "My SSN is 123-45-6789 and my card is 4111 1111 1111 1111."; -} -``` +> [!TIP] +> See the full example in the samples directory: [reidentify-text.ts](samples/detect-api/reidentify-text.ts) -### Deidentify File +### Deidentify File: `.deidentifyFile(fileReq, options)` To deidentify files, use the `deidentifyFile` method. The `DeidentifyFileRequest` class creates a deidentify file request, which includes the file to be deidentified (such as images, PDFs, audio, documents, spreadsheets, or presentations). Additionally, you can provide optional parameters using the `DeidentifyFileOptions` class to control how entities are detected and deidentified, as well as how the output is generated for different file types. -**Note:** File de-identification requires Node.js version 20 or above. +**Note:** File de-identification requires Node.js v20.x or above. ```typescript import { @@ -1871,202 +638,43 @@ import { Bleep } from 'skyflow-node'; -try { - // Step 1: Prepare the file to be deidentified - const filePath: string = ''; - const buffer = fs.readFileSync(filePath); - const file = new File([buffer], filePath); - - //Step 2: Construct the file input by providing either file or filePath but not both - const fileInput: FileInput = { file: file } - // const fileInput: FileInput = { filePath: filePath } - const fileReq = new DeidentifyFileRequest(fileInput); - - // Step 3: Configure DeidentifyFileOptions - const options = new DeidentifyFileOptions(); - options.setEntities([DetectEntities.SSN, DetectEntities.ACCOUNT_NUMBER]); - options.setAllowRegexList(['']); - options.setRestrictRegexList(['']); - - const tokenFormat = new TokenFormat(); // Token format for deidentified entities - tokenFormat.setDefault(TokenType.ENTITY_ONLY); - options.setTokenFormat(tokenFormat); - - const transformations = new Transformations(); // transformations for entities - transformations.setShiftDays({ - max: 30, - min: 10, - entities: [DetectEntities.SSN], - }); - options.setTransformations(transformations); - - options.setOutputDirectory(''); // Output directory for saving the deidentified file. This is not supported in Cloudflare workers - - options.setWaitTime(15); // Wait time for response (max 64 seconds; throws error if more) - - // ===== Image Options (apply when file is an image) ===== - - // options.setOutputProcessedImage(true); // Include processed image in output - - // options.setOutputOcrText(true); // Include OCR text in response - - // options.setMaskingMethod(MaskingMethod.Blackbox); // Masking method for image entities - - // ===== PDF Options (apply when file is a PDF) ===== - - // options.setPixelDensity(300); // Pixel density for PDF processing +// Prepare the file to be deidentified +const filePath: string = ''; +const buffer = fs.readFileSync(filePath); +const file = new File([buffer], filePath); - // options.setMaxResolution(2000); // Max resolution for PDF +// Construct the file input by providing either a file object or file path, but not both +const fileInput: FileInput = { file: file } // OR const fileInput: FileInput = { filePath: filePath } +const fileReq = new DeidentifyFileRequest(fileInput); - // ===== Audio Options (apply when file is audio) ===== +// Configure DeidentifyFileOptions +const options = new DeidentifyFileOptions(); +options.setEntities([DetectEntities.SSN, DetectEntities.ACCOUNT_NUMBER]); +options.setAllowRegexList(['']); +options.setRestrictRegexList(['']); - // options.setOutputProcessedAudio(true); // Include processed audio in output +const tokenFormat = new TokenFormat(); // Token format for deidentified entities +tokenFormat.setDefault(TokenType.ENTITY_ONLY); +options.setTokenFormat(tokenFormat); - // options.setOutputTranscription(DetectOutputTranscription.PLAINTEXT_TRANSCRIPTION); // Type of transcription +const transformations = new Transformations(); // transformations for entities +transformations.setShiftDays({ + max: 30, + min: 10, + entities: [DetectEntities.SSN], +}); +options.setTransformations(transformations); - // const bleep = new Bleep(); // Bleep audio configuration - // bleep.setGain(5); // Relative loudness in dB - // bleep.setFrequency(1000); // Pitch in Hz - // bleep.setStartPadding(0.1); // Padding at start in seconds - // bleep.setStopPadding(0.2); // Padding at end in seconds - // options.setBleep(bleep); - - // Step 4: Call deidentifyFile - const response: DeidentifyFileResponse = await skyflowClient - .detect(primaryVaultConfig.vaultId) - .deidentifyFile(fileReq, options); - - console.log('Deidentify File Response:', response); - -} catch (error) { - // Comprehensive Error Handling - if (error instanceof SkyflowError) { - console.error('Skyflow Specific Error:', { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); - } else { - console.error('Unexpected Error:', JSON.stringify(error)); - } -} -``` - -#### An example of a deidentify file - -```typescript -import { - SkyflowError, - DeidentifyFileRequest, - DeidentifyFileOptions, - DetectEntities, - TokenFormat, - TokenType, - Transformations, - DeidentifyFileResponse, -} from "skyflow-node"; -import fs from "fs"; - -/** - * Skyflow Deidentify File Example - * - * This sample demonstrates how to use all available options for de-identifying files. - * Supported file types: images (jpg, png, etc.), pdf, audio (mp3, wav), documents, spreadsheets, presentations, structured text. - */ - -async function performDeidentifyFile() { - try { - // Step 1: Prepare Deidentify File Request - // Replace with your file object (e.g., from fs.readFileSync or browser File API) - const filePath: string = "/detect/sample.txt"; - const buffer = fs.readFileSync(filePath); - const file = new File([buffer], filePath); - - //Step 2: Construct the file input by providing either file or filePath but not both - const fileInput: FileInput = { file: file }; - // const fileInput: FileInput = { filePath: filePath } - - const fileReq = new DeidentifyFileRequest(fileInput); - - // Step 3: Configure DeidentifyFileOptions - const options = new DeidentifyFileOptions(); - - // Entities to detect and deidentify - options.setEntities([DetectEntities.SSN, DetectEntities.ACCOUNT_NUMBER]); - - // Token format for deidentified entities - const tokenFormat = new TokenFormat(); - tokenFormat.setDefault(TokenType.ENTITY_ONLY); - options.setTokenFormat(tokenFormat); - - // Custom transformations for entities - const transformations = new Transformations(); - transformations.setShiftDays({ - max: 30, - min: 10, - entities: [DetectEntities.SSN], - }); - options.setTransformations(transformations); - - // Output directory for saving the deidentified file - options.setOutputDirectory("/home/user/output"); // Replace with your desired output directory. This is not supported in Cloudflare workers - - // Wait time for response (max 64 seconds) - options.setWaitTime(15); - - // Step 4: Call deidentifyFile API - const response: DeidentifyFileResponse = await skyflowClient - .detect(primaryVaultConfig.vaultId) - .deidentifyFile(fileReq, options); - - // Handle Successful Response - console.log("Deidentify File Response:", response); - } catch (error) { - // Comprehensive Error Handling - if (error instanceof SkyflowError) { - console.error("Skyflow Specific Error:", { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); - } else { - console.error("Unexpected Error:", JSON.stringify(error)); - } - } -} +options.setOutputDirectory(''); // Output directory for saving the deidentified file. This is not supported in Cloudflare workers -// Invoke the deidentify file function -performDeidentifyFile(); -``` +options.setWaitTime(64); // Wait time for response (max 64 seconds; throws error if more) -Sample Response: +// Call deidentifyFile +const response: DeidentifyFileResponse = await skyflowClient + .detect(primaryVaultConfig.vaultId) + .deidentifyFile(fileReq, options); -```typescript -{ - entities: [ - { - file: '0X2xhYmVsIjoiQ1JFRElUX0NB==', - extension: 'json' - } - ], - fileBase64: 'TXkgU1NOIGlzIFtTU0==', - file: File { - size: 15075, - type: '', - name: 'deidentified.jpeg', - lastModified: 1750791985426 - }, - type: 'redacted_file', - extension: 'txt', - wordCount: 12, - charCount: 58, - sizeInKb: 0.06, - durationInSeconds: 0, - pageCount: 0, - slideCount: 0, - runId: undefined, - status: 'SUCCESS' -} +console.log('Deidentify File Response:', response); ``` **Supported file types:** @@ -2079,39 +687,20 @@ Sample Response: - Presentations: `ppt`, `pptx` - Audio: `mp3`, `wav` -**Note:** +**Notes:** - Transformations cannot 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. -- If the API takes more than 64 seconds to process the file, it will return only the run ID in the response. - -Sample response (when the API takes more than 64 seconds): - -```typescript - -{ - entities: undefined, - file: undefined, - type: undefined, - extension: undefined, - wordCount: undefined, - charCount: undefined, - sizeInKb: undefined, - durationInSeconds: undefined, - pageCount: undefined, - slideCount: undefined, - runId: '1ad6dc12-8405-46cf-1c13-db1123f9f4c5', - status: 'IN_PROGRESS' -} -``` +> [!TIP] +> See the full example in the samples directory: [deidentify-file.ts](samples/detect-api/deidentify-file.ts) -### Get run +### Get Run: `.getDetectRun(request)` -To retrieve the results of a previously started file de-identification operation, use the `getDetectRun` method. -The `GetDetectRunRequest` class is initialized with the `runId` returned from a prior `deidentifyFile` call. -This method allows you to fetch the final results of the file processing operation once they are available. +To retrieve the results of a previously started file de-identification operation - or 'run' - use the `getDetectRun(...)` method. +The `GetDetectRunRequest` class is initialized with the `runId` returned from a prior `.deidentifyFile(fileReq, options)` call. +This method allows you to fetch the final results of the file de-identification operation once they are available. ```typescript import { @@ -2121,131 +710,22 @@ import { SkyflowError } from 'skyflow-node'; -try { - // Step 1: Prepare the GetDetectRunRequest with the runId from a previous deidentifyFile call - const getDetectRunRequest = new GetDetectRunRequest({ - runId: '', // Replace with the runId you received earlier - }); - - // Step 2: Call getDetectRun - const response: DeidentifyFileResponse = await skyflowClient - .detect(primaryVaultConfig.vaultId) - .getDetectRun(getDetectRunRequest); - - // Step 3: Handle the response - console.log('Get Detect Run Response:', response); - -} catch (error) { - if (error instanceof SkyflowError) { - console.error('Skyflow Error:', error.message); - } else { - console.error('Unexpected Error:', error); - } -} -``` - -#### An example of a get run function - -```typescript -import { - Credentials, - Env, - LogLevel, - Skyflow, - SkyflowConfig, - VaultConfig, - SkyflowError, - GetDetectRunRequest, - DeidentifyFileResponse, -} from "skyflow-node"; - -/** - * Skyflow Get Detect Run Example - * - * This example demonstrates how to: - * 1. Configure credentials - * 2. Set up vault configuration - * 3. Create a get detect run request - * 4. Call getDetectRun to poll for file processing results - * 5. Handle response and errors - */ - -async function performGetDetectRun() { - try { - // Step 1: Configure Credentials - const credentials: Credentials = { - token: "", // Replace with your BEARER token - }; - - // Step 2: Configure Vault - const primaryVaultConfig: VaultConfig = { - vaultId: "", // Unique vault identifier - clusterId: "", // From vault URL - env: Env.PROD, // Deployment environment - credentials: credentials, // Authentication method - }; - - // Step 3: Configure Skyflow Client - const skyflowConfig: SkyflowConfig = { - vaultConfigs: [primaryVaultConfig], - logLevel: LogLevel.INFO, // Recommended to use LogLevel.ERROR in production environment. - }; - - // Initialize Skyflow Client - const skyflowClient: Skyflow = new Skyflow(skyflowConfig); - - // Step 4: Prepare GetDetectRunRequest - const getDetectRunRequest = new GetDetectRunRequest({ - runId: "", // Replace with the runId from a previous deidentifyFile call - }); +// Prepare the GetDetectRunRequest with the runId from a previous deidentifyFile call +const request = new GetDetectRunRequest({ + runId: '', // Replace with the runId you received earlier +}); - // Step 5: Call getDetectRun API - const response: DeidentifyFileResponse = await skyflowClient - .detect(primaryVaultConfig.vaultId) - .getDetectRun(getDetectRunRequest); - - // Handle Successful Response - console.log("Get Detect Run Response:", response); - } catch (error) { - // Comprehensive Error Handling - if (error instanceof SkyflowError) { - console.error("Skyflow Specific Error:", { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); - } else { - console.error("Unexpected Error:", error); - } - } -} +// Step 2: Call getDetectRun +const response: DeidentifyFileResponse = await skyflowClient + .detect(primaryVaultConfig.vaultId) + .getDetectRun(request); -// Invoke the get detect run function -performGetDetectRun(); +// Step 3: Handle the response +console.log('Get Detect Run Response:', response); ``` -Sample Response - -```typescript -{ - entities: [ - { - file: '0X2xhYmVsIjoiQ1JFRElUX0NB==', - extension: 'json' - } - ], - file: 'TXkgU1NOIGlzIFtTU0==', - type: 'redacted_file', - extension: 'txt', - wordCount: 12, - charCount: 58, - sizeInKb: 0.06, - durationInSeconds: 0, - pageCount: 0, - slideCount: 0, - status: 'SUCCESS' -} -``` +> [!TIP] +> See the full example in the samples directory: [get-detect-run.ts](samples/detect-api/get-detect-run.ts) ## Connections @@ -2264,85 +744,31 @@ To invoke a connection, use the `invoke` method of the Skyflow client. import { InvokeConnectionRequest, RequestMethod, - ConnectionConfig, - SkyflowError, InvokeConnectionResponse, } from "skyflow-node"; -/* -This example demonstrates how to invoke an external connection using the Skyflow SDK, along with corresponding InvokeConnectionRequest schema. -*/ +const invokeRequest = new InvokeConnectionRequest( + RequestMethod.POST, + { : "" }, + { : "" }, + { : "" }, + { : "" } +); -try { - // Initialize Skyflow client - // Step 1: Define the request body parameters - // These are the values you want to send in the request body - const requestBody = { - COLUMN_NAME_1: "", // Replace with actual key-value pairs - COLUMN_NAME_2: "", - }; - - // Step 2: Define the request headers - // Add any required headers that need to be sent with the request - const requestHeaders = { - HEADER_NAME_1: "", - HEADER_NAME_2: "", - }; - - // Step 3: Define the path parameters - // Path parameters are part of the URL and typically used in RESTful APIs - const pathParams = { - YOUR_PATH_PARAM_KEY_1: "", - YOUR_PATH_PARAM_KEY_2: "", - }; - - // Step 4: Define the query parameters - // Query parameters are included in the URL after a '?' and are used to filter or modify the response - const queryParams = { - YOUR_QUERY_PARAM_KEY_1: "", - YOUR_QUERY_PARAM_KEY_2: "", - }; - - // Step 5: Define the request method - const requestMethod: RequestMethod = RequestMethod.POST; - - // Step 6: Build the InvokeConnectionRequest using the provided parameters - const invokeReq: InvokeConnectionRequest = new InvokeConnectionRequest( - requestMethod, - requestBody, - requestHeaders, - pathParams, - queryParams, - ); - - // Step 7: Invoke the connection using the request - const response: InvokeConnectionResponse = await skyflowClient - .connection() - .invoke(invokeReq); - - // Step 8: Print the response from the invoked connection - console.log("Connection invocation successful:", response); -} catch (error) { - // Step 9: Handle any exceptions that occur during the connection invocation - if (error instanceof SkyflowError) { - console.error("Skyflow Specific Error:", { - code: error.error?.http_code, - message: error.message, - details: error.error?.details, - }); - } else { - console.error("Unexpected Error:", error); - } -} +const response: InvokeConnectionResponse = await skyflowClient + .connection() + .invoke(invokeRequest); + +console.log("Invoke connection response:", response); ``` -`method` supports the following methods: +The method of `RequestMethod.POST` must be one of: -- GET -- POST -- PUT -- PATCH -- DELETE +- `GET` +- `POST` +- `PUT` +- `PATCH` +- `DELETE` **pathParams, queryParams, header, body** are the JSON objects represented as dictionaries that will be sent through the connection integration url. @@ -2350,7 +776,28 @@ try { > See the full example in the samples directory: [scoped-token-generation-example.ts](samples/vault-api/invoke-connection.ts) > See [docs.skyflow.com](https://docs.skyflow.com) for more details on integrations with Connections, Functions, and Pipelines. -## Governance, identity, and access control +## Authentication & authorization + + +### Types of `credentials` +Skyflow allows four different kinds of authentication and authorization through the API and SDKs: + +1. **API keys** + A unique identifier used to authenticate and authorize requests to an API. + +2. **Bearer tokens** + A temporary access token used to authenticate API requests, typically included in the + Authorization header. This can be generated with a signed JWT for production use (see below) or passed in directly. + Developers can also copy a personal bearer token from the Skyflow Studio UI to get started quickly. + +3. **Service account credentials file path** + The file path pointing to a JSON file containing credentials for a service account, used + for secure API access by generating bearer tokens on-demand. + +4. **Service account credentials string** + JSON-formatted string containing service account credentials, often used as an alternative to a file for secure API access by generating bearer tokens on-demand. + +**Note: Only one type of credential can be used at a time. If multiple credentials are provided, the last one added will take precedence.** ### Generate bearer tokens for authentication & authorization @@ -2389,67 +836,59 @@ generateBearerToken('path/to/credentials.json') ##### `generateBearerTokenFromCreds(credentials)` -Alternatively, you can also send the entire credentials as string by using `generateBearerTokenFromCreds(credentials)`. - -```js -let bearerToken: string = ''; -generateBearerTokenFromCreds(credentialsString) - .then(response => { - bearerToken = response.accessToken; - // Resolve the generated Bearer Token - resolve(bearerToken); - }) - .catch(error => { - // Handle any errors that occur during the generation process - reject(error); - }); -``` +Alternatively, you can also send the entire credentials as string by using `generateBearerTokenFromCreds(string)`. > [!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 with context - -**Context-aware authorization** embeds context values into a bearer token during its generation and so you can reference those values in your policies. This enables more flexible access controls, such as helping you track end-user identity when making API calls using service accounts, and facilitates using signed data tokens during detokenization. +#### Generate bearer tokens scoped to certain roles -A service account with the context_id identifier generates bearer tokens containing context information, represented as a JWT claim in a Skyflow-generated bearer token. Tokens generated from such service accounts include a context_identifier claim, are valid for 60 minutes, and can be used to make API calls to the Data and Management APIs, depending on the service account's permissions. +A service account with multiple roles can generate bearer tokens with access limited to a specific role by specifying the appropriate roleID. This can be used to limit access to specific roles for services with multiple responsibilities, such as segregating access for billing and analytics. The generated bearer tokens are valid for 60 minutes and can only execute operations permitted by the permissions associated with the designated role. ```ts -generateBearerTokenFromCreds(JSON.stringify({ - clientID: '', - clientName: '', - keyID: '', - tokenURI: '', - privateKey: '', -}), { - ctx: 'context_id', // the user's context identifier -}) +const options = { + roleIDs: ['roleID1', 'roleID2'], +}; ``` > [!TIP] -> See the full example in the samples directory: [token-generation-with-context-example.ts](samples/service-account/token-generation-with-context-example.ts) +> See the full example in the samples directory: [scoped-token-generation-example.ts](samples/service-account/scoped-token-generation-example.ts) > See [docs.skyflow.com](https://docs.skyflow.com) for more details on authentication, access control, and governance for Skyflow. -#### Generate scoped bearer tokens +#### Generate a bearer tokens with `ctx` -A service account with multiple roles can generate bearer tokens with access limited to a specific role by specifying the appropriate roleID. This can be used to limit access to specific roles for services with multiple responsibilities, such as segregating access for billing and analytics. The generated bearer tokens are valid for 60 minutes and can only execute operations permitted by the permissions associated with the designated role. +**Context-aware authorization** embeds context values into a bearer token during its generation and so you can reference those values in your policies. This enables more flexible access controls, such as helping you track end-user identity when making API calls using service accounts, and facilitates using signed data tokens during detokenization. + +A service account with the context_id identifier generates bearer tokens containing context information, represented as a JWT claim in a Skyflow-generated bearer token. Tokens generated from such service accounts include a context_identifier claim, are valid for 60 minutes, and can be used to make API calls to the Data and Management APIs, depending on the service account's permissions. + +```ts +generateBearerTokenFromCreds( + JSON.stringify({ + clientID: "", + clientName: "", + keyID: "", + tokenURI: "", + privateKey: "", + }), + { + ctx: "context_id", // the user's context identifier + }, +); +``` > [!TIP] -> See the full example in the samples directory: [scoped-token-generation-example.ts](samples/service-account/scoped-token-generation-example.ts) +> See the full example in the samples directory: [token-generation-with-context-example.ts](samples/service-account/token-generation-with-context-example.ts) > See [docs.skyflow.com](https://docs.skyflow.com) for more details on authentication, access control, and governance for Skyflow. -#### Generate signed data tokens +#### Generate signed data tokens: `generateSignedDataTokens(filepath, options)` Skyflow generates data tokens when sensitive data is inserted into the vault. These data tokens can be digitally signed with a service account's private key, adding an extra layer of protection. Signed tokens can only be detokenized 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. -- `generateSignedDataTokens(filepath, options);` -- `generateSignedDataTokensFromCreds(credentialsString, options)` - > [!TIP] > 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. -## Logging & error handling +## Logging The SDK provides useful logging. By default the logging level of the SDK is set to `LogLevel.ERROR`. This can be changed by setting the `logLevel` in Skyflow Config while creating the Skyflow Client as shown below: @@ -2471,16 +910,39 @@ Currently, the following five log levels are supported: ### Example `skyflowConfig.logLevel: LogLevel.INFO` ```ts - const skyflowConfig: SkyflowConfig = { - vaultConfigs: [vaultConfig], // Add the Vault configuration - skyflowCredentials: skyflowCredentials, // Use Skyflow credentials if no token is passed - logLevel: LogLevel.INFO, // Recommended to use LogLevel.ERROR in production environment. - }; +const skyflowConfig: SkyflowConfig = { + vaultConfigs: [vaultConfig], // Add the Vault configuration + skyflowCredentials: skyflowCredentials, // Use Skyflow credentials if no token is passed + logLevel: LogLevel.INFO, // Recommended to use LogLevel.ERROR in production environment. +}; + +const skyflowClient: Skyflow = new Skyflow(skyflowConfig); +``` - const skyflowClient: Skyflow = new Skyflow(skyflowConfig); +## Error handling + +### Catching `SkyflowError` instances + +As a best practice always wrap your calls to the Skyflow SDK in try / catch blocks. The SDK provides the `SkyflowError` type which can be used to identify errors coming from Skyflow versus general request / response errors. + +```ts +try { + // ...call the Skyflow SDK +} catch (error) { + // catch an error, identify if it is a SkyflowError + if (error instanceof SkyflowError) { + console.error("Skyflow Specific Error:", { + code: error.error?.http_code, + message: error.message, + details: error.error?.details, + }); + } else { + console.error("Unexpected Error:", JSON.stringify(error)); + } +} ``` -#### Bearer token expiration edge cases +### Bearer token expiration edge cases When you use bearer tokens for authentication and API requests in SDKs, there's the potential for a token to expire after the token is verified as valid but before the actual API call is made, causing the request to fail unexpectedly due to the token's expiration. An error from this edge case would look something like this: @@ -2498,4 +960,4 @@ If you encounter this kind of error, retry the request. During the retry the SDK ### Reporting a Vulnerability -If you discover a potential security issue in this project, please reach out to us at **security@skyflow.com**. Please do not create public GitHub issues or Pull Requests, as malicious actors could potentially view them. +If you discover a potential security issue in this project, please reach out to us at [mailto:security@skyflow.com](security@skyflow.com). Please do not create public GitHub issues or Pull Requests, as malicious actors could potentially view them. diff --git a/docs/generate_bearer_tokens.md b/docs/generate_bearer_tokens.md index e69de29b..312479fe 100644 --- a/docs/generate_bearer_tokens.md +++ b/docs/generate_bearer_tokens.md @@ -0,0 +1,20 @@ + + + +1. **API keys** + A unique identifier used to authenticate and authorize requests to an API. + +2. **Bearer tokens** + A temporary access token used to authenticate API requests, typically included in the + Authorization header. + +3. **Service account credentials file path** + The file path pointing to a JSON file containing credentials for a service account, used + for secure API access. + +4. **Service account credentials string** + JSON-formatted string containing service account credentials, often used as an alternative to a file for programmatic authentication. + +Note: Only one type of credential can be used at a time. If multiple credentials are provided, the last one added will take precedence. + + From f84d100b54e646aa03226678977a299b894c0956 Mon Sep 17 00:00:00 2001 From: Joseph McCarron Date: Fri, 14 Nov 2025 02:42:21 -0600 Subject: [PATCH 04/15] rename and prep docs/auth_credentials.md file --- ...ate_bearer_tokens.md => auth_credentials.md} | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) rename docs/{generate_bearer_tokens.md => auth_credentials.md} (87%) diff --git a/docs/generate_bearer_tokens.md b/docs/auth_credentials.md similarity index 87% rename from docs/generate_bearer_tokens.md rename to docs/auth_credentials.md index 312479fe..caa6e961 100644 --- a/docs/generate_bearer_tokens.md +++ b/docs/auth_credentials.md @@ -1,20 +1,29 @@ +# Authentication credentials options - +Note: Only one type of credential can be used at a time. If multiple credentials are provided, the last one added will take precedence. 1. **API keys** A unique identifier used to authenticate and authorize requests to an API. + ```ts + ``` + 2. **Bearer tokens** A temporary access token used to authenticate API requests, typically included in the Authorization header. + ```ts + ``` + 3. **Service account credentials file path** The file path pointing to a JSON file containing credentials for a service account, used for secure API access. + ```ts + ``` + 4. **Service account credentials string** JSON-formatted string containing service account credentials, often used as an alternative to a file for programmatic authentication. -Note: Only one type of credential can be used at a time. If multiple credentials are provided, the last one added will take precedence. - - + ```ts + ``` From d3d6452415a196be33411a215801bcfdb82cc2f1 Mon Sep 17 00:00:00 2001 From: Joseph McCarron Date: Fri, 14 Nov 2025 02:51:26 -0600 Subject: [PATCH 05/15] auth credentials file --- docs/auth_credentials.md | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/docs/auth_credentials.md b/docs/auth_credentials.md index caa6e961..891c598a 100644 --- a/docs/auth_credentials.md +++ b/docs/auth_credentials.md @@ -2,28 +2,43 @@ Note: Only one type of credential can be used at a time. If multiple credentials are provided, the last one added will take precedence. -1. **API keys** +1. **API keys** A unique identifier used to authenticate and authorize requests to an API. ```ts + const credentials = { + apiKey: "" + }; ``` -2. **Bearer tokens** +2. **Bearer tokens** A temporary access token used to authenticate API requests, typically included in the Authorization header. ```ts + const credentials = { + token: "" + }; ``` -3. **Service account credentials file path** +3. **Service account credentials file path** The file path pointing to a JSON file containing credentials for a service account, used for secure API access. ```ts + const credentials = { + path: "" + }; ``` -4. **Service account credentials string** +4. **Service account credentials string** JSON-formatted string containing service account credentials, often used as an alternative to a file for programmatic authentication. ```ts - ``` + const credentials = { + credentialsString: JSON.stringify(process.env.SKYFLOW_CREDENTIALS) + }; + ``` + +5. **Environment variables** + Automatically uses the SKYFLOW_CREDENTIALS environment variable when no credentials are explicitly provided. This variable must return an object like one of the examples above. From c189af2af7dab19c7cfd7e4c7b8a4d3d0c0ffd8e Mon Sep 17 00:00:00 2001 From: Joseph McCarron Date: Fri, 14 Nov 2025 03:08:00 -0600 Subject: [PATCH 06/15] cleaned up auth section, expanded on examples with types in auth_credentials.md --- README.md | 68 +++++++++----------- docs/advanced_initialization.md | 110 ++++++++++---------------------- docs/auth_credentials.md | 8 +-- 3 files changed, 68 insertions(+), 118 deletions(-) diff --git a/README.md b/README.md index 729d36dd..0de3f8bc 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,11 @@ The Skyflow SDK for Node.js, Deno, Bun, and Cloudflare Workers. - [All imports](#all-imports) - [Quickstart](#quickstart) - [Authenticate](#authenticate) + - [API Key](#api-key) + - [Bearer Token (static)](#bearer-token-static) - [Initialize the client](#initialize-the-client) - [Insert data into the vault, get tokens back](#insert-data-into-the-vault-get-tokens-back) + - [Upgrade from v1 to v2](#upgrade-from-v1-to-v2) - [Vault](#vault) - [Insert and tokenize data](#insert-and-tokenize-data) - [Construct an insert request](#construct-an-insert-request) @@ -53,7 +56,7 @@ The Skyflow SDK for Node.js, Deno, Bun, and Cloudflare Workers. - [`generateBearerToken(filepath)`](#generatebearertokenfilepath) - [`generateBearerTokenFromCreds(credentials)`](#generatebearertokenfromcredscredentials) - [Generate bearer tokens scoped to certain roles](#generate-bearer-tokens-scoped-to-certain-roles) - - [Generate a bearer tokens with `ctx`](#generate-a-bearer-tokens-with-ctx) + - [Generate a bearer tokens with `ctx` for context-aware authorization](#generate-a-bearer-tokens-with-ctx-for-context-aware-authorization) - [Generate signed data tokens: `generateSignedDataTokens(filepath, options)`](#generate-signed-data-tokens-generatesigneddatatokensfilepath-options) - [Logging](#logging) - [Example `skyflowConfig.logLevel: LogLevel.INFO`](#example-skyflowconfigloglevel-loglevelinfo) @@ -110,13 +113,26 @@ Get started quickly with the essential steps: authenticate, initialize the clien ### Authenticate -You can use an API key to authenticate and authorize requests to an API. For authenticating via bearer tokens and different supported bearer token types, refer to the [Authenticate with bearer tokens](#authenticate-with-bearer-tokens) section. +You can use an API key or a personal bearer token to directly authenticate and authorize requests with the SDK. -```javascript -// create a new credentials object -const credentials = { apiKey: "" }; //add your API key in credentials +### API Key + +```typescript +const credentials: Credentials = { + apiKey: "", +}; +``` + +### Bearer Token (static) + +```typescript +const credentials: Credentials = { + token: "", +}; ``` +For authenticating via generated bearer tokens including support for scoped tokens, context-aware access tokens, and more refer to the [Authentication & Authorization](#authentication--authorization) section. + ### Initialize the client To get started, you must first initialize the skyflow client. While initializing the skyflow client, you can specify different types of credentials. @@ -146,13 +162,7 @@ const skyflowConfig: SkyflowConfig = { const skyflowClient: Skyflow = new Skyflow(skyflowConfig); ``` -For advanced initialization examples including multiple vaults and different credential types, see [docs/advanced_initialization.md](docs/advanced_initialization.md). - -Notes - -- If both Skyflow common credentials and individual credentials at the configuration level are specified, the individual credentials at the configuration level will take precedence. -- If neither Skyflow common credentials nor individual configuration-level credentials are provided, the SDK attempts to retrieve credentials from the `SKYFLOW_CREDENTIALS` environment variable. -- All Vault operations require a client instance. +For advanced initialization examples including examples using multiple vaults and different credential types, see [docs/advanced_initialization.md](docs/advanced_initialization.md). ### Insert data into the vault, get tokens back @@ -181,6 +191,10 @@ const insertResponse = await skyflowClient console.log("Insert response:", insertResponse); ``` +## Upgrade from v1 to v2 + +For those upgrading from `skyflow-node` v1, we have a dedicated guide in [docs/migrate_to_v2](docs/migrate_to_v2.md). + ## Vault The [Vault](https://docs.skyflow.com/docs/vaults) performs operations on the vault such as inserting records, detokenizing tokens, retrieving tokens for list of `skyflow_id`'s and to invoke the Connection. @@ -778,8 +792,8 @@ The method of `RequestMethod.POST` must be one of: ## Authentication & authorization - ### Types of `credentials` + Skyflow allows four different kinds of authentication and authorization through the API and SDKs: 1. **API keys** @@ -801,16 +815,7 @@ Skyflow allows four different kinds of authentication and authorization through ### Generate bearer tokens for authentication & authorization -This section covers methods for generating and managing bearer tokens to authenticate API calls: - -- **Generate a bearer token:** - Enable the creation of bearer tokens using service account credentials. These tokens, valid for 60 minutes, provide secure access to Vault services and management APIs based on the service account's permissions. Use this for general API calls when you only need basic authentication without additional context or role-based restrictions. See: [token-generation-example.ts](http://github.com/skyflowapi/skyflow-node/blob/v2/samples/service-account/token-generation-example.ts) -- **Generate a bearer token with context:** - Support embedding context values into bearer tokens, enabling dynamic access control and the ability to track end-user identity. These tokens include context claims and allow flexible authorization for Vault services. Use this when policies depend on specific contextual attributes or when tracking end-user identity is required. -- **Generate a scoped bearer token:** - Facilitate the creation of bearer tokens with role-specific access, ensuring permissions are limited to the operations allowed by the designated role. This is particularly useful for service accounts with multiple roles. Use this to enforce fine-grained role-based access control, ensuring tokens only grant permissions for a specific role. -- **Generate signed data tokens:** - Add an extra layer of security by digitally signing data tokens with the service account's private key. These signed tokens can be securely detokenized, provided the necessary bearer token and permissions are available. Use this to add cryptographic protection to sensitive data, enabling secure detokenization with verified integrity and authenticity. +This section covers methods for generating and managing bearer tokens to authenticate API calls, including options for scoping to certain roles, passing context, and signing data tokens. #### Generate a bearer token @@ -855,27 +860,12 @@ const options = { > See the full example in the samples directory: [scoped-token-generation-example.ts](samples/service-account/scoped-token-generation-example.ts) > See [docs.skyflow.com](https://docs.skyflow.com) for more details on authentication, access control, and governance for Skyflow. -#### Generate a bearer tokens with `ctx` +#### Generate a bearer tokens with `ctx` for context-aware authorization **Context-aware authorization** embeds context values into a bearer token during its generation and so you can reference those values in your policies. This enables more flexible access controls, such as helping you track end-user identity when making API calls using service accounts, and facilitates using signed data tokens during detokenization. A service account with the context_id identifier generates bearer tokens containing context information, represented as a JWT claim in a Skyflow-generated bearer token. Tokens generated from such service accounts include a context_identifier claim, are valid for 60 minutes, and can be used to make API calls to the Data and Management APIs, depending on the service account's permissions. -```ts -generateBearerTokenFromCreds( - JSON.stringify({ - clientID: "", - clientName: "", - keyID: "", - tokenURI: "", - privateKey: "", - }), - { - ctx: "context_id", // the user's context identifier - }, -); -``` - > [!TIP] > See the full example in the samples directory: [token-generation-with-context-example.ts](samples/service-account/token-generation-with-context-example.ts) > See [docs.skyflow.com](https://docs.skyflow.com) for more details on authentication, access control, and governance for Skyflow. diff --git a/docs/advanced_initialization.md b/docs/advanced_initialization.md index 390cf0b4..ecfad035 100644 --- a/docs/advanced_initialization.md +++ b/docs/advanced_initialization.md @@ -6,13 +6,13 @@ This guide demonstrates advanced initialization patterns for the Skyflow Node SD ```typescript import { - Credentials, - Env, - LogLevel, - Skyflow, - VaultConfig, - SkyflowConfig, -} from 'skyflow-node'; + Credentials, + Env, + LogLevel, + Skyflow, + VaultConfig, + SkyflowConfig, +} from "skyflow-node"; /* Example program to initialize the Skyflow client with various configurations. @@ -29,28 +29,28 @@ such as securely managing sensitive data. // Initialize primary credentials using a Bearer token for authentication. const primaryCredentials: Credentials = { - token: '', // Replace with your actual authentication token. + token: "", // Replace with your actual authentication token. }; // Step 2: Configure the primary vault details. // VaultConfig stores all necessary details to connect to a specific Skyflow vault. const primaryVaultConfig: VaultConfig = { - vaultId: '', // Replace with your primary vault ID - clusterId: '', // Replace with the cluster ID (part of the vault URL, e.g., https://{clusterId}.vault.skyflowapis.com). - env: Env.PROD, // Set the environment (PROD, SANDBOX, STAGE, DEV). - credentials: primaryCredentials // Attach the primary credentials to this vault configuration. + vaultId: "", // Replace with your primary vault ID + clusterId: "", // Replace with the cluster ID (part of the vault URL, e.g., https://{clusterId}.vault.skyflowapis.com). + env: Env.PROD, // Set the environment (PROD, SANDBOX, STAGE, DEV). + credentials: primaryCredentials, // Attach the primary credentials to this vault configuration. }; // Step 3: Create credentials as a JSON object (if a Bearer Token is not provided). // Demonstrates an alternate approach to authenticate with Skyflow using a credentials object. const skyflowCredentials: object = { - clientID: '', // Replace with your Client ID. - clientName: '', // Replace with your Client Name. - tokenURI: '', // Replace with the Token URI. - keyID: '', // Replace with your Key ID. - privateKey: '' // Replace with your Private Key. -} + clientID: "", // Replace with your Client ID. + clientName: "", // Replace with your Client Name. + tokenURI: "", // Replace with the Token URI. + keyID: "", // Replace with your Key ID. + privateKey: "", // Replace with your Private Key. +}; // Step 4: Convert the JSON object to a string and use it as credentials. // This approach allows the use of dynamically generated or pre-configured credentials. @@ -59,39 +59,39 @@ const credentialsString: string = JSON.stringify(skyflowCredentials); // Convert // Step 5: Define secondary credentials (API key-based authentication as an example). // Demonstrates a different type of authentication mechanism for Skyflow vaults. const secondaryCredentials: Credentials = { - apiKey: '', // Replace with your API Key for authentication. -} + apiKey: "", // Replace with your API Key for authentication. +}; // Step 6: Configure the secondary vault details. // A secondary vault configuration can be used for operations involving multiple vaults. const secondaryVaultConfig: VaultConfig = { - vaultId: '', // Replace with your secondary vault's ID. - clusterId: '', // Replace with the corresponding cluster ID. - env: Env.PROD, // Set the environment for this vault. - credentials: secondaryCredentials // Attach the secondary credentials to this configuration. -} + vaultId: "", // Replace with your secondary vault's ID. + clusterId: "", // Replace with the corresponding cluster ID. + env: Env.PROD, // Set the environment for this vault. + credentials: secondaryCredentials, // Attach the secondary credentials to this configuration. +}; // Step 7: Define tertiary credentials using a path to a credentials JSON file. // This method demonstrates an alternative authentication method. const tertiaryCredentials: Credentials = { - path: '' // Replace with the path to your credentials file. -} + path: "", // Replace with the path to your credentials file. +}; // Step 8: Configure the tertiary vault details. const tertiaryVaultConfig: VaultConfig = { - vaultId: '', // Replace with the tertiary vault ID. - clusterId: '', // Replace with the corresponding cluster ID. - env: Env.PROD, // Set the environment for this vault. - credentials: tertiaryCredentials // Attach the tertiary credentials. -} + vaultId: "", // Replace with the tertiary vault ID. + clusterId: "", // Replace with the corresponding cluster ID. + env: Env.PROD, // Set the environment for this vault. + credentials: tertiaryCredentials, // Attach the tertiary credentials. +}; // Step 9: Build and initialize the Skyflow client after creating Skyflow Config // Skyflow client is configured with multiple vaults and credentials. const skyflowConfig: SkyflowConfig = { - vaultConfigs: [primaryVaultConfig, secondaryVaultConfig, tertiaryVaultConfig], // Add the primary, secondary and tertiary vault configurations. - skyflowCredentials: skyflowCredentials, // Add JSON-formatted credentials if applicable. - logLevel: LogLevel.INFO // Recommended to use LogLevel.ERROR in production environment. + vaultConfigs: [primaryVaultConfig, secondaryVaultConfig, tertiaryVaultConfig], // Add the primary, secondary and tertiary vault configurations. + skyflowCredentials: skyflowCredentials, // Add JSON-formatted credentials if applicable. + logLevel: LogLevel.INFO, // Recommended to use LogLevel.ERROR in production environment. }; // Step 10: Initialize Skyflow Client @@ -104,43 +104,3 @@ const skyflowClient: Skyflow = new Skyflow(skyflowConfig); // - Deleting data // within the configured Skyflow vaults. ``` - -## Credential Types - -The SDK supports multiple credential types: - -### Bearer Token -```typescript -const credentials: Credentials = { - token: '' -}; -``` - -### API Key -```typescript -const credentials: Credentials = { - apiKey: '' -}; -``` - -### Credentials Object -```typescript -const skyflowCredentials = { - clientID: '', - clientName: '', - tokenURI: '', - keyID: '', - privateKey: '' -}; -``` - -### Credentials File Path -```typescript -const credentials: Credentials = { - path: '' -}; -``` - -## Environment Variables - -If neither Skyflow common credentials nor individual configuration-level credentials are provided, the SDK attempts to retrieve credentials from the `SKYFLOW_CREDENTIALS` environment variable. diff --git a/docs/auth_credentials.md b/docs/auth_credentials.md index 891c598a..05d90bf1 100644 --- a/docs/auth_credentials.md +++ b/docs/auth_credentials.md @@ -6,7 +6,7 @@ Note: Only one type of credential can be used at a time. If multiple credentials A unique identifier used to authenticate and authorize requests to an API. ```ts - const credentials = { + const credentials: Credentials = { apiKey: "" }; ``` @@ -16,7 +16,7 @@ Note: Only one type of credential can be used at a time. If multiple credentials Authorization header. ```ts - const credentials = { + const credentials: Credentials = { token: "" }; ``` @@ -26,7 +26,7 @@ Note: Only one type of credential can be used at a time. If multiple credentials for secure API access. ```ts - const credentials = { + const credentials: Credentials = { path: "" }; ``` @@ -35,7 +35,7 @@ Note: Only one type of credential can be used at a time. If multiple credentials JSON-formatted string containing service account credentials, often used as an alternative to a file for programmatic authentication. ```ts - const credentials = { + const credentials: Credentials = { credentialsString: JSON.stringify(process.env.SKYFLOW_CREDENTIALS) }; ``` From ea79020796e09ac1c5997997eb0fb8fede34660b Mon Sep 17 00:00:00 2001 From: Joseph McCarron Date: Fri, 14 Nov 2025 03:14:42 -0600 Subject: [PATCH 07/15] upsert --- README.md | 51 ++++++++++++++------------------------------------- 1 file changed, 14 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 0de3f8bc..c9fbfedb 100644 --- a/README.md +++ b/README.md @@ -23,12 +23,12 @@ The Skyflow SDK for Node.js, Deno, Bun, and Cloudflare Workers. - [Insert data into the vault, get tokens back](#insert-data-into-the-vault-get-tokens-back) - [Upgrade from v1 to v2](#upgrade-from-v1-to-v2) - [Vault](#vault) - - [Insert and tokenize data](#insert-and-tokenize-data) - - [Construct an insert request](#construct-an-insert-request) + - [Insert and tokenize data: `.insert(request)`](#insert-and-tokenize-data-insertrequest) - [Insert example with `continueOnError` option](#insert-example-with-continueonerror-option) - - [Detokenize](#detokenize) + - [Upsert request](#upsert-request) + - [Detokenize: `.detokenize(request, options)`](#detokenize-detokenizerequest-options) - [Construct a detokenize request](#construct-a-detokenize-request) - - [Get Record(s)](#get-records) + - [Get Record(s): `.get(request, options)`](#get-records-getrequest-options) - [Construct a get request](#construct-a-get-request) - [Get by Skyflow IDs](#get-by-skyflow-ids) - [Get tokens for records](#get-tokens-for-records) @@ -199,12 +199,10 @@ For those upgrading from `skyflow-node` v1, we have a dedicated guide in [docs/m The [Vault](https://docs.skyflow.com/docs/vaults) performs operations on the vault such as inserting records, detokenizing tokens, retrieving tokens for list of `skyflow_id`'s and to invoke the Connection. -### Insert and tokenize data +### Insert and tokenize data: `.insert(request)` Apart from using the `insert` method to insert data into your vault covered in [Quickstart](#quickstart), you can also pass options to `insert` method to enable additional functionality such as returning tokenized data, upserting records, or allowing bulk operations to continue despite errors. -#### Construct an insert request - ```typescript import { InsertRequest, InsertResponse } from 'skyflow-node'; @@ -233,40 +231,19 @@ The `continueOnError` flag is a boolean that determines whether insert operation > [!TIP] > See the full example in the samples directory: [insert-continue-on-error.ts](samples/vault-api/insert-continue-on-error.ts) -**Insert call example with `upsert` option** -An upsert operation checks for a record based on a unique column's value. If a match exists, the record is updated; otherwise, a new record is inserted. - -```typescript -import { - InsertOptions, - InsertRequest, - SkyflowError, - InsertResponse, -} from "skyflow-node"; - -const insertData: Record[] = [ - { - cardholder_name: "John Doe", - }, -]; +#### Upsert request -const insertReq: InsertRequest = new InsertRequest( - "table1", // Specify the table in the vault where the data will be inserted - insertData, // Attach the data (records) to be inserted -); +The upsert option turns an insert into an 'update-or-insert' operation. When enabling this option, the vault checks for an existing record with the same value in the specified column. If a match exists, the record is updated; otherwise, a new record is inserted. -const insertOptions: InsertOptions = new InsertOptions(); -insertOptions.setReturnTokens(true); // Optional: Specify if tokens should be returned upon successful insertion +```typescript +// ... +// 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"); - -const insertResponse: InsertResponse = await skyflowClient - .vault(primaryVaultConfig.vaultId) - .insert(insertReq, insertOptions); - -console.log("Insert response: ", insertResponse); +// ... ``` -### Detokenize +### Detokenize: `.detokenize(request, options)` To convert tokens back into the plaintext values (or masked values), use the `.detokenize()` method. Detokenization accepts tokens and returns values. @@ -302,7 +279,7 @@ console.log("Detokenization response:", response); > [!TIP] > See the full example in the samples directory: [detokenzie-records.ts](samples/vault-api/detokenzie-records.ts) -### Get Record(s) +### Get Record(s): `.get(request, options)` To retrieve data using Skyflow IDs or unique column values, use the get method. The `GetRequest` class creates a get request, where you specify parameters such as the table name, redaction type, Skyflow IDs, column names, column values. If you specify Skyflow IDs, you can't use column names and column values, and the inverse is true—if you specify column names and column values, you can't use Skyflow IDs. And `GetOptions` class creates a get options object through which you specify whether to return tokens or not. From f829255234151c504c790b33268f7a24b8a3033d Mon Sep 17 00:00:00 2001 From: Joseph McCarron Date: Fri, 14 Nov 2025 03:19:59 -0600 Subject: [PATCH 08/15] credentials pointers --- README.md | 47 ++++++++++++++++++++++++++++++---------- docs/auth_credentials.md | 2 +- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index c9fbfedb..715bf998 100644 --- a/README.md +++ b/README.md @@ -771,22 +771,47 @@ The method of `RequestMethod.POST` must be one of: ### Types of `credentials` -Skyflow allows four different kinds of authentication and authorization through the API and SDKs: +The SDK accepts one of several types of credentials object. -1. **API keys** - A unique identifier used to authenticate and authorize requests to an API. +1. **API keys** + A unique identifier used to authenticate and authorize requests to an API. To create an API key you must first create a 'Service Account' in Skyflow and choose the 'API key' option during creation. -2. **Bearer tokens** - A temporary access token used to authenticate API requests, typically included in the - Authorization header. This can be generated with a signed JWT for production use (see below) or passed in directly. - Developers can also copy a personal bearer token from the Skyflow Studio UI to get started quickly. + ```ts + const credentials: Credentials = { + apiKey: "" + }; + ``` -3. **Service account credentials file path** +2. **Bearer tokens** + A temporary access token used to authenticate API requests. As a developer with the right access you can generate a temporary personal bearer token in Skyflow in the user menu. + + ```ts + const credentials: Credentials = { + token: "" + }; + ``` + +3. **Service account credentials file path** The file path pointing to a JSON file containing credentials for a service account, used - for secure API access by generating bearer tokens on-demand. + for secure API access. + + ```ts + const credentials: Credentials = { + path: "" + }; + ``` + +4. **Service account credentials string** + JSON-formatted string containing service account credentials, often used as an alternative to a file for programmatic authentication. + + ```ts + const credentials: Credentials = { + credentialsString: JSON.stringify(process.env.SKYFLOW_CREDENTIALS) + }; + ``` -4. **Service account credentials string** - JSON-formatted string containing service account credentials, often used as an alternative to a file for secure API access by generating bearer tokens on-demand. +5. **Environment variables** + If no credentials are explicitly provided the SDK automatically looks for the SKYFLOW_CREDENTIALS environment variable. This variable must return an object like one of the examples above. **Note: Only one type of credential can be used at a time. If multiple credentials are provided, the last one added will take precedence.** diff --git a/docs/auth_credentials.md b/docs/auth_credentials.md index 05d90bf1..698bfac9 100644 --- a/docs/auth_credentials.md +++ b/docs/auth_credentials.md @@ -41,4 +41,4 @@ Note: Only one type of credential can be used at a time. If multiple credentials ``` 5. **Environment variables** - Automatically uses the SKYFLOW_CREDENTIALS environment variable when no credentials are explicitly provided. This variable must return an object like one of the examples above. + If no credentials are explicitly provided the SDK automatically looks for the SKYFLOW_CREDENTIALS environment variable. This variable must return an object like one of the examples above. From 6b0dab2c59463425e30a2d68b13d57af1f872114 Mon Sep 17 00:00:00 2001 From: Joseph McCarron Date: Fri, 14 Nov 2025 03:25:22 -0600 Subject: [PATCH 09/15] removed extra auth file, leftover --- AUTH.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 AUTH.md diff --git a/AUTH.md b/AUTH.md deleted file mode 100644 index e69de29b..00000000 From 62c979b5d0815a50813e5a510b487d054b96db6f Mon Sep 17 00:00:00 2001 From: Manny Silva <102989456+manny-silva@users.noreply.github.com> Date: Fri, 14 Nov 2025 10:38:57 -0800 Subject: [PATCH 10/15] Feedback on the Node SDK content updates --- AGENTS.md | 304 ++++++++++++++++++++++++++++++++ README.md | 155 ++++++++-------- SECURITY.md | 4 +- docs/advanced_initialization.md | 2 + docs/auth_credentials.md | 10 +- docs/migrate_to_v2.md | 50 ++++-- samples/README.md | 144 ++++++--------- 7 files changed, 486 insertions(+), 183 deletions(-) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..3f07aa25 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,304 @@ +# Skyflow Node SDK - AI Coding Agent Instructions + +## Project Overview + +The Skyflow Node SDK is a TypeScript-based client library for Skyflow's data privacy vault, supporting Node.js, Deno, Bun, and Cloudflare Workers. It provides three primary API surfaces: **Vault** (data operations), **Detect** (PII detection/masking), and **Connections** (integration gateway). + +**Key Architecture:** +- **Client Layer** (`src/vault/client/`): Manages authentication, API initialization, and HTTP configuration +- **Controller Layer** (`src/vault/controller/`): Business logic for vault, detect, and connection operations +- **Model Layer** (`src/vault/model/`): Request/Response/Options classes for type-safe API interactions +- **Generated Code** (`src/_generated_/`): Auto-generated REST client (do not modify manually) + +## Request/Response Pattern + +All API operations follow a consistent pattern using dedicated classes: + +```typescript +// 1. Create a Request object +const insertReq = new InsertRequest('table_name', [{ field: 'value' }]); + +// 2. Create Options object (if needed) +const insertOptions = new InsertOptions(); +insertOptions.setReturnTokens(true); + +// 3. Call the operation through the client +const response: InsertResponse = await skyflowClient + .vault(vaultId) + .insert(insertReq, insertOptions); +``` + +**Key Classes:** +- Request classes: `InsertRequest`, `GetRequest`, `DetokenizeRequest`, `UpdateRequest`, etc. +- Options classes: `InsertOptions`, `GetOptions`, `DetokenizeOptions` (use setters, not direct property access) +- Response classes: `InsertResponse`, `GetResponse`, `DetokenizeResponse` (readonly data containers) + +## Authentication & Credentials + +The SDK supports five credential types (see `src/vault/config/credentials/index.ts`): + +1. **Bearer Token** (recommended): `{ token: 'token' }` +3. **Path to JSON**: `{ path: '/path/to/creds.json' }` +4. **Credentials String**: `{ credentialsString: JSON.stringify(creds) }` +5. **Environment Variable**: Auto-reads `SKYFLOW_CREDENTIALS` if no credentials provided +2. **API Key**: `{ apiKey: 'key' }` + +**Credentials Hierarchy:** +- Individual vault/connection credentials override common credentials +- Common credentials (`skyflowCredentials`) apply to all vaults/connections +- Use `validateSkyflowCredentials()` from `src/utils/validations/` for validation + +## Client Initialization + +The `Skyflow` class (in `src/vault/skyflow/index.ts`) manages multiple vaults and connections: + +```typescript +const skyflowConfig: SkyflowConfig = { + vaultConfigs: [vaultConfig1, vaultConfig2], + connectionConfigs: [connectionConfig], + skyflowCredentials: credentials, // Optional common credentials + logLevel: LogLevel.ERROR // Default: LogLevel.ERROR +}; + +const client = new Skyflow(skyflowConfig); +``` + +**Multi-Vault Access:** +- Access specific vault: `client.vault('vault-id-1')` +- Access first vault: `client.vault()` (no ID defaults to first) +- Same pattern for `.detect()` and `.connection()` + +## Error Handling Pattern + +Always wrap SDK calls in try/catch and check for `SkyflowError`: + +```typescript +try { + const response = await skyflowClient.vault(vaultId).insert(request); +} catch (error) { + if (error instanceof SkyflowError) { + // Structured error from Skyflow + console.error({ + code: error.error?.http_code, + message: error.message, + details: error.error?.details + }); + } else { + // Unexpected error + console.error('Unexpected error:', error); + } +} +``` + +**Error Structure:** See `src/error/index.ts` for `SkyflowError` class and `src/error/codes/` for error constants. + +## Testing Conventions + +- Tests use Jest (see `jest.config.js`) +- Test files: `test/**/*.test.js` (note: `.js` not `.ts`) +- Run tests: `npm test` (includes coverage) +- Coverage excludes: `src/_generated_`, model classes (request/response/options) +- Mock data: `test/mockData/` and `test/demo-credentials/` + +**Test Structure:** +```javascript +describe('ComponentName', () => { + it('should perform specific action', () => { + // Arrange + // Act + // Assert + }); +}); +``` + +## Build & Development Workflow + +**Essential Commands:** +- `npm run build` - Compile TypeScript to `lib/` (CommonJS) +- `npm test` - Run Jest tests with coverage +- `npm run lint` - Run prettier + eslint +- `npm run lint-fix` - Auto-fix formatting issues +- `npm run spellcheck` - Check spelling with cspell +- `npm run docs-gen` - Generate TypeDoc + process markdown + +**Build Output:** +- Compiled JS: `lib/` +- TypeScript config: `tsconfig.json` (target: ES6, module: CommonJS) +- Babel config: `babel.config.js` (for test transpilation) + +## Logging System + +Configure via `LogLevel` enum (in `src/utils/index.ts`): +- `LogLevel.DEBUG` - All logs (verbose) +- `LogLevel.INFO` - Info, warn, error +- `LogLevel.WARN` - Warn and error only +- `LogLevel.ERROR` - Error only (default) +- `LogLevel.OFF` - No logs + +**Usage:** +```typescript +import { printLog, MessageType, LogLevel } from './utils'; +printLog('message', MessageType.LOG, this.logLevel); +``` + +## Validation Pattern + +All inputs are validated using functions in `src/utils/validations/index.ts`: + +- `validateSkyflowConfig()` - Client configuration +- `validateVaultConfig()` - Vault setup +- `validateConnectionConfig()` - Connection setup +- `validateSkyflowCredentials()` - Credential objects + +**When adding new features:** +1. Add validation function in `src/utils/validations/` +2. Call validation early (constructor/method entry) +3. Throw `SkyflowError` with appropriate error code from `src/error/codes/` + +## Important File Locations + +- **Main exports**: `src/index.ts` (public API surface) +- **Client initialization**: `src/vault/skyflow/index.ts` +- **HTTP client**: `src/vault/client/index.ts` +- **Controllers**: `src/vault/controller/{vault,detect,connections}/` +- **Type definitions**: `src/vault/types/index.ts` +- **Utilities**: `src/utils/` (validations, logging, JWT helpers) +- **Service account auth**: `src/service-account/` +- **Sample code**: `samples/` (use as reference for common patterns) + +## Special Considerations + +1. **Bearer Token Expiry**: SDK auto-generates new tokens when expired. Edge case: token expires between validation and API call - solution is to retry the request. + +2. **Generated Code**: `src/_generated_/` contains Fern-generated REST clients. Never modify manually. These are initialized in `VaultClient.initAPI()` based on operation type. + +3. **File Operations**: Require Node.js v20+ for `File` API. See `src/vault/controller/detect/` for file handling examples. + +4. **Async Patterns**: All SDK operations return Promises. Controllers use `async/await`. Always propagate errors to callers. + +5. **V1 to V2 Migration**: See `docs/migrate_to_v2.md` for breaking changes. Key difference: class-based Request/Response/Options objects vs. plain objects. + +## Code Style Guidelines + +- **TypeScript**: Strict mode enabled, no implicit any +- **Naming**: PascalCase for classes, camelCase for functions/variables +- **Imports**: Use absolute paths from `src/`, export via `src/index.ts` +- **Error Messages**: Use parameterized strings from `src/utils/logs/` +- **Comments**: JSDoc for public APIs, inline comments for complex logic +- **Formatting**: Prettier + ESLint (run `npm run lint-fix` before commit) + +## When Adding New Features + +1. Create Request/Response/Options classes in `src/vault/model/` +2. Add controller method in appropriate controller +3. Update `src/index.ts` with exports +4. Add validation in `src/utils/validations/` +5. Write tests in `test/` +6. Add sample in `samples/` directory +7. Update TypeDoc comments for documentation generation + +## Documentation & README Standards + +### Core Writing Principles + +When creating or updating documentation (including README.md, samples, and code comments): + +1. **Research-driven creation**: Thoroughly research existing docs before writing. Create original content that addresses specific user scenarios—don't copy existing material. + +2. **Context-driven updates**: Analyze content structure and identify specific sections requiring changes. Improve clarity, accuracy, and completeness through thoughtful revision. + +3. **Quality assurance**: Resolve all IDE warnings and errors before finalizing. Iterate until documentation passes validation checks. + +4. **Consistency first**: Maintain uniform formatting, terminology, and structure while adapting content to user needs. + +### README.md Maintenance + +The README.md follows specific standards for SDK documentation: + +**Structure requirements:** +- **Project identification**: Name at top, clear owner/author identification, repository URL +- **Project evaluation**: Describe what the project *does* (not what it's *made of*)—focus on user benefits + - Use patterns like: "With Skyflow Node SDK you can securely handle sensitive data..." + - Write in second person (you), use action verbs, avoid passive voice + - Describe who may use it and under what terms (MIT license) +- **Usage help**: Prerequisites, installation steps, quickstart that works on first try +- **Engagement**: Links to docs, support channels, contribution guidelines + +**Writing style:** +- **Voice**: Conversational but professional, use second person ("you") +- **Sentences**: Under 26 words when possible, active voice, present tense +- **Instructions**: Start with verbs ("Create", "Configure", "Call") +- **Code formatting**: Single backticks for inline code (filenames, class names, methods), fenced blocks for multi-line examples +- **Links**: Descriptive text rather than raw URLs +- **Emphasis**: `_italics_` for key terms/concepts, `**bold**` for UI elements + +**Content organization:** +- Lead with most important information +- Break up text with headers, lists, formatting +- Use parallel structure in lists +- Keep README under 10-12 screens—move extensive content to separate docs +- Add table of contents if README exceeds 3-4 screens + +### Code Examples in Documentation + +All code examples must: +- Be **complete and working**—avoid placeholder or empty examples +- Include **realistic values** that demonstrate actual usage +- Add **explanatory comments** for key parts +- Show **error handling patterns** with `SkyflowError` +- Match the **class-based Request/Response/Options pattern** + +**Good example pattern:** +```typescript +// Step 1: Configure credentials +const credentials: Credentials = { + apiKey: 'your-skyflow-api-key', +}; + +// Step 2: Create request with actual data structure +const insertReq = new InsertRequest('table_name', [ + { card_number: '4111111111111112', cardholder_name: 'John Doe' } +]); + +// Step 3: Configure options using setters +const insertOptions = new InsertOptions(); +insertOptions.setReturnTokens(true); + +// Step 4: Execute with error handling +try { + const response = await skyflowClient.vault(vaultId).insert(insertReq, insertOptions); + console.log('Insert response:', response); +} catch (error) { + if (error instanceof SkyflowError) { + console.error({ + code: error.error?.http_code, + message: error.message + }); + } +} +``` + +### Progressive Disclosure Pattern + +When documenting features: +1. **Quickstart**: Minimal working example with most common use case +2. **Basic usage**: Core functionality with clear explanations +3. **Advanced options**: Link to detailed docs for complex scenarios +4. **Related concepts**: Cross-reference to related features + +### Formatting Standards + +- **Line length**: 80-character limit for readability (except URLs/code blocks) +- **Indentation**: 2 spaces (never tabs) +- **Code blocks**: Always include language identifier +- **Tables**: Use for structured comparisons (error codes, options, parameters) +- **Lists**: Use for sequential steps or feature enumerations + +### Testing Documentation + +Before finalizing any documentation: +1. **Test all code examples**—every snippet must execute successfully +2. **Verify all links** work and point to correct locations +3. **Check for consistency** with existing terminology and patterns +4. **Validate formatting** matches project standards +5. **Review for completeness**—ensure all required sections present diff --git a/README.md b/README.md index 715bf998..a78d6fc6 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Skyflow Node.js SDK -The Skyflow SDK for Node.js, Deno, Bun, and Cloudflare Workers. +Securely handle sensitive data at rest, in-transit, and in-use with the Skyflow SDK for Node.js, Deno, Bun, and Cloudflare Workers. [![CI](https://img.shields.io/static/v1?label=CI&message=passing&color=green?style=plastic&logo=github)](https://github.com/skyflowapi/skyflow-node/actions) [![GitHub release](https://badge.fury.io/js/skyflow-node.svg)](https://www.npmjs.com/package/skyflow-node) @@ -39,12 +39,12 @@ The Skyflow SDK for Node.js, Deno, Bun, and Cloudflare Workers. - [Delete Records](#delete-records) - [Query](#query) - [Upload File](#upload-file) - - [Get Tokens by Values: `.tokenize(request)`](#get-tokens-by-values-tokenizerequest) + - [Retrieve Existing Tokens: `.tokenize(request)`](#retrieve-existing-tokens-tokenizerequest) - [Construct a `.tokenize()` request](#construct-a-tokenize-request) - [Detect](#detect) - [De-identify Text: `.deidentifyText(request, options)`](#de-identify-text-deidentifytextrequest-options) - [Re-identify Text: `.reidentifyText(request, options)`](#re-identify-text-reidentifytextrequest-options) - - [Deidentify File: `.deidentifyFile(fileReq, options)`](#deidentify-file-deidentifyfilefilereq-options) + - [De-identify File: `.deidentifyFile(fileReq, options)`](#de-identify-file-deidentifyfilefilereq-options) - [Get Run: `.getDetectRun(request)`](#get-run-getdetectrunrequest) - [Connections](#connections) - [Invoke a connection](#invoke-a-connection) @@ -56,7 +56,7 @@ The Skyflow SDK for Node.js, Deno, Bun, and Cloudflare Workers. - [`generateBearerToken(filepath)`](#generatebearertokenfilepath) - [`generateBearerTokenFromCreds(credentials)`](#generatebearertokenfromcredscredentials) - [Generate bearer tokens scoped to certain roles](#generate-bearer-tokens-scoped-to-certain-roles) - - [Generate a bearer tokens with `ctx` for context-aware authorization](#generate-a-bearer-tokens-with-ctx-for-context-aware-authorization) + - [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) - [Logging](#logging) - [Example `skyflowConfig.logLevel: LogLevel.INFO`](#example-skyflowconfigloglevel-loglevelinfo) @@ -71,7 +71,7 @@ The Skyflow SDK for Node.js, Deno, Bun, and Cloudflare Workers. The Skyflow SDK enables you to connect to your Skyflow Vault(s) to securely handle sensitive data at rest, in-transit, and in-use. > [!IMPORTANT] -> This readme covers version 2 of the SDK. +> 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). > For more information on how to migrate see [MIGRATE_TO_V2.md](docs/migrate_to_v2.md). @@ -109,15 +109,17 @@ import { ## Quickstart -Get started quickly with the essential steps: authenticate, initialize the client, and perform a basic vault operation. This section provides a minimal setup to help you integrate the SDK efficiently. +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. ### Authenticate -You can use an API key or a personal bearer token to directly authenticate and authorize requests with the SDK. +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. ### API Key ```typescript +import { Credentials } from 'skyflow-node'; + const credentials: Credentials = { apiKey: "", }; @@ -126,16 +128,18 @@ const credentials: Credentials = { ### Bearer Token (static) ```typescript +import { Credentials } from 'skyflow-node'; + const credentials: Credentials = { token: "", }; ``` -For authenticating via generated bearer tokens including support for scoped tokens, context-aware access tokens, and more refer to the [Authentication & Authorization](#authentication--authorization) section. +For authenticating via generated bearer tokens including support for scoped tokens, context-aware access tokens, and more, refer to the [Authentication & Authorization](#authentication--authorization) section. ### Initialize the client -To get started, you must first initialize the skyflow client. While initializing the skyflow client, you can specify different types of credentials. +Initialize the Skyflow client first. You can specify different credential types during initialization. ```javascript import { Skyflow, SkyflowConfig, VaultConfig, Env, LogLevel } from 'skyflow-node'; @@ -162,15 +166,15 @@ const skyflowConfig: SkyflowConfig = { const skyflowClient: Skyflow = new Skyflow(skyflowConfig); ``` -For advanced initialization examples including examples using multiple vaults and different credential types, see [docs/advanced_initialization.md](docs/advanced_initialization.md). +See [docs/advanced_initialization.md](docs/advanced_initialization.md) for advanced initialization examples including multiple vaults and different credential types. ### Insert data into the vault, get tokens back -To insert data into your vault use the `insert` method. Make sure to set `insertOptions.setReturnTokens(true)` to ensure values are tokenized in the response. +Insert data into your vault using the `insert` method. Set `insertOptions.setReturnTokens(true)` to ensure values are tokenized in the response. -The `InsertRequest` class creates an insert request, which includes the values to be inserted as a list of records. +Create an insert request with the `InsertRequest` class, which includes the values to be inserted as a list of records. -Below is a simple example to get started. For advanced options, check out [Insert data into the vault](#insert-data-into-the-vault-1) section. +Below is a simple example to get started. See the [Insert and tokenize data](#insert-and-tokenize-data-insertrequest) section for advanced options. ```javascript import { InsertRequest, InsertOptions } from "skyflow-node"; @@ -193,7 +197,7 @@ console.log("Insert response:", insertResponse); ## Upgrade from v1 to v2 -For those upgrading from `skyflow-node` v1, we have a dedicated guide in [docs/migrate_to_v2](docs/migrate_to_v2.md). +Upgrade from `skyflow-node` v1 using the dedicated guide in [docs/migrate_to_v2.md](docs/migrate_to_v2.md). ## Vault @@ -201,7 +205,7 @@ The [Vault](https://docs.skyflow.com/docs/vaults) performs operations on the vau ### Insert and tokenize data: `.insert(request)` -Apart from using the `insert` method to insert data into your vault covered in [Quickstart](#quickstart), you can also pass options to `insert` method to enable additional functionality such as returning tokenized data, upserting records, or allowing bulk operations to continue despite errors. +Pass options to the `insert` method to enable additional functionality such as returning tokenized data, upserting records, or allowing bulk operations to continue despite errors. See [Quickstart](#quickstart) for a basic example. ```typescript import { InsertRequest, InsertResponse } from 'skyflow-node'; @@ -226,14 +230,14 @@ console.log('Insert response:', response); #### Insert example with `continueOnError` option -The `continueOnError` flag is a boolean that determines whether insert operation should proceed despite encountering partial errors. Set to `true` to allow the process to continue even if some errors occur. +Set the `continueOnError` flag to `true` to allow insert operations to proceed despite encountering partial errors. > [!TIP] > See the full example in the samples directory: [insert-continue-on-error.ts](samples/vault-api/insert-continue-on-error.ts) #### Upsert request -The upsert option turns an insert into an 'update-or-insert' operation. When enabling this option, the vault checks for an existing record with the same value in the specified column. If a match exists, the record is updated; otherwise, a new record is inserted. +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 // ... @@ -243,13 +247,16 @@ insertOptions.setUpsertColumn("cardholder_name"); // ... ``` +> [!TIP] +> See the full example in the samples directory: [insert-byot.ts](samples/vault-api/insert-byot.ts) + ### Detokenize: `.detokenize(request, options)` -To convert tokens back into the plaintext values (or masked values), use the `.detokenize()` method. Detokenization accepts tokens and returns values. +Convert tokens back into plaintext values (or masked values) using the `.detokenize()` method. Detokenization accepts tokens and returns values. -The `DetokenizeRequest` class requires a list of tokens and column groups as input. +Create a detokenization request with the `DetokenizeRequest` class, which requires a list of tokens and column groups as input. -Additionally, you can provide optional parameters, such as the redaction type and the option to continue on error. +Provide optional parameters such as the redaction type and the option to continue on error. #### Construct a detokenize request @@ -281,7 +288,10 @@ console.log("Detokenization response:", response); ### Get Record(s): `.get(request, options)` -To retrieve data using Skyflow IDs or unique column values, use the get method. The `GetRequest` class creates a get request, where you specify parameters such as the table name, redaction type, Skyflow IDs, column names, column values. If you specify Skyflow IDs, you can't use column names and column values, and the inverse is true—if you specify column names and column values, you can't use Skyflow IDs. And `GetOptions` class creates a get options object through which you specify whether to return tokens or not. +Retrieve data using Skyflow IDs or unique column values with the get method. Create a get request with the `GetRequest` class, specifying parameters such as the table name, redaction type, Skyflow IDs, column names, and column values. + +> [!NOTE] +> You can't use both Skyflow IDs and column name/value pairs in the same request. Use the `GetOptions` class to specify whether to return tokens. #### Construct a get request @@ -302,7 +312,7 @@ console.log("Get response:", response); #### Get by Skyflow IDs -Retrieve specific records using skyflow `ids`. Ideal for fetching exact records when IDs are known. +Retrieve specific records using Skyflow IDs. Use this method when you know the exact record IDs. ```typescript import { @@ -341,10 +351,10 @@ console.log("Data retrieval successful:", getResponse); #### Get tokens for records -Return tokens for records. Ideal for securely processing sensitive data while maintaining data privacy. +Return tokens for records to securely process sensitive data while maintaining data privacy. ```ts -getOptions.setReturnTokens(true); // Optional: Set to true to get tokens +getOptions.setReturnTokens(true); // Set to `true` to get tokens ``` > [!TIP] @@ -352,7 +362,7 @@ getOptions.setReturnTokens(true); // Optional: Set to true to get tokens #### Get by column name and column values -Retrieve records by unique column values. Ideal for querying data without knowing Skyflow IDs, using alternate unique identifiers. +Retrieve records by unique column values when you don't know the Skyflow IDs. Use this method to query data with alternate unique identifiers. ```ts const getRequest: GetColumnRequest = new GetColumnRequest( @@ -367,7 +377,7 @@ const getRequest: GetColumnRequest = new GetColumnRequest( #### Redaction Types -Redaction types determine how sensitive data is displayed when retrieved from the vault. +Use redaction types to control how sensitive data displays when retrieved from the vault. **Available Redaction Types** @@ -384,7 +394,9 @@ Redaction types determine how sensitive data is displayed when retrieved from th ### Update Records -To update data in your vault, use the `update` method. The `UpdateRequest` class is used to create an update request, where you specify parameters such as the table name, data (as a dictionary). The `UpdateOptions` class is used to configure update options to returnTokens, tokens, and tokenMode. If `returnTokens` is set to True, Skyflow returns tokens for the updated records. If `returnTokens` is set to False, Skyflow returns IDs for the updated 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). + +Configure update options using the `UpdateOptions` class to control returnTokens, tokens, and tokenMode. When `returnTokens` is `true`, Skyflow returns tokens for the updated records. When `false`, Skyflow returns IDs for the updated records. #### Construct an update request @@ -409,7 +421,7 @@ console.log('Update response:', response); ### Delete Records -To delete records using Skyflow IDs, use the `delete` method. The `DeleteRequest` class accepts a list of Skyflow IDs that you want to delete, as shown below: +Delete records using Skyflow IDs with the `delete` method. Create a delete request with the `DeleteRequest` class, which accepts a list of Skyflow IDs: ```typescript import { DeleteRequest, DeleteResponse } from "skyflow-node"; @@ -432,9 +444,9 @@ console.log("Delete response:", response); ### Query -To retrieve data with SQL queries, use the `query` method. `QueryRequest` is class that takes the `query` parameter as follows: +Retrieve data with SQL queries using the `query` method. Create a query request with the `QueryRequest` class, which takes the `query` parameter as follows: + -Refer to [Query your data](https://docs.skyflow.com/query-data/) and [Execute Query](https://docs.skyflow.com/record/#QueryService_ExecuteQuery) for guidelines and restrictions on supported SQL statements, operators, and keywords. ```typescript import { QueryRequest, QueryResponse } from "skyflow-node"; @@ -449,13 +461,14 @@ const response: QueryResponse = await skyflowClient console.log("Query response:", response); ``` - > [!TIP] > See the full example in the samples directory: [query-records.ts](samples/vault-api/query-records.ts) +Refer to [Query your data](https://docs.skyflow.com/query-data/) and [Execute Query](https://docs.skyflow.com/record/#QueryService_ExecuteQuery) for guidelines and restrictions on supported SQL statements, operators, and keywords. + ### Upload File -To upload files to a Skyflow vault, use the `uploadFile` method. The `FileUploadRequest` class accepts parameters such as the table name, column name and skyflow ID. And `FileUploadOptions` class accepts the file object as shown below: +Upload files to a Skyflow vault using the `uploadFile` method. Create a file upload request with the `FileUploadRequest` class, which accepts parameters such as the table name, column name, and Skyflow ID. Configure upload options with the `FileUploadOptions` class, which accepts the file object as shown below: ```typescript // Please use Node version 20 & above to run file upload @@ -497,11 +510,9 @@ console.log("File upload:", response); > [!TIP] > See the full example in the samples directory: [file-upload.ts](samples/vault-api/file-upload.ts) -### Get Tokens by Values: `.tokenize(request)` - -The `.tokenize()` method is used to retrieve tokens for values which already exist in the vault. Think of it as a "Get Tokens by Value" action. +### Retrieve Existing Tokens: `.tokenize(request)` -This method does not generate new tokens, only returns existing tokens from the vault. +Retrieve tokens for values that already exist in the vault using the `.tokenize()` method. This method returns existing tokens only and does not generate new tokens. #### Construct a `.tokenize()` request @@ -525,13 +536,13 @@ console.log("Tokenization Result:", response); ## Detect -Skyflow Detect enables you to deidentify and reidentify sensitive data in text and files, supporting advanced privacy-preserving workflows. +De-identify and reidentify sensitive data in text and files using Skyflow Detect, which supports advanced privacy-preserving workflows. ### De-identify Text: `.deidentifyText(request, options)` -To de-identify or _anonymize_ text, use the `deidentifyText` method. +De-identify or anonymize text using the `deidentifyText` method. -The `DeidentifyTextRequest` class creates a deidentify text request, which includes the text to be deidentified. Additionally, you can provide optional parameters using the `DeidentifyTextOptions` class. +Create a de-identify text request with the `DeidentifyTextRequest` class, which includes the text to be deidentified. Provide optional parameters using the `DeidentifyTextOptions` class. ```typescript import { @@ -551,7 +562,7 @@ const deidentifyTextRequest = new DeidentifyTextRequest( // Configure DeidentifyTextOptions const options = new DeidentifyTextOptions(); -options.setEntities([DetectEntities.ACCOUNT_NUMBER, DetectEntities.SSN]); // Entities to deidentify +options.setEntities([DetectEntities.ACCOUNT_NUMBER, DetectEntities.SSN]); // Entities to de-identify options.setAllowRegexList([""]); // Allowlist regex patterns options.setRestrictRegexList([""]); // Restrict regex patterns @@ -572,7 +583,7 @@ const response = await skyflowClient .detect(primaryVaultConfig.vaultId) .deidentifyText(deidentifyTextRequest, options); -console.log("Deidentify Text Response:", response); +console.log("De-identify Text Response:", response); ``` > [!TIP] @@ -580,7 +591,7 @@ console.log("Deidentify Text Response:", response); ### Re-identify Text: `.reidentifyText(request, options)` -To reidentify text, use the `reidentifyText` method. The `ReidentifyTextRequest` class creates a reidentify text request, which includes the redacted or de-identified text to be re-identified. Additionally, you can provide optional parameters using the `ReidentifyTextOptions` class to control how specific entities are returned (as redacted, masked, or plain text). +Re-identify text using the `reidentifyText` method. Create a reidentify text request with the `ReidentifyTextRequest` class, which includes the redacted or de-identified text to be re-identified. Provide optional parameters using the `ReidentifyTextOptions` class to control how specific entities are returned (as redacted, masked, or plain text). ```typescript import { @@ -611,11 +622,12 @@ console.log("Reidentify Text Response:", response); > [!TIP] > See the full example in the samples directory: [reidentify-text.ts](samples/detect-api/reidentify-text.ts) -### Deidentify File: `.deidentifyFile(fileReq, options)` +### De-identify File: `.deidentifyFile(fileReq, options)` -To deidentify files, use the `deidentifyFile` method. The `DeidentifyFileRequest` class creates a deidentify file request, which includes the file to be deidentified (such as images, PDFs, audio, documents, spreadsheets, or presentations). Additionally, you can provide optional parameters using the `DeidentifyFileOptions` class to control how entities are detected and deidentified, as well as how the output is generated for different file types. +De-identify files using the `deidentifyFile` method. Create a de-identify file request with the `DeidentifyFileRequest` class, which includes the file to be deidentified (such as images, PDFs, audio, documents, spreadsheets, or presentations). Provide optional parameters using the `DeidentifyFileOptions` class to control how entities are detected and deidentified, as well as how the output is generated for different file types. -**Note:** File de-identification requires Node.js v20.x or above. +> [!NOTE] +> File de-identification requires Node.js v20.x or above. ```typescript import { @@ -665,7 +677,7 @@ const response: DeidentifyFileResponse = await skyflowClient .detect(primaryVaultConfig.vaultId) .deidentifyFile(fileReq, options); -console.log('Deidentify File Response:', response); +console.log('De-identify File Response:', response); ``` **Supported file types:** @@ -680,7 +692,7 @@ console.log('Deidentify File Response:', response); **Notes:** -- Transformations cannot be applied to Documents, Images, or PDFs file formats. +- 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. @@ -689,9 +701,7 @@ console.log('Deidentify File Response:', response); ### Get Run: `.getDetectRun(request)` -To retrieve the results of a previously started file de-identification operation - or 'run' - use the `getDetectRun(...)` method. -The `GetDetectRunRequest` class is initialized with the `runId` returned from a prior `.deidentifyFile(fileReq, options)` call. -This method allows you to fetch the final results of the file de-identification operation once they are available. +Retrieve the results of a previously started file de-identification operation (or 'run') using the `getDetectRun(...)` method. Initialize the `GetDetectRunRequest` class with the `runId` returned from a prior `.deidentifyFile(fileReq, options)` call. Fetch the final results of the file de-identification operation once they are available. ```typescript import { @@ -720,14 +730,14 @@ console.log('Get Detect Run Response:', response); ## Connections -Skyflow Connections is a gateway service that uses tokenization to securely send and receive data between your systems and first- or third-party services. The [connections](https://github.com/skyflowapi/skyflow-node/tree/v2/src/vault/controller/connections) module invokes both inbound and/or outbound connections. +Securely send and receive data between your systems and first- or third-party services using Skyflow Connections, a gateway service that uses tokenization. The [connections](https://github.com/skyflowapi/skyflow-node/tree/v2/src/vault/controller/connections) module invokes both inbound and outbound connections. - **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. ### Invoke a connection -To invoke a connection, use the `invoke` method of the Skyflow client. +Invoke a connection using the `invoke` method of the Skyflow client. #### Construct an invoke connection request @@ -774,7 +784,7 @@ The method of `RequestMethod.POST` must be one of: The SDK accepts one of several types of credentials object. 1. **API keys** - A unique identifier used to authenticate and authorize requests to an API. To create an API key you must first create a 'Service Account' in Skyflow and choose the 'API key' option during creation. + A unique identifier used to authenticate and authorize requests to an API. Use for long-term service authentication. To create an API key, first create a 'Service Account' in Skyflow and choose the 'API key' option during creation. ```ts const credentials: Credentials = { @@ -783,7 +793,7 @@ The SDK accepts one of several types of credentials object. ``` 2. **Bearer tokens** - A temporary access token used to authenticate API requests. As a developer with the right access you can generate a temporary personal bearer token in Skyflow in the user menu. + A temporary access token used to authenticate API requests. Use for optimal security. As a developer with the right access, you can generate a temporary personal bearer token in Skyflow in the user menu. ```ts const credentials: Credentials = { @@ -792,8 +802,7 @@ The SDK accepts one of several types of credentials object. ``` 3. **Service account credentials file path** - The file path pointing to a JSON file containing credentials for a service account, used - for secure API access. + The file path pointing to a JSON file containing credentials for a service account. Use when credentials are managed externally or stored in secure file systems. ```ts const credentials: Credentials = { @@ -802,7 +811,7 @@ The SDK accepts one of several types of credentials object. ``` 4. **Service account credentials string** - JSON-formatted string containing service account credentials, often used as an alternative to a file for programmatic authentication. + JSON-formatted string containing service account credentials. Use when integrating with secret management systems or when credentials are passed programmatically. ```ts const credentials: Credentials = { @@ -811,17 +820,18 @@ The SDK accepts one of several types of credentials object. ``` 5. **Environment variables** - If no credentials are explicitly provided the SDK automatically looks for the SKYFLOW_CREDENTIALS environment variable. This variable must return an object like one of the examples above. + If no credentials are explicitly provided, the SDK automatically looks for the SKYFLOW_CREDENTIALS environment variable. Use to avoid hardcoding credentials in source code. This variable must return an object like one of the examples above. -**Note: Only one type of credential can be used at a time. If multiple credentials are provided, the last one added will take precedence.** +> [!NOTE] +> Only one type of credential can be used at a time. If multiple credentials are provided, the last one added will take precedence. ### Generate bearer tokens for authentication & authorization -This section covers methods for generating and managing bearer tokens to authenticate API calls, including options for scoping to certain roles, passing context, and signing data tokens. +Generate and manage bearer tokens to authenticate API calls. This section covers options for scoping to certain roles, passing context, and signing data tokens. #### Generate a bearer token -The [Service Account](https://github.com/skyflowapi/skyflow-node/tree/v2/src/service-account) Node package generates service account tokens using a service account credentials file, which is provided when a service account is created. The tokens generated by this module are valid for 60 minutes and can be used to make API calls to the [Data](https://docs.skyflow.com/record/) and [Management](https://docs.skyflow.com/management/) APIs, depending on the permissions assigned to the service account. +Generate service account tokens using the [Service Account](https://github.com/skyflowapi/skyflow-node/tree/v2/src/service-account) Node package with a service account credentials file provided when a service account is created. Tokens generated by this module are valid for 60 minutes and can be used to make API calls to the [Data](https://docs.skyflow.com/record/) and [Management](https://docs.skyflow.com/management/) APIs, depending on the permissions assigned to the service account. ##### `generateBearerToken(filepath)` @@ -850,7 +860,7 @@ Alternatively, you can also send the entire credentials as string by using `gene #### Generate bearer tokens scoped to certain roles -A service account with multiple roles can generate bearer tokens with access limited to a specific role by specifying the appropriate roleID. This can be used to limit access to specific roles for services with multiple responsibilities, such as segregating access for billing and analytics. The 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 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. ```ts const options = { @@ -862,11 +872,11 @@ const options = { > See the full example in the samples directory: [scoped-token-generation-example.ts](samples/service-account/scoped-token-generation-example.ts) > See [docs.skyflow.com](https://docs.skyflow.com) for more details on authentication, access control, and governance for Skyflow. -#### Generate a bearer tokens with `ctx` for context-aware authorization +#### Generate bearer tokens with `ctx` for context-aware authorization -**Context-aware authorization** embeds context values into a bearer token during its generation and so you can reference those values in your policies. This enables more flexible access controls, such as helping you track end-user identity when making API calls using service accounts, and facilitates using signed data tokens during detokenization. +Embed context values into a bearer token during generation so you can reference those values in your policies. This enables more flexible access controls, such as tracking end-user identity when making API calls using service accounts, and facilitates using signed data tokens during detokenization. -A service account with the context_id identifier generates bearer tokens containing context information, represented as a JWT claim in a Skyflow-generated bearer token. Tokens generated from such service accounts include a context_identifier claim, are valid for 60 minutes, and can be used to make API calls to the Data and Management APIs, depending on the service account's permissions. +Generate bearer tokens containing context information using a service account with the context_id identifier. Context information is represented as a JWT claim in a Skyflow-generated bearer token. Tokens generated from such service accounts include a context_identifier claim, are valid for 60 minutes, and can be used to make API calls to the Data and Management APIs, depending on the service account's permissions. > [!TIP] > See the full example in the samples directory: [token-generation-with-context-example.ts](samples/service-account/token-generation-with-context-example.ts) @@ -874,7 +884,7 @@ A service account with the context_id identifier generates bearer tokens contain #### Generate signed data tokens: `generateSignedDataTokens(filepath, options)` -Skyflow generates data tokens when sensitive data is inserted into the vault. These data tokens can be digitally signed with a service account's private key, adding an extra layer of protection. Signed tokens can only be detokenized 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. +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. > [!TIP] > See the full example in the samples directory: [signed-token-generation-example.ts](samples/service-account/signed-token-generation-example.ts) @@ -882,7 +892,7 @@ Skyflow generates data tokens when sensitive data is inserted into the vault. Th ## Logging -The SDK provides useful logging. By default the logging level of the SDK is set to `LogLevel.ERROR`. This can be changed by setting the `logLevel` in Skyflow Config while creating the Skyflow Client as shown below: +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: Currently, the following five log levels are supported: @@ -897,7 +907,8 @@ Currently, the following five log levels are supported: - `OFF`: `LogLevel.OFF` can be used to turn off all logging from the Skyflow Python SDK. -**Note:** The ranking of logging levels is as follows: `DEBUG` < `INFO` < `WARN` < `ERROR` < `OFF`. +> [!NOTE] +> The ranking of logging levels is as follows: `DEBUG` < `INFO` < `WARN` < `ERROR` < `OFF`. ### Example `skyflowConfig.logLevel: LogLevel.INFO` @@ -915,7 +926,7 @@ const skyflowClient: Skyflow = new Skyflow(skyflowConfig); ### Catching `SkyflowError` instances -As a best practice always wrap your calls to the Skyflow SDK in try / catch blocks. The SDK provides the `SkyflowError` type which can be used to identify errors coming from Skyflow versus general request / response errors. +Wrap your calls to the Skyflow SDK in try/catch blocks as a best practice. Use the `SkyflowError` type to identify errors coming from Skyflow versus general request/response errors. ```ts try { @@ -936,7 +947,7 @@ try { ### Bearer token expiration edge cases -When you use bearer tokens for authentication and API requests in SDKs, there's the potential for a token to expire after the token is verified as valid but before the actual API call is made, causing the request to fail unexpectedly due to the token's expiration. An error from this edge case would look something like this: +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: ```txt message: Authentication failed. Bearer token is expired. Use a valid bearer token. See https://docs.skyflow.com/api-authentication/ @@ -952,4 +963,6 @@ If you encounter this kind of error, retry the request. During the retry the SDK ### Reporting a Vulnerability -If you discover a potential security issue in this project, please reach out to us at [mailto:security@skyflow.com](security@skyflow.com). Please do not create public GitHub issues or Pull Requests, as malicious actors could potentially view them. +If you discover a potential security issue in this project, reach out to us at [security@skyflow.com](mailto:security@skyflow.com). + +Don't create public GitHub issues or Pull Requests, as malicious actors could potentially view them. diff --git a/SECURITY.md b/SECURITY.md index 676e66b0..9f012c14 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,6 +2,6 @@ ## Reporting a Vulnerability -If you discover a potential security issue in this project, please reach out to us at [mailto:security@skyflow.com](security@skyflow.com). +If you discover a potential security issue in this project, reach out to us at [security@skyflow.com](mailto:security@skyflow.com). -Please do not create public GitHub issues or Pull Requests, as malicious actors could potentially view them. +Don't create public GitHub issues or Pull Requests, as malicious actors could potentially view them. diff --git a/docs/advanced_initialization.md b/docs/advanced_initialization.md index ecfad035..de2ab648 100644 --- a/docs/advanced_initialization.md +++ b/docs/advanced_initialization.md @@ -2,6 +2,8 @@ This guide demonstrates advanced initialization patterns for the Skyflow Node SDK, including multiple vault configurations and different credential types. +Use multiple vault configurations when your application needs to access data across different Skyflow vaults, such as separating production and staging data, or managing data across different geographic regions. + ## Multiple Vault Configuration Example ```typescript diff --git a/docs/auth_credentials.md b/docs/auth_credentials.md index 698bfac9..a7dd7856 100644 --- a/docs/auth_credentials.md +++ b/docs/auth_credentials.md @@ -1,6 +1,14 @@ # Authentication credentials options -Note: Only one type of credential can be used at a time. If multiple credentials are provided, the last one added will take precedence. +> [!NOTE] +> Only one type of credential can be used at a time. If multiple credentials are provided, the last one added will take precedence. + +**Choosing the right credential type:** +- Use **API keys** for long-term service authentication +- Use **Bearer tokens** for optimal security +- Use **Service account file paths** when credentials are managed externally +- Use **Credential strings** when integrating with secret management systems +- Use **Environment variables** to avoid hardcoding credentials in source code (recommended) 1. **API keys** A unique identifier used to authenticate and authorize requests to an API. diff --git a/docs/migrate_to_v2.md b/docs/migrate_to_v2.md index 5371874f..8b524b11 100644 --- a/docs/migrate_to_v2.md +++ b/docs/migrate_to_v2.md @@ -16,7 +16,7 @@ These options allow you to choose the authentication method that best suits your ### v1 Authentication: Pass the auth function below as a parameter to the getBearerToken key -```javascript +```typescript // sample function to retrieve a bearer token from an environment variable // customize this according to your environment and security posture const auth = function () { @@ -28,10 +28,12 @@ const auth = function () { #### v2 Authentication: Credentials object -```javascript -{ +```typescript +import { Credentials } from 'skyflow-node'; + +const credentials: Credentials = { apiKey: "" -} +}; ``` // Option 2: Environment Variables (Recommended) @@ -39,22 +41,28 @@ const auth = function () { // Option 3: Credentials File -```js -const credentials = { path: "" }; // Replace with the path to credentials file +```typescript +import { Credentials } from 'skyflow-node'; + +const credentials: Credentials = { path: "" }; ``` // Option 4: Stringified JSON -```js -const credentials = { +```typescript +import { Credentials } from 'skyflow-node'; + +const credentials: Credentials = { credentialsString: JSON.stringify(process.env.SKYFLOW_CREDENTIALS), }; ``` // Option 5: Bearer Token -```js -const credentials = { token: "" }; +```typescript +import { Credentials } from 'skyflow-node'; + +const credentials: Credentials = { token: "" }; ``` ## Initializing the client @@ -78,7 +86,6 @@ const vault = Skyflow.init({ // Id of the vault that the client should connect to. vaultID: "string", // URL of the vault that the client should connect to. - vaultURL: "string", // Helper function generates a Skyflow bearer token. getBearerToken: auth, @@ -87,8 +94,10 @@ const vault = Skyflow.init({ #### V2 (New) -```javascript -// Step 1: Configure Bearer Token Credentials +```typescript +import { Credentials, VaultConfig, SkyflowConfig, Env, LogLevel, Skyflow } from 'skyflow-node'; + +// Step 1: Configure API Key Credentials const credentials: Credentials = { apiKey: '' }; // Step 2: Configure Vault @@ -119,13 +128,16 @@ const skyflowClient: Skyflow = new Skyflow(skyflowConfig); --- -### Request & Response Structure +### Request and Response Structure -In V2, with the introduction of TypeScript support, you can now pass an **InsertRequest** of type **InsertRequest**. This request need +In v2, with the introduction of TypeScript support, you can now pass an **InsertRequest** of type **InsertRequest**. This request requires: - **`tableName`**: The name of the table. - **`insertData`**: An array of objects containing the data to be inserted - The response will be of type InsertResponse, which contains insertedFields and errors. + +The response will be of type InsertResponse, which contains insertedFields and errors. + +**Note:** Similar patterns apply to other operations like Get, Update, Delete. See the [README](../README.md) for complete examples. #### V1 (Old) - Request Building @@ -217,7 +229,9 @@ const options = { #### V2 (New) -```javascript +```typescript +import { InsertOptions } from 'skyflow-node'; + const insertOptions: InsertOptions = new InsertOptions(); insertOptions.setReturnTokens(true); // Optional: Get tokens for inserted data insertOptions.setContinueOnError(true); // Optional: Continue on partial errors @@ -246,7 +260,7 @@ The error response now includes: #### V2 (New) - Error Structure -```javascript +```typescript { http_status?: string | number | null, grpc_code?: string | number | null, diff --git a/samples/README.md b/samples/README.md index 4c9c6046..43b8f3cf 100644 --- a/samples/README.md +++ b/samples/README.md @@ -1,6 +1,6 @@ # Node.js SDK samples -Test the SDK by adding `VAULT-ID`, `VAULT-URL`, and `SERVICE-ACCOUNT` details in the required places for each sample. +Explore working examples that demonstrate common SDK operations. Start with basic vault operations like `insert-records.ts`, then explore other samples for specific use cases. ## Prerequisites @@ -9,7 +9,7 @@ Test the SDK by adding `VAULT-ID`, `VAULT-URL`, and `SERVICE-ACCOUNT` details in ## Prepare -- Install the Node SDK: +Install the Node SDK: ```bash npm install skyflow-node @@ -17,104 +17,66 @@ npm install skyflow-node ### Create a vault -1. In a browser, navigate to Skyflow Studio. -2. Create a vault by clicking **Create Vault** > **Start With a Template** > **Quickstart vault**. -3. Once the vault is created, click the gear icon and select **Edit Vault Details**. -4. Note your **Vault URL** and **Vault ID** values, then click **Cancel**. You'll need these later. +1. Navigate to Skyflow Studio in your browser. +2. Click **Create Vault** > **Start With a Template** > **Quickstart vault**. +3. When the vault is ready, click the gear icon and select **Edit Vault Details**. +4. Copy your **Vault ID** and **Cluster ID** from the URL (format: `https://{clusterId}.vault.skyflowapis.com`), then click **Cancel**. ### Create a service account -1. In the side navigation click, **IAM** > **Service Accounts** > **New Service Account**. -2. For **Name**, enter "SDK Samples". For **Roles**, choose **Vault Editor**. -3. Click **Create**. Your browser downloads a **credentials.json** file. Keep this file secure. You'll need it for each of the samples. +1. Click **IAM** > **Service Accounts** > **New Service Account** in the side navigation. +2. Enter "SDK Samples" for **Name** and choose **Vault Editor** for **Roles**. +3. Click **Create**. Your browser downloads a **credentials.json** file. Store this file securely. ## The samples -### Detokenize +Sample files are organized by API type: +- `vault-api/` - Vault operations (insert, get, update, delete, tokenize, detokenize) +- `detect-api/` - Detect operations (deidentify, reidentify) +- `service-account/` - Token generation examples -Detokenize a data token from the vault. Make sure the specified token is for data that exists in the vault. If you need a valid token, use [Insert.ts](./vault-api/Insert.ts) to insert the data, then use this data's token for detokenization. +### Running a sample -1. Replace `` with **VAULT ID** -2. Replace `` with **VAULT URL**. -3. Replace `` with **COLUMN NAME**. -4. Replace `` with **Data Token 1**. -5. Replace `` with **Data Token 2**. -6. Replace `` with **Data Token 3**. -7. Replace `` with **Data Token 4**. -8. Replace `` with relative path of **SERVICE ACCOUNT CREDENTIAL FILE**. -9. Run the sample +1. Open the sample file you want to run (for example, `vault-api/insert-records.ts`) +2. Update placeholder values: + - Replace `` with your Vault ID from Skyflow Studio + - Replace `` with your Cluster ID from the vault URL + - Replace credential placeholders with your actual credentials +3. Run the sample: ```bash -ts-node Detokenize.ts +cd samples +npm install +ts-node vault-api/insert-records.ts ``` -### GetById - -Get data using skyflow id. - -1. Replace `` with **VAULT ID** -2. Replace `` with **VAULT URL**. -3. Replace `` with **Skyflow Id 1**. -4. Replace `` with **Skyflow Id 2**. -5. Replace `` with **Skyflow Id 3**. -6. Replace `` with relative path of **SERVICE ACCOUNT CREDENTIAL FILE**. -7. Replace `` with **credit_cards**. -8. Run the sample - -```bash -ts-node GetById.ts -``` - -### Insert - -Insert data in the vault. - -1. Replace `` with **VAULT ID**. -2. Replace `` with **VAULT URL**. -3. Replace `` with relative path of **SERVICE ACCOUNT CREDENTIAL FILE**. -4. Replace `` with **credit_cards**. -5. Replace `` with **column name**. -6. Replace `` with **valid value corresponding to column name**. -7. Run the sample - -```bash -ts-node Insert.ts -``` - -### InvokeConnection - -Skyflow Connections is a gateway service that uses Skyflow's underlying tokenization capabilities to securely connect to first-party and third-party services. This way, your infrastructure is never directly exposed to sensitive data, and you offload security and compliance requirements to Skyflow. - -1. Replace `` with **VAULT ID**. -2. Replace `` with **VAULT URL**. -3. Replace `` with relative path of **SERVICE ACCOUNT CREDENTIAL FILE**. -4. Replace `` with **Connection url**. -5. Give **Authorization** value as the tokens. -6. Replace value of **requestBody** with your's request body content. -7. Run the sample - -```bash -ts-node InvokeConnection.ts -``` - -### Service account token generation - -Generates a service account Bearer token using the file path of credentials.json. - -1. Replace `` with relative path of **SERVICE ACCOUNT CREDENTIAL FILE**. -2. Run the sample - -```bash -ts-node TokenGenerationExample.ts -``` - -### Generate a Bearer Token From `credentials.json` - -Generates a service account bearer token using the JSON content of a `credentials.json` file. - -1. Replace **credentials\*** with json data of downloaded credentials file while creation Service account. -2. Run the sample - -```bash -ts-node TokenGenerationUsingCredContent.ts -``` +### Sample files overview + +**Vault API samples** (`vault-api/`): +- `insert-records.ts` - Insert data and get tokens +- `insert-continue-on-error.ts` - Bulk insert with error handling +- `insert-byot.ts` - Upsert operations +- `get-records.ts` - Retrieve records by Skyflow IDs +- `get-column-values.ts` - Query by column values +- `detokenzie-records.ts` - Convert tokens to values +- `tokenize-records.ts` - Get tokens for existing values +- `update-record.ts` - Update existing records +- `delete-records.ts` - Delete records by ID +- `query-records.ts` - SQL query operations +- `file-upload.ts` - Upload files to vault +- `invoke-connection.ts` - Call external integrations + +**Detect API samples** (`detect-api/`): +- `deidentify-text.ts` - Anonymize text data +- `deidentify-file.ts` - Anonymize file data +- `reidentify-text.ts` - Restore original values +- `get-detect-run.ts` - Check operation status + +**Service Account samples** (`service-account/`): +- `token-generation-example.ts` - Generate bearer tokens +- `scoped-token-generation-example.ts` - Role-scoped tokens +- `token-generation-with-context-example.ts` - Context-aware tokens +- `signed-token-generation-example.ts` - Signed data tokens +- `bearer-token-expiry-example.ts` - Handle token expiration + +For detailed API documentation, see the main [README](../README.md). From 58c45cd9b06fbbd1cceac701a8972b9ff656f1bb Mon Sep 17 00:00:00 2001 From: Manny Silva <102989456+manny-silva@users.noreply.github.com> Date: Fri, 14 Nov 2025 11:16:12 -0800 Subject: [PATCH 11/15] Responded to feedback --- docs/advanced_initialization.md | 2 +- docs/auth_credentials.md | 7 --- samples/README.md | 82 ++++++++++++++++++--------------- 3 files changed, 47 insertions(+), 44 deletions(-) diff --git a/docs/advanced_initialization.md b/docs/advanced_initialization.md index de2ab648..98bfae63 100644 --- a/docs/advanced_initialization.md +++ b/docs/advanced_initialization.md @@ -2,7 +2,7 @@ This guide demonstrates advanced initialization patterns for the Skyflow Node SDK, including multiple vault configurations and different credential types. -Use multiple vault configurations when your application needs to access data across different Skyflow vaults, such as separating production and staging data, or managing data across different geographic regions. +Use multiple vault configurations when your application needs to access data across different Skyflow vaults, such as managing data across different geographic regions. ## Multiple Vault Configuration Example diff --git a/docs/auth_credentials.md b/docs/auth_credentials.md index a7dd7856..b87c1ebd 100644 --- a/docs/auth_credentials.md +++ b/docs/auth_credentials.md @@ -3,13 +3,6 @@ > [!NOTE] > Only one type of credential can be used at a time. If multiple credentials are provided, the last one added will take precedence. -**Choosing the right credential type:** -- Use **API keys** for long-term service authentication -- Use **Bearer tokens** for optimal security -- Use **Service account file paths** when credentials are managed externally -- Use **Credential strings** when integrating with secret management systems -- Use **Environment variables** to avoid hardcoding credentials in source code (recommended) - 1. **API keys** A unique identifier used to authenticate and authorize requests to an API. diff --git a/samples/README.md b/samples/README.md index 43b8f3cf..80cc0efa 100644 --- a/samples/README.md +++ b/samples/README.md @@ -20,11 +20,11 @@ npm install skyflow-node 1. Navigate to Skyflow Studio in your browser. 2. Click **Create Vault** > **Start With a Template** > **Quickstart vault**. 3. When the vault is ready, click the gear icon and select **Edit Vault Details**. -4. Copy your **Vault ID** and **Cluster ID** from the URL (format: `https://{clusterId}.vault.skyflowapis.com`), then click **Cancel**. +4. Copy your **Vault URL** and **Vault ID**, then click **Cancel**. ### Create a service account -1. Click **IAM** > **Service Accounts** > **New Service Account** in the side navigation. +1. In the side navigation, click **Access** > **Service Accounts** > **New Service Account**. 2. Enter "SDK Samples" for **Name** and choose **Vault Editor** for **Roles**. 3. Click **Create**. Your browser downloads a **credentials.json** file. Store this file securely. @@ -39,44 +39,54 @@ Sample files are organized by API type: 1. Open the sample file you want to run (for example, `vault-api/insert-records.ts`) 2. Update placeholder values: - - Replace `` with your Vault ID from Skyflow Studio - - Replace `` with your Cluster ID from the vault URL - - Replace credential placeholders with your actual credentials + + | Placeholder | Replace With | + |-------------|--------------| + | `` | Your Vault ID from Skyflow Studio | + | `` | Your Cluster ID from the vault URL | + | `` | Relative path to your actual credentials file | + | `` | The name of a table in your vault (for example, `users`) | + | `` | The name of a column in your table (for example, `name`) | + | ``, ``, etc. | Actual record IDs from your vault | + | `` | Actual values to insert into your vault | + | ``, ``, etc. | Actual tokens from your vault | + | `` | Your connection URL | + 3. Run the sample: -```bash -cd samples -npm install -ts-node vault-api/insert-records.ts -``` + ```bash + cd samples + npm install + ts-node vault-api/insert-records.ts + ``` ### Sample files overview -**Vault API samples** (`vault-api/`): -- `insert-records.ts` - Insert data and get tokens -- `insert-continue-on-error.ts` - Bulk insert with error handling -- `insert-byot.ts` - Upsert operations -- `get-records.ts` - Retrieve records by Skyflow IDs -- `get-column-values.ts` - Query by column values -- `detokenzie-records.ts` - Convert tokens to values -- `tokenize-records.ts` - Get tokens for existing values -- `update-record.ts` - Update existing records -- `delete-records.ts` - Delete records by ID -- `query-records.ts` - SQL query operations -- `file-upload.ts` - Upload files to vault -- `invoke-connection.ts` - Call external integrations - -**Detect API samples** (`detect-api/`): -- `deidentify-text.ts` - Anonymize text data -- `deidentify-file.ts` - Anonymize file data -- `reidentify-text.ts` - Restore original values -- `get-detect-run.ts` - Check operation status - -**Service Account samples** (`service-account/`): -- `token-generation-example.ts` - Generate bearer tokens -- `scoped-token-generation-example.ts` - Role-scoped tokens -- `token-generation-with-context-example.ts` - Context-aware tokens -- `signed-token-generation-example.ts` - Signed data tokens -- `bearer-token-expiry-example.ts` - Handle token expiration +**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 +- [`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 +- [`tokenize-records.ts`](vault-api/tokenize-records.ts) - Get tokens for existing values +- [`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 +- [`invoke-connection.ts`](vault-api/invoke-connection.ts) - Call external integrations + +**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 + +**Service Account samples** ([`service-account/`](service-account/)): +- [`token-generation-example.ts`](service-account/token-generation-example.ts) - Generate bearer tokens +- [`scoped-token-generation-example.ts`](service-account/scoped-token-generation-example.ts) - Role-scoped tokens +- [`token-generation-with-context-example.ts`](service-account/token-generation-with-context-example.ts) - Context-aware tokens +- [`signed-token-generation-example.ts`](service-account/signed-token-generation-example.ts) - Signed data tokens +- [`bearer-token-expiry-example.ts`](service-account/bearer-token-expiry-example.ts) - Handle token expiration For detailed API documentation, see the main [README](../README.md). From e197a1d7c92d3765db27f60f8759f02df8a50fc6 Mon Sep 17 00:00:00 2001 From: Manny Silva <102989456+manny-silva@users.noreply.github.com> Date: Fri, 14 Nov 2025 11:21:51 -0800 Subject: [PATCH 12/15] Remove duplicate imports --- docs/migrate_to_v2.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/docs/migrate_to_v2.md b/docs/migrate_to_v2.md index 8b524b11..51124d63 100644 --- a/docs/migrate_to_v2.md +++ b/docs/migrate_to_v2.md @@ -42,16 +42,12 @@ const credentials: Credentials = { // Option 3: Credentials File ```typescript -import { Credentials } from 'skyflow-node'; - const credentials: Credentials = { path: "" }; ``` // Option 4: Stringified JSON ```typescript -import { Credentials } from 'skyflow-node'; - const credentials: Credentials = { credentialsString: JSON.stringify(process.env.SKYFLOW_CREDENTIALS), }; @@ -60,8 +56,6 @@ const credentials: Credentials = { // Option 5: Bearer Token ```typescript -import { Credentials } from 'skyflow-node'; - const credentials: Credentials = { token: "" }; ``` From 4179177aaa25c1bb0de54683367b4c36197486e3 Mon Sep 17 00:00:00 2001 From: Manny Silva <102989456+manny-silva@users.noreply.github.com> Date: Fri, 14 Nov 2025 11:23:29 -0800 Subject: [PATCH 13/15] Responded to updates --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index a78d6fc6..a1bc7449 100644 --- a/README.md +++ b/README.md @@ -247,9 +247,6 @@ insertOptions.setUpsertColumn("cardholder_name"); // ... ``` -> [!TIP] -> See the full example in the samples directory: [insert-byot.ts](samples/vault-api/insert-byot.ts) - ### Detokenize: `.detokenize(request, options)` Convert tokens back into plaintext values (or masked values) using the `.detokenize()` method. Detokenization accepts tokens and returns values. From fe3687845c4fa6e6ba5372a3492e6ee1ac7fb673 Mon Sep 17 00:00:00 2001 From: Manny Silva <102989456+manny-silva@users.noreply.github.com> Date: Fri, 14 Nov 2025 11:25:41 -0800 Subject: [PATCH 14/15] Removed auth mention --- AGENTS.md | 1 - 1 file changed, 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index 3f07aa25..0b0128d6 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -56,7 +56,6 @@ The `Skyflow` class (in `src/vault/skyflow/index.ts`) manages multiple vaults an const skyflowConfig: SkyflowConfig = { vaultConfigs: [vaultConfig1, vaultConfig2], connectionConfigs: [connectionConfig], - skyflowCredentials: credentials, // Optional common credentials logLevel: LogLevel.ERROR // Default: LogLevel.ERROR }; From 02fded7c7af76f1de823a0c5ba7ca8d181493c68 Mon Sep 17 00:00:00 2001 From: Manny Silva <102989456+manny-silva@users.noreply.github.com> Date: Fri, 14 Nov 2025 11:28:14 -0800 Subject: [PATCH 15/15] Add CLAUDE.md with reference to AGENTS.md --- .claude/CLAUDE.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 .claude/CLAUDE.md diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md new file mode 100644 index 00000000..ebac26f3 --- /dev/null +++ b/.claude/CLAUDE.md @@ -0,0 +1 @@ +See @../AGENTS.md for documentation on how to configure and use Claude agents in this workspace. \ No newline at end of file