diff --git a/src/pages/overview/document-generation-api/gettingstarted.md b/src/pages/overview/document-generation-api/gettingstarted.md index 0a57a33fa..b103fdac9 100644 --- a/src/pages/overview/document-generation-api/gettingstarted.md +++ b/src/pages/overview/document-generation-api/gettingstarted.md @@ -290,50 +290,81 @@ Please refer the [API usage guide](../pdf-services-api/howtos/api-usage.md) to u // Run the sample: // node src/documentmerge/merge-document-to-pdf.js - const PDFServicesSdk = require('@adobe/pdfservices-node-sdk'); - - try { - // Initial setup, create credentials instance. - const credentials = PDFServicesSdk.Credentials - .servicePrincipalCredentialsBuilder() - .withClientId("PDF_SERVICES_CLIENT_ID") - .withClientSecret("PDF_SERVICES_CLIENT_SECRET") - .build(); - - // Setup input data for the document merge process. - const jsonString = "{\"customerName\": \"Kane Miller\", \"customerVisits\": 100}", - jsonDataForMerge = JSON.parse(jsonString); - - // Create an ExecutionContext using credentials. - const executionContext = PDFServicesSdk.ExecutionContext.create(credentials); - - // Create a new DocumentMerge options instance. - const documentMerge = PDFServicesSdk.DocumentMerge, - documentMergeOptions = documentMerge.options, - options = new documentMergeOptions.DocumentMergeOptions(jsonDataForMerge, documentMergeOptions.OutputFormat.PDF); - - // Create a new operation instance using the options instance. - const documentMergeOperation = documentMerge.Operation.createNew(options); - - // Set operation input document template from a source file. - const input = PDFServicesSdk.FileRef.createFromLocalFile('resources/documentMergeTemplate.docx'); - documentMergeOperation.setInput(input); - - // Execute the operation and Save the result to the specified location. - documentMergeOperation.execute(executionContext) - .then(result => result.saveAsFile('output/documentMergeOutput.pdf')) - .catch(err => { - if(err instanceof PDFServicesSdk.Error.ServiceApiError - || err instanceof PDFServicesSdk.Error.ServiceUsageError) { - console.log('Exception encountered while executing operation', err); - } else { - console.log('Exception encountered while executing operation', err); - } - }); - } - catch (err) { - console.log('Exception encountered while executing operation', err); - } +const { + ServicePrincipalCredentials, + PDFServices, + MimeType, + DocumentMergeParams, + OutputFormat, + DocumentMergeJob, + DocumentMergeResult, + SDKError, + ServiceUsageError, + ServiceApiError +} = require("@adobe/pdfservices-node-sdk"); +const fs = require("fs"); + +(async () => { + let readStream; + try { + // Initial setup, create credentials instance + const credentials = new ServicePrincipalCredentials({ + clientId: process.env.PDF_SERVICES_CLIENT_ID, + clientSecret: process.env.PDF_SERVICES_CLIENT_SECRET + }); + + // Creates a PDF Services instance + const pdfServices = new PDFServices({credentials}); + + // Setup input data for the document merge process + const jsonDataForMerge = { + customerName: "Kane Miller", + customerVisits: 100 + } + + // Creates an asset(s) from source file(s) and upload + readStream = fs.createReadStream("./documentMergeTemplate.docx"); + const inputAsset = await pdfServices.upload({ + readStream, + mimeType: MimeType.DOCX + }); + + // Create parameters for the job + const params = new DocumentMergeParams({ + jsonDataForMerge, + outputFormat: OutputFormat.PDF + }); + + // Creates a new job instance + const job = new DocumentMergeJob({inputAsset, params}); + + // Submit the job and get the job result + const pollingURL = await pdfServices.submit({job}); + const pdfServicesResponse = await pdfServices.getJobResult({ + pollingURL, + resultType: DocumentMergeResult + }); + + // Get content from the resulting asset(s) + const resultAsset = pdfServicesResponse.result.asset; + const streamAsset = await pdfServices.getContent({asset: resultAsset}); + + // Creates a write stream and copy stream asset's content to it + const outputFilePath = "./documentMergeOutput.pdf"; + console.log(`Saving asset at ${outputFilePath}`); + + const writeStream = fs.createWriteStream(outputFilePath); + streamAsset.readStream.pipe(writeStream); + } catch (err) { + if (err instanceof SDKError || err instanceof ServiceUsageError || err instanceof ServiceApiError) { + console.log("Exception encountered while executing operation", err); + } else { + console.log("Exception encountered while executing operation", err); + } + } finally { + readStream?.destroy(); + } +})(); ``` #### Rest API @@ -439,7 +470,7 @@ with the input JSON data. #### Generate PDF or Word document (with [Fragments](./fragments.md)) -The sample below shows the use of **Fragments** in the word template and generates the output document in the **PDF** format. +The sample below shows the use of **Fragments** in the word template and generates the output document in the **DOCX** format. Please refer the [API usage guide](../pdf-services-api/howtos/api-usage.md) to understand how to use our APIs. @@ -450,7 +481,7 @@ Please refer the [API usage guide](../pdf-services-api/howtos/api-usage.md) to u ```javascript // Get the samples from https://www.adobe.com/go/pdftoolsapi_java_samples // Run the sample: -// mvn -f pom.xml exec:java -Dexec.mainClass=com.adobe.pdfservices.operation.samples.documentmerge.MergeDocumentToPDFWithFragments +// mvn -f pom.xml exec:java -Dexec.mainClass=com.adobe.pdfservices.operation.samples.documentmerge.MergeDocumentToDOCXWithFragments package com.adobe.pdfservices.operation.samples.documentmerge; public class MergeDocumentToPDFWithFragments { @@ -531,7 +562,7 @@ Please refer the [API usage guide](../pdf-services-api/howtos/api-usage.md) to u StreamAsset streamAsset = pdfServices.getContent(resultAsset); // Creates an output stream and copy stream asset's content to it - OutputStream outputStream = Files.newOutputStream(new File("output/documentMergeFragmentsOutput.pdf").toPath()); + OutputStream outputStream = Files.newOutputStream(new File("output/documentMergeFragmentsOutput.docx").toPath()); IOUtils.copy(streamAsset.getInputStream(), outputStream); outputStream.close(); } catch (ServiceApiException | IOException | SDKException | ServiceUsageException ex) { @@ -547,8 +578,8 @@ Please refer the [API usage guide](../pdf-services-api/howtos/api-usage.md) to u // Get the samples from https://www.adobe.com/go/pdftoolsapi_net_samples // Run the sample: // cd MergeDocumentToDocx/ -// dotnet run MergeDocumentToDOCX.csproj - namespace MergeDocumentToPDFFragments +// dotnet run MergeDocumentToDocxFragments.csproj + namespace MergeDocumentToDocxFragments { class Program { @@ -589,7 +620,7 @@ Please refer the [API usage guide](../pdf-services-api/howtos/api-usage.md) to u // Create a new DocumentMerge Options instance with fragment - DocumentMergeOptions documentMergeOptions = new DocumentMergeOptions(jsonDataForMerge, OutputFormat.PDF, fragments); + DocumentMergeOptions documentMergeOptions = new DocumentMergeOptions(jsonDataForMerge, OutputFormat.DOCX, fragments); // Create a new DocumentMerge Operation instance with the DocumentMerge Options instance DocumentMergeOperation documentMergeOperation = DocumentMergeOperation.CreateNew(documentMergeOptions); @@ -601,7 +632,7 @@ Please refer the [API usage guide](../pdf-services-api/howtos/api-usage.md) to u FileRef result = documentMergeOperation.Execute(executionContext); // Save the result to the specified location - result.SaveAs(Directory.GetCurrentDirectory() + "/output/orderDetailOutput.pdf"); + result.SaveAs(Directory.GetCurrentDirectory() + "/output/orderDetailOutput.docx"); } catch (ServiceUsageException ex) { @@ -640,75 +671,106 @@ Please refer the [API usage guide](../pdf-services-api/howtos/api-usage.md) to u // Run the sample: // node src/documentmerge/merge-document-to-pdf-fragments.js - const PDFServicesSdk = require('@dcloud/pdfservices-node-sdk'); - +const { + ServicePrincipalCredentials, + PDFServices, + MimeType, + DocumentMergeParams, + OutputFormat, + DocumentMergeJob, + DocumentMergeResult, + SDKError, + ServiceUsageError, + ServiceApiError +} = require("@adobe/pdfservices-node-sdk"); +const fs = require("fs"); + +(async () => { + let readStream; try { - // Initial setup, create credentials instance. - const credentials = PDFServicesSdk.Credentials - .servicePrincipalCredentialsBuilder() - .withClientId("PDF_SERVICES_CLIENT_ID") - .withClientSecret("PDF_SERVICES_CLIENT_SECRET") - .build(); - + // Initial setup, create credentials instance + const credentials = new ServicePrincipalCredentials({ + clientId: process.env.PDF_SERVICES_CLIENT_ID, + clientSecret: process.env.PDF_SERVICES_CLIENT_SECRET + }); + + // Creates a PDF Services instance + const pdfServices = new PDFServices({credentials}); + + // Creates an asset(s) from source file(s) and upload + readStream = fs.createReadStream("./documentMergeFragmentsTemplate.docx"); + const inputAsset = await pdfServices.upload({ + readStream, + mimeType: MimeType.DOCX + }); + // Setup input data for the document merge process - const jsonString = ` -{ - "customerName": "Kane Miller", - "customerVisits": 100," - "itemsBought": [ - { - "description": "Sprays", - "quantity": 50", - "amount: 100 - }, - { - "description": "Chemicals", - "quantity": 100", - "amount": 200 - } - ], - "totalAmount": 300, - "previousBalance": 50, - "lastThreeBillings": [100, 200, 300], - "photograph": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP88h8AAu0B9XNPCQQAAAAASUVORK5CYII=" -}`; - - jsonDataForMerge = JSON.parse(jsonString); - - const fragment1 = JSON.parse(`{"orderDetails": "Quantity:{{quantity}}, Description:{{description}}, Amount:{{amount}}"}`); - const fragment2 = JSON.parse(`{"customerDetails": "{{customerName}}, Visits: {{customerVisits}}"}`); - - const fragmentsList = [fragment1, fragment2]; - - // Create an ExecutionContext using credentials - const executionContext = PDFServicesSdk.ExecutionContext.create(credentials); - - // Create a new DocumentMerge options instance - const documentMerge = PDFServicesSdk.DocumentMerge, - documentMergeOptions = documentMerge.options, - options = new documentMergeOptions.DocumentMergeOptions(jsonDataForMerge, documentMergeOptions.OutputFormat.PDF, fragmentsList); - - // Create a new operation instance using the options instance - const documentMergeOperation = documentMerge.Operation.createNew(options); - - // Set operation input document template from a source file. - const input = PDFServicesSdk.FileRef.createFromLocalFile('resources/documentMergeFragmentsTemplate.docx'); - documentMergeOperation.setInput(input); - - // Execute the operation and Save the result to the specified location. - documentMergeOperation.execute(executionContext) - .then(result => result.saveAsFile('output/documentMergeOutput.pdf')) - .catch(err => { - if(err instanceof PDFServicesSdk.Error.ServiceApiError - || err instanceof PDFServicesSdk.Error.ServiceUsageError) { - console.log('Exception encountered while executing operation', err); - } else { - console.log('Exception encountered while executing operation', err); + const jsonDataForMerge = { + customerName: 'Kane Miller', + customerVisits: 100, + itemsBought: [ + { + description: 'Sprays', + quantity: 50, + amount: 100 + }, + { + description: 'Chemicals', + quantity: 100, + amount: 200 } - }); + ], + totalAmount: 300, + previousBalance: 50, + lastThreeBillings: [ + 100, + 200, + 300 + ], + photograph: 'data:image/png;base64,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' + }; + + // Create fragments from fragment JSON data + const fragment1 = JSON.parse("{\"orderDetails\": \"Quantity:{{quantity}}, Description:{{description}}, Amount:{{amount}}\"}"); + const fragment2 = JSON.parse("{\"customerDetails\": \"{{customerName}}, Visits: {{customerVisits}}\"}"); + + // Create parameters for the job + const params = new DocumentMergeParams({ + jsonDataForMerge, + outputFormat: OutputFormat.DOCX, + fragments: [fragment1, fragment2] + }); + + // Creates a new job instance + const job = new DocumentMergeJob({inputAsset, params}); + + // Submit the job and get the job result + const pollingURL = await pdfServices.submit({job}); + const pdfServicesResponse = await pdfServices.getJobResult({ + pollingURL, + resultType: DocumentMergeResult + }); + + // Get content from the resulting asset(s) + const resultAsset = pdfServicesResponse.result.asset; + const streamAsset = await pdfServices.getContent({asset: resultAsset}); + + // Creates a write stream and copy stream asset's content to it + const outputFilePath = "./documentMergeFragmentsOutput.docx"; + console.log(`Saving asset at ${outputFilePath}`); + + const writeStream = fs.createWriteStream(outputFilePath); + streamAsset.readStream.pipe(writeStream); } catch (err) { - console.log('Exception encountered while executing operation', err); + if (err instanceof SDKError || err instanceof ServiceUsageError || err instanceof ServiceApiError) { + console.log("Exception encountered while executing operation", err); + } else { + console.log("Exception encountered while executing operation", err); + } + } finally { + readStream?.destroy(); } +})(); ``` #### Rest API @@ -723,7 +785,7 @@ curl --location --request POST 'https://pdf-services.adobe.io/operation/document --header 'Authorization: Bearer {{Placeholder for token}}' \ --data-raw '{ "assetID": "urn:aaid:AS:UE1:23c30ee0-2e4d-46d6-87f2-087832fca718", - "outputFormat": "pdf", + "outputFormat": "docx", "jsonDataForMerge": { "customerName": "Kane Miller", "customerVisits": 100, diff --git a/src/pages/overview/document-generation-api/quickstarts/nodejs/index.md b/src/pages/overview/document-generation-api/quickstarts/nodejs/index.md index defe2c436..c975de52f 100644 --- a/src/pages/overview/document-generation-api/quickstarts/nodejs/index.md +++ b/src/pages/overview/document-generation-api/quickstarts/nodejs/index.md @@ -10,7 +10,7 @@ To get started using Adobe Document Generation API, let's walk through a simple To complete this guide, you will need: -* [Node.js](https://nodejs.org) - Node.js version 14.0 or higher is required. +* [Node.js](https://nodejs.org) - Node.js version 18.0 or higher is required. * An Adobe ID. If you do not have one, the credential setup will walk you through creating one. * A way to edit code. No specific editor is required for this guide. @@ -116,28 +116,22 @@ Notice how the tokens in the Word document match up with values in our JSON. Whi 3) We'll begin by including our required dependencies: ```js -const PDFServicesSdk = require('@adobe/pdfservices-node-sdk'); -const fs = require('fs'); +const { + ServicePrincipalCredentials, + PDFServices, + MimeType, + DocumentMergeParams, + OutputFormat, + DocumentMergeJob, + DocumentMergeResult, + SDKError, + ServiceUsageError, + ServiceApiError +} = require("@adobe/pdfservices-node-sdk"); +const fs = require("fs"); ``` -The first line includes the Adobe PDF Services Node.js SDK. The second third include Node's `filesystem` package. - -2) Now let's define our input and output: - -```js -const OUTPUT = './generatedReceipt.pdf'; - -// If our output already exists, remove it so we can run the application again. -if(fs.existsSync(OUTPUT)) fs.unlinkSync(OUTPUT); - -const INPUT = './receiptTemplate.docx'; - -const JSON_INPUT = require('./receipt.json'); -``` - -These lines are hard coded but in a real application would typically be dynamic. - -3) Set the environment variables `PDF_SERVICES_CLIENT_ID` and `PDF_SERVICES_CLIENT_SECRET` by running the following commands and replacing placeholders `YOUR CLIENT ID` and `YOUR CLIENT SECRET` with the credentials present in `pdfservices-api-credentials.json` file: +4) Set the environment variables `PDF_SERVICES_CLIENT_ID` and `PDF_SERVICES_CLIENT_SECRET` by running the following commands and replacing placeholders `YOUR CLIENT ID` and `YOUR CLIENT SECRET` with the credentials present in `pdfservices-api-credentials.json` file: - **Windows:** - `set PDF_SERVICES_CLIENT_ID=` - `set PDF_SERVICES_CLIENT_SECRET=` @@ -146,109 +140,153 @@ These lines are hard coded but in a real application would typically be dynamic. - `export PDF_SERVICES_CLIENT_ID=` - `export PDF_SERVICES_CLIENT_SECRET=` -4) Next, we setup the SDK to use our credentials. +5) Next, we setup the SDK to use our credentials. ```js -const credentials = PDFServicesSdk.Credentials - .servicePrincipalCredentialsBuilder() - .withClientId(process.env.PDF_SERVICES_CLIENT_ID) - .withClientSecret(process.env.PDF_SERVICES_CLIENT_SECRET) - .build(); - -// Create an ExecutionContext using credentials -const executionContext = PDFServicesSdk.ExecutionContext.create(credentials); -``` +// Initial setup, create credentials instance +const credentials = new ServicePrincipalCredentials({ + clientId: process.env.PDF_SERVICES_CLIENT_ID, + clientSecret: process.env.PDF_SERVICES_CLIENT_SECRET +}); -This code both points to the credentials downloaded previously as well as sets up an execution context object that will be used later. +// Creates a PDF Services instance +const pdfServices = new PDFServices({credentials}); +``` -5) Now, let's create the operation: +6) Now, let's upload the asset and create JSON data for merge: ```js -const documentMerge = PDFServicesSdk.DocumentMerge, - documentMergeOptions = documentMerge.options, - options = new documentMergeOptions.DocumentMergeOptions(JSON_INPUT, documentMergeOptions.OutputFormat.PDF); +// Creates an asset(s) from source file(s) and upload +readStream = fs.createReadStream("./receiptTemplate.docx"); +const inputAsset = await pdfServices.upload({ + readStream, + mimeType: MimeType.DOCX +}); + +// Setup input data for the document merge process +const jsonDataForMerge = JSON.parse(fs.readFileSync('./receipt.json', 'utf-8')); +``` -// Create a new operation instance using the options instance. -const documentMergeOperation = documentMerge.Operation.createNew(options); +7) Now, let's create the parameters and the job: -// Set operation input document template from a source file. -const input = PDFServicesSdk.FileRef.createFromLocalFile(INPUT); -documentMergeOperation.setInput(input); +```js +// Create parameters for the job +const params = new DocumentMergeParams({ + jsonDataForMerge, + outputFormat: OutputFormat.PDF +}); + +// Creates a new job instance +const job = new DocumentMergeJob({inputAsset, params}); ``` This set of code defines what we're doing (a document merge operation, the SDK's way of describing Document Generation), points to our local JSON file and specifies the output is a PDF. It also points to the Word file used as a template. -6) The next code block executes the operation: +8) The next code block submits the job and gets the job result: ```js -// Execute the operation and Save the result to the specified location. -documentMergeOperation.execute(executionContext) -.then(result => result.saveAsFile(OUTPUT)) -.catch(err => { - if(err instanceof PDFServicesSdk.Error.ServiceApiError - || err instanceof PDFServicesSdk.Error.ServiceUsageError) { - console.log('Exception encountered while executing operation', err); - } else { - console.log('Exception encountered while executing operation', err); - } +// Submit the job and get the job result +const pollingURL = await pdfServices.submit({job}); +const pdfServicesResponse = await pdfServices.getJobResult({ + pollingURL, + resultType: DocumentMergeResult }); -``` - -This code runs the document generation process and then stores the result PDF document to the file system. -![Example running at the command line](./shot9.png) +// Get content from the resulting asset(s) +const resultAsset = pdfServicesResponse.result.asset; +const streamAsset = await pdfServices.getContent({asset: resultAsset}); +``` -Here's the complete application (`documentmerge.js`): +9) The next code block saves the result at the specified location: ```js -const PDFServicesSdk = require('@adobe/pdfservices-node-sdk'); -const fs = require('fs'); - -const OUTPUT = './generatedReceipt.pdf'; +// Creates a write stream and copy stream asset's content to it +const outputFilePath = "./generatePDFOutput.pdf"; +console.log(`Saving asset at ${outputFilePath}`); -// If our output already exists, remove it so we can run the application again. -if(fs.existsSync(OUTPUT)) fs.unlinkSync(OUTPUT); +const writeStream = fs.createWriteStream(outputFilePath); +streamAsset.readStream.pipe(writeStream); +``` -const INPUT = './receiptTemplate.docx'; +This code runs the Document Generation process and then stores the resulting PDF document to the file system. -const JSON_INPUT = require('./receipt.json'); +![Example running at the command line](./shot9.png) +Here's the complete application (`documentmerge.js`): -// Set up our credentials object. -const credentials = PDFServicesSdk.Credentials - .servicePrincipalCredentialsBuilder() - .withClientId(process.env.PDF_SERVICES_CLIENT_ID) - .withClientSecret(process.env.PDF_SERVICES_CLIENT_SECRET) - .build(); +```js +const { + ServicePrincipalCredentials, + PDFServices, + MimeType, + DocumentMergeParams, + OutputFormat, + DocumentMergeJob, + DocumentMergeResult, + SDKError, + ServiceUsageError, + ServiceApiError +} = require("@adobe/pdfservices-node-sdk"); +const fs = require("fs"); + +(async () => { + let readStream; + try { + // Initial setup, create credentials instance + const credentials = new ServicePrincipalCredentials({ + clientId: process.env.PDF_SERVICES_CLIENT_ID, + clientSecret: process.env.PDF_SERVICES_CLIENT_SECRET + }); -// Create an ExecutionContext using credentials -const executionContext = PDFServicesSdk.ExecutionContext.create(credentials); + // Creates a PDF Services instance + const pdfServices = new PDFServices({credentials}); -// This creates an instance of the Export operation we're using, as well as specifying output type (DOCX) -const documentMerge = PDFServicesSdk.DocumentMerge, - documentMergeOptions = documentMerge.options, - options = new documentMergeOptions.DocumentMergeOptions(JSON_INPUT, documentMergeOptions.OutputFormat.PDF); + // Creates an asset(s) from source file(s) and upload + readStream = fs.createReadStream("./receiptTemplate.docx"); + const inputAsset = await pdfServices.upload({ + readStream, + mimeType: MimeType.DOCX + }); -// Create a new operation instance using the options instance. -const documentMergeOperation = documentMerge.Operation.createNew(options); + // Setup input data for the document merge process + const jsonDataForMerge = JSON.parse(fs.readFileSync('./receipt.json', 'utf-8')); -// Set operation input document template from a source file. -const input = PDFServicesSdk.FileRef.createFromLocalFile(INPUT); -documentMergeOperation.setInput(input); + // Create parameters for the job + const params = new DocumentMergeParams({ + jsonDataForMerge, + outputFormat: OutputFormat.PDF + }); + // Creates a new job instance + const job = new DocumentMergeJob({inputAsset, params}); -// Execute the operation and Save the result to the specified location. -documentMergeOperation.execute(executionContext) - .then(result => result.saveAsFile(OUTPUT)) - .catch(err => { - if(err instanceof PDFServicesSdk.Error.ServiceApiError - || err instanceof PDFServicesSdk.Error.ServiceUsageError) { - console.log('Exception encountered while executing operation', err); - } else { - console.log('Exception encountered while executing operation', err); - } + // Submit the job and get the job result + const pollingURL = await pdfServices.submit({job}); + const pdfServicesResponse = await pdfServices.getJobResult({ + pollingURL, + resultType: DocumentMergeResult }); + // Get content from the resulting asset(s) + const resultAsset = pdfServicesResponse.result.asset; + const streamAsset = await pdfServices.getContent({asset: resultAsset}); + + // Creates a write stream and copy stream asset's content to it + const outputFilePath = "./generatePDFOutput.pdf"; + console.log(`Saving asset at ${outputFilePath}`); + + const writeStream = fs.createWriteStream(outputFilePath); + streamAsset.readStream.pipe(writeStream); + } catch (err) { + if (err instanceof SDKError || err instanceof ServiceUsageError || err instanceof ServiceApiError) { + console.log("Exception encountered while executing operation", err); + } else { + console.log("Exception encountered while executing operation", err); + } + } finally { + readStream?.destroy(); + } +})(); ``` ## Next Steps diff --git a/src/pages/overview/document-generation-api/quickstarts/nodejs/shot9.png b/src/pages/overview/document-generation-api/quickstarts/nodejs/shot9.png index 39aaa5a63..0c7e508e7 100644 Binary files a/src/pages/overview/document-generation-api/quickstarts/nodejs/shot9.png and b/src/pages/overview/document-generation-api/quickstarts/nodejs/shot9.png differ diff --git a/src/pages/overview/legacy-documentation/pdf-extract-api/quickstarts.md b/src/pages/overview/legacy-documentation/pdf-extract-api/quickstarts.md index c0d871f02..7528957b7 100644 --- a/src/pages/overview/legacy-documentation/pdf-extract-api/quickstarts.md +++ b/src/pages/overview/legacy-documentation/pdf-extract-api/quickstarts.md @@ -331,7 +331,7 @@ After downloading the zip, you can either run the samples in the zip directly, o Running any sample or custom code requires the following steps: -1. Install [Node.js 14.0](https://nodejs.org/en/download/) or higher. +1. Install [Node.js 18.0](https://nodejs.org/en/download/) or higher. diff --git a/src/pages/overview/pdf-accessibility-auto-tag-api/gettingstarted.md b/src/pages/overview/pdf-accessibility-auto-tag-api/gettingstarted.md index 070036f3f..2c3bfb285 100644 --- a/src/pages/overview/pdf-accessibility-auto-tag-api/gettingstarted.md +++ b/src/pages/overview/pdf-accessibility-auto-tag-api/gettingstarted.md @@ -472,7 +472,7 @@ After downloading the zip, you can run the samples in the zip directly by settin Running any sample or custom code requires the following steps: -1. Install [Node.js 14.0](https://nodejs.org/en/download/) or higher. +1. Install [Node.js 18.0](https://nodejs.org/en/download/) or higher. diff --git a/src/pages/overview/pdf-accessibility-auto-tag-api/howtos/accessibility-auto-tag-api.md b/src/pages/overview/pdf-accessibility-auto-tag-api/howtos/accessibility-auto-tag-api.md index 6f6ec73f0..4fde737da 100644 --- a/src/pages/overview/pdf-accessibility-auto-tag-api/howtos/accessibility-auto-tag-api.md +++ b/src/pages/overview/pdf-accessibility-auto-tag-api/howtos/accessibility-auto-tag-api.md @@ -190,42 +190,64 @@ namespace AutotagPDF // Run the sample: // node src/autotagpdf/autotag-pdf.js -const PDFServicesSdk = require('@adobe/pdfservices-node-sdk'); - -try { - // Initial setup, create credentials instance. - const credentials = PDFServicesSdk.Credentials - .servicePrincipalCredentialsBuilder() - .withClientId("PDF_SERVICES_CLIENT_ID") - .withClientSecret("PDF_SERVICES_CLIENT_SECRET") - .build(); - - // Create an ExecutionContext using credentials and create a new operation instance. - const executionContext = PDFServicesSdk.ExecutionContext.create(credentials), - autotagPDF = PDFServicesSdk.AutotagPDF, - autotagPDFOperation = autotagPDF.Operation.createNew(); - - // Set operation input from a source file. - const input = PDFServicesSdk.FileRef.createFromLocalFile('autotagPDFInput.pdf'); - autotagPDFOperation.setInput(input); - - // Execute the operation and Save the result to the specified location. - autotagPDFOperation.execute(executionContext) - .then(result => { - result.taggedPDF.saveAsFile('autotagPDFOutput.pdf'); - }) - .catch(err => { - if(err instanceof PDFServicesSdk.Error.ServiceApiError - || err instanceof PDFServicesSdk.Error.ServiceUsageError) { - console.log('Exception encountered while executing operation', err); - } else { - console.log('Exception encountered while executing operation', err); - } +const { + ServicePrincipalCredentials, + PDFServices, + MimeType, + AutotagPDFJob, + AutotagPDFResult, +} = require("@adobe/pdfservices-node-sdk"); +const fs = require("fs"); + +(async () => { + let readStream; + try { + // Initial setup, create credentials instance + const credentials = new ServicePrincipalCredentials({ + clientId: process.env.PDF_SERVICES_CLIENT_ID, + clientSecret: process.env.PDF_SERVICES_CLIENT_SECRET }); - -} catch (err) { - console.log('Exception encountered while executing operation', err); -} + + // Creates a PDF Services instance + const pdfServices = new PDFServices({credentials}); + + // Creates an asset(s) from source file(s) and upload + readStream = fs.createReadStream("./autotagPDFInput.pdf"); + const inputAsset = await pdfServices.upload({ + readStream, + mimeType: MimeType.PDF + }); + + // Creates a new job instance + const job = new AutotagPDFJob({inputAsset}); + + // Submit the job and get the job result + const pollingURL = await pdfServices.submit({job}); + const pdfServicesResponse = await pdfServices.getJobResult({ + pollingURL, + resultType: AutotagPDFResult + }); + + // Get content from the resulting asset(s) + const resultAsset = pdfServicesResponse.result.taggedPDF; + const streamAsset = await pdfServices.getContent({asset: resultAsset}); + + // Creates an output stream and copy stream asset's content to it + const outputFilePath = "./autotag-tagged.pdf"; + console.log(`Saving asset at ${outputFilePath}`); + + let writeStream = fs.createWriteStream(outputFilePath); + streamAsset.readStream.pipe(writeStream); + } catch (err) { + if (err instanceof SDKError || err instanceof ServiceUsageError || err instanceof ServiceApiError) { + console.log("Exception encountered while executing operation", err); + } else { + console.log("Exception encountered while executing operation", err); + } + } finally { + readStream?.destroy(); + } +})(); ``` #### Python @@ -554,70 +576,100 @@ namespace AutotagPDFParameterised // Run the sample: // node src/autotag/autoag-pdf-parameterised.js -const PDFServicesSdk = require('@adobe/pdfservices-node-sdk'); - +const { + ServicePrincipalCredentials, + PDFServices, + MimeType, + AutotagPDFParams, + AutotagPDFJob, + AutotagPDFResult, + SDKError, + ServiceUsageError, + ServiceApiError +} = require("@adobe/pdfservices-node-sdk"); +const fs = require("fs"); const args = process.argv; -try { - console.log("--input " + getInputFilePathFromCmdArgs(args)); - console.log("--output " + getOutputFilePathFromCmdArgs(args)); - console.log("--report " + getGenerateReportFromCmdArgs(args)); - console.log("--shift_headings " + getShiftHeadingsFromCmdArgs(args)); - - // Initial setup, create credentials instance. - const credentials = PDFServicesSdk.Credentials - .servicePrincipalCredentialsBuilder() - .withClientId("PDF_SERVICES_CLIENT_ID") - .withClientSecret("PDF_SERVICES_CLIENT_SECRET") - .build(); - - // Create an ExecutionContext using credentials and create a new operation instance. - const executionContext = PDFServicesSdk.ExecutionContext.create(credentials), - autotagPDF = PDFServicesSdk.AutotagPDF, - autotagPDFOperation = autotagPDF.Operation.createNew(); - - // Set operation input from a source file. - const input = PDFServicesSdk.FileRef.createFromLocalFile(getInputFilePathFromCmdArgs(args)); - autotagPDFOperation.setInput(input); - - // Create Options - let autotagPDFOptionsBuilder = new PDFServicesSdk.AutotagPDF.options.AutotagPDFOptions.Builder(); - autotagPDFOptionsBuilder = getShiftHeadingsFromCmdArgs(args) ? autotagPDFOptionsBuilder.shiftHeadings() : autotagPDFOptionsBuilder; - autotagPDFOptionsBuilder = getGenerateReportFromCmdArgs(args) ? autotagPDFOptionsBuilder.generateReport() : autotagPDFOptionsBuilder; - - const autotagPDFOptions = autotagPDFOptionsBuilder.build(); - - // Set operation options - autotagPDFOperation.setOptions(autotagPDFOptions); - - let outputPath = getOutputFilePathFromCmdArgs(args); - // Execute the operation and Save the result to the specified location. - autotagPDFOperation.execute(executionContext) - .then(result => { - result.taggedPDF.saveAsFile(outputPath + 'AutotagPDFParamerterised-tagged.pdf'); - result.report?.saveAsFile(outputPath + 'AutotagPDFParamerterised-report.xlsx'); - }) - .catch(err => { - if(err instanceof PDFServicesSdk.Error.ServiceApiError - || err instanceof PDFServicesSdk.Error.ServiceUsageError) { - console.log('Exception encountered while executing operation', err); - } else { - console.log('Exception encountered while executing operation', err); - } +(async () => { + let readStream; + try { + console.log("--input " + getInputFilePathFromCmdArgs(args)); + console.log("--output " + getOutputFilePathFromCmdArgs(args)); + console.log("--report " + getGenerateReportFromCmdArgs(args)); + console.log("--shift_headings " + getShiftHeadingsFromCmdArgs(args)); + + // Initial setup, create credentials instance + const credentials = new ServicePrincipalCredentials({ + clientId: process.env.PDF_SERVICES_CLIENT_ID, + clientSecret: process.env.PDF_SERVICES_CLIENT_SECRET + }); + + // Creates a PDF Services instance + const pdfServices = new PDFServices({credentials}); + + // Creates an asset(s) from source file(s) and upload + readStream = fs.createReadStream(getInputFilePathFromCmdArgs(args)); + const inputAsset = await pdfServices.upload({ + readStream, + mimeType: MimeType.PDF }); -} catch (err) { - console.log('Exception encountered while executing operation', err); -} + // Create parameters for the job + const params = new AutotagPDFParams({ + generateReport: getGenerateReportFromCmdArgs(args), + shiftHeadings: getShiftHeadingsFromCmdArgs(args) + }); + + // Creates a new job instance + const job = new AutotagPDFJob({inputAsset, params}); + + // Submit the job and get the job result + const pollingURL = await pdfServices.submit({job}); + const pdfServicesResponse = await pdfServices.getJobResult({ + pollingURL, + resultType: AutotagPDFResult + }); + + // Get content from the resulting asset(s) + const resultAsset = pdfServicesResponse.result.taggedPDF; + const resultAssetReport = pdfServicesResponse.result.report; + const streamAsset = await pdfServices.getContent({asset: resultAsset}); + const streamAssetReport = resultAssetReport + ? await pdfServices.getContent({asset: resultAssetReport}) + : undefined; + + // Creates an output stream and copy stream asset's content to it + const outputPath = getOutputFilePathFromCmdArgs(args); + const outputFilePath = outputPath + "autotagPDFInput-tagged.pdf"; + console.log(`Saving asset at ${outputFilePath}`); + + const writeStream = fs.createWriteStream(outputFilePath); + streamAsset.readStream.pipe(writeStream); + if (resultAssetReport) { + const outputFileReportPath = outputPath + "autotagPDFInput-report.xlsx"; + console.log(`Saving asset at ${outputFileReportPath}`); + + const writeStream = fs.createWriteStream(outputFileReportPath); + streamAssetReport.readStream.pipe(writeStream); + } + } catch (err) { + if (err instanceof SDKError || err instanceof ServiceUsageError || err instanceof ServiceApiError) { + console.log("Exception encountered while executing operation", err); + } else { + console.log("Exception encountered while executing operation", err); + } + } finally { + readStream?.destroy(); + } +})(); function getInputFilePathFromCmdArgs(args) { let inputFilePath = "resources/autotagPdfInput.pdf"; let inputFilePathIndex = args.indexOf("--input"); if (inputFilePathIndex >= 0 && inputFilePathIndex < args.length - 1) { inputFilePath = args[inputFilePathIndex + 1]; - }else + } else console.log("input file not specified, using default value : autotagPdfInput.pdf"); - return inputFilePath; } @@ -626,9 +678,10 @@ function getOutputFilePathFromCmdArgs(args) { let outputFilePathIndex = args.indexOf("--output"); if (outputFilePathIndex >= 0 && outputFilePathIndex < args.length - 1) { outputFilePath = args[outputFilePathIndex + 1]; - }else - console.log("output path not specified, using default value : output/"); - + } else { + console.log("output path not specified, using default value :" + outputFilePath); + fs.mkdirSync(outputFilePath, {recursive: true}); + } return outputFilePath; } diff --git a/src/pages/overview/pdf-accessibility-auto-tag-api/howtos/index.md b/src/pages/overview/pdf-accessibility-auto-tag-api/howtos/index.md index ace3c5bbb..dd3755467 100644 --- a/src/pages/overview/pdf-accessibility-auto-tag-api/howtos/index.md +++ b/src/pages/overview/pdf-accessibility-auto-tag-api/howtos/index.md @@ -87,13 +87,8 @@ ClientConfig clientConfig = ClientConfig.ConfigBuilder() Available properties: -- **connectTimeout**: Default: 10000. The maximum allowed time in - milliseconds for creating an initial HTTPS connection. -- **readTimeout**: Default: 10000. The maximum allowed time in - milliseconds between two successive HTTP response packets. -- **processingTimeout**: Default: 600000. The maximum allowed time - in milliseconds for processing the documents. Any operation taking more time than the specified `processingTimeout` will result in an operation timeout exception. - - **Note :** It is advisable to set the `processingTimeout` to higher values for processing large files. +- **timeout**: Default: 10000. The maximum allowed time in milliseconds before the request times out. If the request + takes longer than `timeout`, the request will be aborted. Override the timeout properties via a custom `ClientConfig` class: @@ -102,11 +97,9 @@ Override the timeout properties via a custom `ClientConfig` class: ### ```javascript -const clientConfig = PDFServicesSdk.ClientConfig - .clientConfigBuilder() - .withConnectTimeout(15000) - .withReadTimeout(15000) - .build(); +const clientConfig = new ClientConfig({ + timeout: 15000 +}) ``` ### Python timeout configuration diff --git a/src/pages/overview/pdf-accessibility-auto-tag-api/quickstarts/nodejs/index.md b/src/pages/overview/pdf-accessibility-auto-tag-api/quickstarts/nodejs/index.md index f01d529b7..a02edf535 100644 --- a/src/pages/overview/pdf-accessibility-auto-tag-api/quickstarts/nodejs/index.md +++ b/src/pages/overview/pdf-accessibility-auto-tag-api/quickstarts/nodejs/index.md @@ -10,7 +10,7 @@ To get started using Adobe PDF Accessibility Auto-Tag API, let's walk through a To complete this guide, you will need: -* [Node.js](https://nodejs.org) - Node.js version 14.0 or higher is required. +* [Node.js](https://nodejs.org) - Node.js version 18.0 or higher is required. * An Adobe ID. If you do not have one, the credential setup will walk you through creating one. * A way to edit code. No specific editor is required for this guide. @@ -40,7 +40,7 @@ To complete this guide, you will need: ![alt](./shot5_spc.png) -2) Take these the `pdfservices-api-credentials.json` and place it in a new directory. Remember that these credential files are important and should be stored safely. +2) Take the `pdfservices-api-credentials.json` and place it in a new directory. Remember that these credential files are important and should be stored safely. 3) At the command line, change to the directory you created, and initialize a new Node.js project with `npm init -y` @@ -65,27 +65,18 @@ Now you're ready to begin coding. 1) We'll begin by including our required dependencies: ```js -const PDFServicesSdk = require('@adobe/pdfservices-node-sdk'); +const { + ServicePrincipalCredentials, + PDFServices, + MimeType, + AutotagPDFParams, + AutotagPDFJob, + AutotagPDFResult, +} = require("@adobe/pdfservices-node-sdk"); +const fs = require("fs"); ``` -The first line includes the Adobe PDF Services Node.js SDK. The second third include Node's `filesystem` package as well as the package that will work with the ZIP file returned from the API. - -2) Now let's define our input and output: - -```js -const INPUT_PDF = './Adobe Accessibility Auto-Tag API Sample.pdf'; -const OUTPUT_PATH = './output/AutotagPDF/'; - -//Remove if the output already exists. -if(fs.existsSync(OUTPUT_PATH)) fs.unlinkSync(OUTPUT_PATH); - -const TAGGED_PDF = OUTPUT_PATH + INPUT_PDF + "-tagged-pdf.pdf"; -const TAGGING_REPORT = OUTPUT_PATH + INPUT_PDF + "-tagging-report.xlsx"; -``` - -This defines what our output directory will be and optionally deletes it if it already exists. Then we define what PDF will be tagged. (You can download the source we used here.) In a real application, these values would be typically be dynamic. - -3) Set the environment variables `PDF_SERVICES_CLIENT_ID` and `PDF_SERVICES_CLIENT_SECRET` by running the following commands and replacing placeholders `YOUR CLIENT ID` and `YOUR CLIENT SECRET` with the credentials present in `pdfservices-api-credentials.json` file: +2) Set the environment variables `PDF_SERVICES_CLIENT_ID` and `PDF_SERVICES_CLIENT_SECRET` by running the following commands and replacing placeholders `YOUR CLIENT ID` and `YOUR CLIENT SECRET` with the credentials present in `pdfservices-api-credentials.json` file: - **Windows:** - `set PDF_SERVICES_CLIENT_ID=` - `set PDF_SERVICES_CLIENT_SECRET=` @@ -94,52 +85,74 @@ This defines what our output directory will be and optionally deletes it if it a - `export PDF_SERVICES_CLIENT_ID=` - `export PDF_SERVICES_CLIENT_SECRET=` -4) Next, we setup the SDK to use our credentials. +3) Next, we can create our credentials and use them: ```js -const credentials = PDFServicesSdk.Credentials - .servicePrincipalCredentialsBuilder() - .withClientId(process.env.PDF_SERVICES_CLIENT_ID) - .withClientSecret(process.env.PDF_SERVICES_CLIENT_SECRET) - .build(); - -// Create an ExecutionContext using credentials -const executionContext = PDFServicesSdk.ExecutionContext.create(credentials); +// Initial setup, create credentials instance +const credentials = new ServicePrincipalCredentials({ + clientId: process.env.PDF_SERVICES_CLIENT_ID, + clientSecret: process.env.PDF_SERVICES_CLIENT_SECRET +}); + +// Creates a PDF Services instance +const pdfServices = new PDFServices({credentials}); ``` -This code both points to the credentials downloaded previously as well as sets up an execution context object that will be used later. +4) Now, let's upload the asset: -4) Now, let's create the operation: +```js +const inputAsset = await pdfServices.upload({ + readStream, + mimeType: MimeType.PDF +}); +``` + +5) Now, let's create the parameters and the job: ```js -// Create a new operation instance. -const autotagPDFOperation = PDFServicesSdk.AutotagPDF.Operation.createNew(), - input = PDFServicesSdk.FileRef.createFromLocalFile(INPUT_PDF); - -// Build autotagPDF options -const autotagPDFOptions = new PDFServicesSdk.AutotagPDF.options.AutotagPDFOptions.Builder() - .shiftHeadings() - .generateReport() - .build(); -autotagPDFOperation.setInput(input); -autotagPDFOperation.setOptions(options); +// Create parameters for the job +const params = new AutotagPDFParams({ + generateReport: true, + shiftHeadings: true +}); + +// Creates a new job instance +const job = new AutotagPDFJob({inputAsset, params}); ``` -This set of code defines what we're doing (an Auto-Tag operation), points to our local file and specifies the input is a PDF, and then defines options for the Auto-Tag call. PDF Accessibility Auto-Tag API has a few different options, but in this example, we're simply asking for a basic tagging operation, which returns the tagged PDF document and an XLSX report of the document. +This set of code defines what we're doing (an Auto-Tag operation), +it defines parameters for the Auto-Tag job. PDF Accessibility Auto-Tag API has a few different options, but in this example, we're simply asking for a basic tagging operation, which returns the tagged PDF document and an XLSX report of the document. + +6) The next code block submits the job and gets the job result: + +```js +// Submit the job and get the job result +const pollingURL = await pdfServices.submit({job}); +const pdfServicesResponse = await pdfServices.getJobResult({ + pollingURL, + resultType: AutotagPDFResult +}); + +// Get content from the resulting asset(s) +const resultAsset = pdfServicesResponse.result.taggedPDF; +const resultAssetReport = pdfServicesResponse.result.report; +const streamAsset = await pdfServices.getContent({asset: resultAsset}); +const streamAssetReport = await pdfServices.getContent({asset: resultAssetReport}); +``` -5) The next code block executes the operation: +7) The next code block saves the result at the specified location: ```js -// Execute the operation -autotagPDFOperation.execute(executionContext) - .then(result => { - result.taggedPDF.saveAsFile(TAGGED_PDF); - result.report.saveAsFile(TAGGING_REPORT); - }) - .then(() => { - console.log('Successfully tagged information in PDF.'); - }) - .catch(err => console.log(err)); +// Creates an output stream and copy stream asset's content to it +const outputFilePath = "./autotag-tagged.pdf"; +const outputFilePathReport = "./autotag-report.xlsx"; +console.log(`Saving asset at ${outputFilePath}`); +console.log(`Saving asset at ${outputFilePathReport}`); + +let writeStream = fs.createWriteStream(outputFilePath); +streamAsset.readStream.pipe(writeStream); +writeStream = fs.createWriteStream(outputFilePathReport); +streamAssetReport.readStream.pipe(writeStream); ``` ![Example running at the command line](./shot9_ga.png) @@ -147,48 +160,73 @@ autotagPDFOperation.execute(executionContext) Here's the complete application (`autotag-pdf.js`): ```js -const PDFServicesSdk = require('@adobe/pdfservices-node-sdk'); - -const INPUT_PDF = './Adobe Accessibility Auto-Tag API Sample.pdf'; -const OUTPUT_PATH = './output/AutotagPDF/'; - -//Remove if the output already exists. -if(fs.existsSync(OUTPUT_PATH)) fs.unlinkSync(OUTPUT_PATH); - -const TAGGED_PDF = OUTPUT_PATH + INPUT_PDF + "-tagged-pdf.pdf"; -const TAGGING_REPORT = OUTPUT_PATH + INPUT_PDF + "-tagging-report.xlsx"; - -const credentials = PDFServicesSdk.Credentials - .servicePrincipalCredentialsBuilder() - .withClientId(process.env.PDF_SERVICES_CLIENT_ID) - .withClientSecret(process.env.PDF_SERVICES_CLIENT_SECRET) - .build(); - -// Create an ExecutionContext using credentials -const executionContext = PDFServicesSdk.ExecutionContext.create(credentials); - -// Create a new operation instance. -const autotagPDFOperation = PDFServicesSdk.AutotagPDF.Operation.createNew(), - input = PDFServicesSdk.FileRef.createFromLocalFile(INPUT_PDF); - -// Build autotagPDF options -const autotagPDFOptions = new PDFServicesSdk.AutotagPDF.options.AutotagPDFOptions.Builder() - .shiftHeadings() - .generateReport() - .build(); -autotagPDFOperation.setInput(input); -autotagPDFOperation.setOptions(options); - -// Execute the operation -autotagPDFOperation.execute(executionContext) - .then(result => { - result.taggedPDF.saveAsFile(TAGGED_PDF); - result.report.saveAsFile(TAGGING_REPORT); - }) - .then(() => { - console.log('Successfully tagged information in PDF.'); - }) - .catch(err => console.log(err)); +const { + ServicePrincipalCredentials, + PDFServices, + MimeType, + AutotagPDFParams, + AutotagPDFJob, + AutotagPDFResult, +} = require("@adobe/pdfservices-node-sdk"); +const fs = require("fs"); + +(async () => { + let readStream; + try { + // Initial setup, create credentials instance + const credentials = new ServicePrincipalCredentials({ + clientId: process.env.PDF_SERVICES_CLIENT_ID, + clientSecret: process.env.PDF_SERVICES_CLIENT_SECRET + }); + + // Creates a PDF Services instance + const pdfServices = new PDFServices({credentials}); + + // Creates an asset(s) from source file(s) and upload + readStream = fs.createReadStream("./Adobe_Accessibility_Auto_Tag_API_Sample.pdf"); + const inputAsset = await pdfServices.upload({ + readStream, + mimeType: MimeType.PDF + }); + + // Create parameters for the job + const params = new AutotagPDFParams({ + generateReport: true, + shiftHeadings: true + }); + + // Creates a new job instance + const job = new AutotagPDFJob({inputAsset, params}); + + // Submit the job and get the job result + const pollingURL = await pdfServices.submit({job}); + const pdfServicesResponse = await pdfServices.getJobResult({ + pollingURL, + resultType: AutotagPDFResult + }); + + // Get content from the resulting asset(s) + const resultAsset = pdfServicesResponse.result.taggedPDF; + const resultAssetReport = pdfServicesResponse.result.report; + const streamAsset = await pdfServices.getContent({asset: resultAsset}); + const streamAssetReport = await pdfServices.getContent({asset: resultAssetReport}); + + // Creates an output stream and copy stream asset's content to it + const outputFilePath = "./autotag-tagged.pdf"; + const outputFilePathReport = "./autotag-report.xlsx"; + console.log(`Saving asset at ${outputFilePath}`); + console.log(`Saving asset at ${outputFilePathReport}`); + + let writeStream = fs.createWriteStream(outputFilePath); + streamAsset.readStream.pipe(writeStream); + writeStream = fs.createWriteStream(outputFilePathReport); + streamAssetReport.readStream.pipe(writeStream); + } catch (err) { + console.log("Exception encountered while executing operation", err); + } finally { + readStream?.destroy(); + } +})(); ``` ## Next Steps diff --git a/src/pages/overview/pdf-accessibility-auto-tag-api/quickstarts/nodejs/shot9_ga.png b/src/pages/overview/pdf-accessibility-auto-tag-api/quickstarts/nodejs/shot9_ga.png index 2a7e0cc85..7523559a5 100644 Binary files a/src/pages/overview/pdf-accessibility-auto-tag-api/quickstarts/nodejs/shot9_ga.png and b/src/pages/overview/pdf-accessibility-auto-tag-api/quickstarts/nodejs/shot9_ga.png differ diff --git a/src/pages/overview/pdf-electronic-seal-api/gettingstarted.md b/src/pages/overview/pdf-electronic-seal-api/gettingstarted.md index 1fc48012e..88af5550f 100644 --- a/src/pages/overview/pdf-electronic-seal-api/gettingstarted.md +++ b/src/pages/overview/pdf-electronic-seal-api/gettingstarted.md @@ -521,7 +521,7 @@ After downloading the zip, you can run the samples in the zip directly by settin Running any sample or custom code requires the following steps: -1. Install [Node.js 14.0](https://nodejs.org/en/download/) or higher. +1. Install [Node.js 18.0](https://nodejs.org/en/download/) or higher. diff --git a/src/pages/overview/pdf-electronic-seal-api/howtos/electronic-seal-api.md b/src/pages/overview/pdf-electronic-seal-api/howtos/electronic-seal-api.md index fb49ae40a..bb2d8cfa0 100644 --- a/src/pages/overview/pdf-electronic-seal-api/howtos/electronic-seal-api.md +++ b/src/pages/overview/pdf-electronic-seal-api/howtos/electronic-seal-api.md @@ -404,98 +404,146 @@ namespace ElectronicSeal // Run the sample: // node src/electronicseal/electronic-seal.js -const PDFServicesSdk = require('@adobe/pdfservices-node-sdk'); - -try { - // Initial setup, create credentials instance. - const credentials = PDFServicesSdk.Credentials - .servicePrincipalCredentialsBuilder() - .withClientId("PDF_SERVICES_CLIENT_ID") - .withClientSecret("PDF_SERVICES_CLIENT_SECRET") - .build(); - - // Create an ExecutionContext using credentials - const executionContext = PDFServicesSdk.ExecutionContext.create(credentials); - - const pdfElectronicSeal = PDFServicesSdk.PDFElectronicSeal, - options = pdfElectronicSeal.options; - - //Get the input document to perform the sealing operation - const sourceFile = PDFServicesSdk.FileRef.createFromLocalFile('resources/sampleInvoice.pdf'), - - //Get the background seal image for signature , if required. - sealImageFile = PDFServicesSdk.FileRef.createFromLocalFile('resources/sampleSealImage.png'); - - // Set the Seal Field Name to be created in input PDF document. - sealFieldName = "Signature1"; - - // Set the page number in input document for applying seal. - sealPageNumber = 1; - - // Set if seal should be visible or invisible. - sealVisible = true; - - //Create FieldLocation instance and set the coordinates for applying signature - fieldLocation = new options.FieldLocation(150,250,350,200); - - //Create FieldOptions instance with required details. - fieldOptions = new options.FieldOptions.Builder(sealFieldName) - .setFieldLocation(fieldLocation) - .setPageNumber(sealPageNumber) - .setVisible(sealVisible) - .build(); - - //Set the name of TSP Provider being used. - providerName = ""; - - //Set the access token to be used to access TSP provider hosted APIs. - accessToken = ""; - - //Set the credential ID. - credentialID = ""; - - //Set the PIN generated while creating credentials. - pin = ""; - - //Create CSCAuthContext instance using access token and token type. - cscAuthContext = new options.CSCAuthContext(accessToken, "Bearer"); - - //Create CertificateCredentials instance with required certificate details. - certificateCredentials = options.CertificateCredentials.cscCredentialBuilder() - .withProviderName(providerName) - .withCredentialID(credentialID) - .withPin(pin) - .withCSCAuthContext(cscAuthContext) - .build(); - - //Create SealOptions instance with sealing parameters. - sealOptions = new options.SealOptions.Builder(certificateCredentials, fieldOptions) - .build() - - //Create the PDFElectronicSealOperation instance using the SealOptions instance - const pdfElectronicSealOperation = pdfElectronicSeal.Operation.createNew(sealOptions); - - //Set the input source file for PDFElectronicSealOperation instance - pdfElectronicSealOperation.setInput(sourceFile); - - //Set the optional input seal image for PDFElectronicSealOperation instance - pdfElectronicSealOperation.setSealImage(sealImageFile); - - // Execute the operation and Save the result to the specified location. - pdfElectronicSealOperation.execute(executionContext) - .then(result => result.saveAsFile("output/sealedOutput.pdf")) - .catch(err => { - if(err instanceof PDFServicesSdk.Error.ServiceApiError - || err instanceof PDFServicesSdk.Error.ServiceUsageError) { - console.log('Exception encountered while executing operation', err); - } else { - console.log('Exception encountered while executing operation', err); - } - }); - +const { + ServicePrincipalCredentials, + PDFServices, + MimeType, + DocumentLevelPermission, + FieldLocation, + FieldOptions, + CSCAuthContext, + CSCCredential, + PDFElectronicSealParams, + PDFElectronicSealJob, + PDFElectronicSealResult, + SDKError, + ServiceUsageError, + ServiceApiError +} = require("@adobe/pdfservices-node-sdk"); +const fs = require("fs"); + +(async () => { + let sourceFileReadStream; + let sealImageReadStream; + try { + // Initial setup, create credentials instance + const credentials = new ServicePrincipalCredentials({ + clientId: process.env.PDF_SERVICES_CLIENT_ID, + clientSecret: process.env.PDF_SERVICES_CLIENT_SECRET + }); + + // Creates a PDF Services instance + const pdfServices = new PDFServices({credentials}); + + // Creates an asset(s) from source file(s) and upload + sourceFileReadStream = fs.createReadStream("./sampleInvoice.pdf") + sealImageReadStream = fs.createReadStream("./sampleSealImage.png"); + const [sourceFileAsset, sealImageAsset] = await pdfServices.uploadAssets({ + streamAssets: [{ + readStream: sourceFileReadStream, + mimeType: MimeType.PDF + }, { + readStream: sealImageReadStream, + mimeType: MimeType.PNG + }] + }); + + // Set the document level permission to be applied for output document + const documentLevelPermission = DocumentLevelPermission.FORM_FILLING; + + // Set the Seal Field Name to be created in input PDF document + const sealFieldName = "Signature1"; + + // Set the page number in input document for applying seal + const sealPageNumber = 1; + + // Set if seal should be visible or invisible + const sealVisible = true; + + // Create FieldLocation instance and set the coordinates for applying signature + const fieldLocation = new FieldLocation({ + left: 150, + top: 250, + right: 350, + bottom: 200 + }); + + // Create FieldOptions instance with required details + const sealFieldOptions = new FieldOptions({ + visible: sealVisible, + location: fieldLocation, + fieldName: sealFieldName, + pageNumber: sealPageNumber, + }); + + // Set the name of TSP Provider being used + const providerName = ""; + + // Set the access token to be used to access TSP provider hosted APIs + const accessToken = ""; + + // Set the credential ID + const credentialId = ""; + + // Set the PIN generated while creating credentials + const pin = ""; + + // Create CSCAuthContext instance using access token and token type + const authorizationContext = new CSCAuthContext({ + accessToken, + tokenType: "Bearer" + }); + + // Create CertificateCredentials instance with required certificate details + const certificateCredentials = new CSCCredential({ + providerName, + credentialId, + pin, + authorizationContext, + }); + + // Create parameters for the job + const params = new PDFElectronicSealParams({ + certificateCredentials, + sealFieldOptions, + documentLevelPermission, + }); + + // Creates a new job instance + const job = new PDFElectronicSealJob({ + inputAsset: sourceFileAsset, + sealImageAsset, + params, + }); + + // Submit the job and get the job result + const pollingURL = await pdfServices.submit({job}); + const pdfServicesResponse = await pdfServices.getJobResult({ + pollingURL, + resultType: PDFElectronicSealResult + }); + + // Get content from the resulting asset(s) + const resultAsset = pdfServicesResponse.result.asset; + const streamAsset = await pdfServices.getContent({asset: resultAsset}); + + // Creates a write stream and copy stream asset's content to it + const outputFilePath = "./sealedOutput.pdf"; + console.log(`Saving asset at ${outputFilePath}`); + + const writeStream = fs.createWriteStream(outputFilePath); + streamAsset.readStream.pipe(writeStream); } catch (err) { - console.log('Exception encountered while executing operation', err); -} + if (err instanceof SDKError || err instanceof ServiceUsageError || err instanceof ServiceApiError) { + console.log("Exception encountered while executing operation", err); + } else { + console.log("Exception encountered while executing operation", err); + } + } finally { + sourceFileReadStream?.destroy(); + sealImageReadStream?.destroy(); + } +})(); ``` #### REST API @@ -800,109 +848,162 @@ namespace ElectronicSealWithAppearanceOptions ```javascript // Get the samples from http://www.adobe.com/go/pdftoolsapi_node_sample // Run the sample: -// node src/electronicseal/electronic-seal.js - -const PDFServicesSdk = require('@adobe/pdfservices-node-sdk'); - -try { - // Initial setup, create credentials instance. - const credentials = PDFServicesSdk.Credentials - .servicePrincipalCredentialsBuilder() - .withClientId("PDF_SERVICES_CLIENT_ID") - .withClientSecret("PDF_SERVICES_CLIENT_SECRET") - .build(); - - // Create an ExecutionContext using credentials - const executionContext = PDFServicesSdk.ExecutionContext.create(credentials); - - const pdfElectronicSeal = PDFServicesSdk.PDFElectronicSeal, - options = pdfElectronicSeal.options; - - //Get the input document to perform the sealing operation - const sourceFile = PDFServicesSdk.FileRef.createFromLocalFile('resources/sampleInvoice.pdf'), - - //Get the background seal image for signature , if required. - sealImageFile = PDFServicesSdk.FileRef.createFromLocalFile('resources/sampleSealImage.png'); - - //Create AppearanceOptions and add the required signature appearance items - appearanceOptions = new options.AppearanceOptions(); - appearanceOptions.addItem(options.AppearanceOptions.AppearanceItem.DATE); - appearanceOptions.addItem(options.AppearanceOptions.AppearanceItem.SEAL_IMAGE); - appearanceOptions.addItem(options.AppearanceOptions.AppearanceItem.NAME); - appearanceOptions.addItem(options.AppearanceOptions.AppearanceItem.LABELS); - appearanceOptions.addItem(options.AppearanceOptions.AppearanceItem.DISTINGUISHED_NAME); - - // Set the Seal Field Name to be created in input PDF document. - sealFieldName = "Signature1"; - - // Set the page number in input document for applying seal. - sealPageNumber = 1; - - // Set if seal should be visible or invisible. - sealVisible = true; - - //Create FieldLocation instance and set the coordinates for applying signature - fieldLocation = new options.FieldLocation(150,250,350,200); - - //Create FieldOptions instance with required details. - fieldOptions = new options.FieldOptions.Builder(sealFieldName) - .setFieldLocation(fieldLocation) - .setPageNumber(sealPageNumber) - .setVisible(sealVisible) - .build(); - - //Set the name of TSP Provider being used. - providerName = ""; - - //Set the access token to be used to access TSP provider hosted APIs. - accessToken = ""; - - //Set the credential ID. - credentialID = ""; - - //Set the PIN generated while creating credentials. - pin = ""; - - //Create CSCAuthContext instance using access token and token type. - cscAuthContext = new options.CSCAuthContext(accessToken, "Bearer"); - - //Create CertificateCredentials instance with required certificate details. - certificateCredentials = options.CertificateCredentials.cscCredentialBuilder() - .withProviderName(providerName) - .withCredentialID(credentialID) - .withPin(pin) - .withCSCAuthContext(cscAuthContext) - .build(); - - //Create SealOptions instance with sealing parameters. - sealOptions = new options.SealOptions.Builder(certificateCredentials, fieldOptions) - .withAppearanceOptions(appearanceOptions) - .build() - - //Create the PDFElectronicSealOperation instance using the SealOptions instance - const pdfElectronicSealOperation = pdfElectronicSeal.Operation.createNew(sealOptions); - - //Set the input source file for PDFElectronicSealOperation instance - pdfElectronicSealOperation.setInput(sourceFile); - - //Set the optional input seal image for PDFElectronicSealOperation instance - pdfElectronicSealOperation.setSealImage(sealImageFile); - - // Execute the operation and Save the result to the specified location. - pdfElectronicSealOperation.execute(executionContext) - .then(result => result.saveAsFile("output/sealedOutput.pdf")) - .catch(err => { - if(err instanceof PDFServicesSdk.Error.ServiceApiError - || err instanceof PDFServicesSdk.Error.ServiceUsageError) { - console.log('Exception encountered while executing operation', err); - } else { - console.log('Exception encountered while executing operation', err); - } - }); - +// node src/electronicseal/electronic-seal-with-appearance-options.js + +const { + ServicePrincipalCredentials, + PDFServices, + MimeType, + FieldLocation, + FieldOptions, + CSCAuthContext, + CSCCredential, + PDFElectronicSealParams, + PDFElectronicSealJob, + PDFElectronicSealResult, + AppearanceOptions, + AppearanceItem, + SDKError, + ServiceUsageError, + ServiceApiError, DocumentLevelPermission +} = require("@adobe/pdfservices-node-sdk"); +const fs = require("fs"); + +(async () => { + + let sourceFileReadStream; + let sealImageReadStream; + try { + // Initial setup, create credentials instance + const credentials = new ServicePrincipalCredentials({ + clientId: process.env.PDF_SERVICES_CLIENT_ID, + clientSecret: process.env.PDF_SERVICES_CLIENT_SECRET + }); + + // Creates a PDF Services instance + const pdfServices = new PDFServices({credentials}); + + // Creates an asset(s) from source file(s) and upload + sourceFileReadStream = fs.createReadStream("./sampleInvoice.pdf") + sealImageReadStream = fs.createReadStream("./sampleSealImage.png"); + const [sourceFileAsset, sealImageAsset] = await pdfServices.uploadAssets({ + streamAssets: [{ + readStream: sourceFileReadStream, + mimeType: MimeType.PDF + }, { + readStream: sealImageReadStream, + mimeType: MimeType.PNG + }] + }); + + // Set the document level permission to be applied for output document + const documentLevelPermission = DocumentLevelPermission.FORM_FILLING; + + // Create AppearanceOptions and add the required signature appearance items + const sealAppearanceOptions = new AppearanceOptions({ + items: [ + AppearanceItem.DATE, + AppearanceItem.SEAL_IMAGE, + AppearanceItem.NAME, + AppearanceItem.LABELS, + AppearanceItem.DISTINGUISHED_NAME + ] + }); + + // Set the Seal Field Name to be created in input PDF document + const sealFieldName = "Signature1"; + + // Set the page number in input document for applying seal + const sealPageNumber = 1; + + // Set if seal should be visible or invisible + const sealVisible = true; + + // Create FieldLocation instance and set the coordinates for applying signature + const fieldLocation = new FieldLocation({ + left: 150, + top: 250, + right: 350, + bottom: 200 + }); + + // Create FieldOptions instance with required details + const sealFieldOptions = new FieldOptions({ + visible: sealVisible, + location: fieldLocation, + fieldName: sealFieldName, + pageNumber: sealPageNumber, + }); + + // Set the name of TSP Provider being used + const providerName = ""; + + // Set the access token to be used to access TSP provider hosted APIs + const accessToken = ""; + + // Set the credential ID + const credentialId = ""; + + // Set the PIN generated while creating credentials + const pin = ""; + + // Create CSCAuthContext instance using access token and token type + const authorizationContext = new CSCAuthContext({ + accessToken, + tokenType: "Bearer" + }); + + // Create CertificateCredentials instance with required certificate details + const certificateCredentials = new CSCCredential({ + providerName, + credentialId, + pin, + authorizationContext, + }); + + // Create parameters for the job + const params = new PDFElectronicSealParams({ + documentLevelPermission + certificateCredentials, + sealFieldOptions, + sealAppearanceOptions + }); + + // Creates a new job instance + const job = new PDFElectronicSealJob({ + inputAsset: sourceFileAsset, + sealImageAsset, + params, + }); + + // Submit the job and get the job result + const pollingURL = await pdfServices.submit({job}); + const pdfServicesResponse = await pdfServices.getJobResult({ + pollingURL, + resultType: PDFElectronicSealResult + }); + + // Get content from the resulting asset(s) + const resultAsset = pdfServicesResponse.result.asset; + const streamAsset = await pdfServices.getContent({asset: resultAsset}); + + // Creates a write stream and copy stream asset's content to it + const outputFilePath = "./sealedOutput.pdf"; + console.log(`Saving asset at ${outputFilePath}`); + + const writeStream = fs.createWriteStream(outputFilePath); + streamAsset.readStream.pipe(writeStream); } catch (err) { - console.log('Exception encountered while executing operation', err); -} + if (err instanceof SDKError || err instanceof ServiceUsageError || err instanceof ServiceApiError) { + console.log("Exception encountered while executing operation", err); + } else { + console.log("Exception encountered while executing operation", err); + } + } finally { + sourceFileReadStream?.destroy(); + sealImageReadStream?.destroy(); + } +})(); ``` #### REST API @@ -1072,6 +1173,171 @@ public class ElectronicSealWithTimeStampAuthority { ``` +#### Node JS + +```javascript +// Get the samples from http://www.adobe.com/go/pdftoolsapi_node_sample +// Run the sample: +// node src/electronicseal/electronic-seal-with-stamp-authority.js + +const { + ServicePrincipalCredentials, + PDFServices, + MimeType, + FieldLocation, + FieldOptions, + CSCAuthContext, + CSCCredential, + PDFElectronicSealParams, + PDFElectronicSealJob, + PDFElectronicSealResult, + DocumentLevelPermission, + TSABasicAuthCredentials, + RFC3161TSAOptions, + SDKError, + ServiceUsageError, + ServiceApiError, +} = require("@adobe/pdfservices-node-sdk"); +const fs = require("fs"); + +(async () => { + + let sourceFileReadStream; + let sealImageReadStream; + try { + // Initial setup, create credentials instance + const credentials = new ServicePrincipalCredentials({ + clientId: process.env.PDF_SERVICES_CLIENT_ID, + clientSecret: process.env.PDF_SERVICES_CLIENT_SECRET + }); + + // Creates a PDF Services instance + const pdfServices = new PDFServices({credentials}); + + // Creates an asset(s) from source file(s) and upload + sourceFileReadStream = fs.createReadStream("./sampleInvoice.pdf") + sealImageReadStream = fs.createReadStream("./sampleSealImage.png"); + const [sourceFileAsset, sealImageAsset] = await pdfServices.uploadAssets({ + streamAssets: [{ + readStream: sourceFileReadStream, + mimeType: MimeType.PDF + }, { + readStream: sealImageReadStream, + mimeType: MimeType.PNG + }] + }); + + // Set the document level permission to be applied for output document + const documentLevelPermission = DocumentLevelPermission.FORM_FILLING; + + // Set the Seal Field Name to be created in input PDF document + const sealFieldName = "Signature1"; + + // Set the page number in input document for applying seal + const sealPageNumber = 1; + + // Set if seal should be visible or invisible + const sealVisible = true; + + // Create FieldLocation instance and set the coordinates for applying signature + const fieldLocation = new FieldLocation({ + left: 150, + top: 250, + right: 350, + bottom: 200 + }); + + // Create FieldOptions instance with required details + const sealFieldOptions = new FieldOptions({ + visible: sealVisible, + location: fieldLocation, + fieldName: sealFieldName, + pageNumber: sealPageNumber, + }); + + // Set the name of TSP Provider being used + const providerName = ""; + + // Set the access token to be used to access TSP provider hosted APIs + const accessToken = ""; + + // Set the credential ID + const credentialId = ""; + + // Set the PIN generated while creating credentials + const pin = ""; + + // Create CSCAuthContext instance using access token and token type + const authorizationContext = new CSCAuthContext({ + accessToken, + tokenType: "Bearer" + }); + + // Create CertificateCredentials instance with required certificate details + const certificateCredentials = new CSCCredential({ + providerName, + credentialId, + pin, + authorizationContext, + }); + + // Create TSABasicAuthCredentials using username and password + const tsaBasicAuthCredentials = new TSABasicAuthCredentials({ + username: "", + password: "" + }); + + // Set the Time Stamp Authority Options using url and TSA Auth credentials + const tsaOptions = new RFC3161TSAOptions({ + url: "", + credentialAuthParameters: tsaBasicAuthCredentials + }); + + // Create parameters for the job + const params = new PDFElectronicSealParams({ + documentLevelPermission, + certificateCredentials, + sealFieldOptions, + tsaOptions + }); + + // Creates a new job instance + const job = new PDFElectronicSealJob({ + inputAsset: sourceFileAsset, + sealImageAsset, + params, + }); + + // Submit the job and get the job result + const pollingURL = await pdfServices.submit({job}); + const pdfServicesResponse = await pdfServices.getJobResult({ + pollingURL, + resultType: PDFElectronicSealResult + }); + + // Get content from the resulting asset(s) + const resultAsset = pdfServicesResponse.result.asset; + const streamAsset = await pdfServices.getContent({asset: resultAsset}); + + // Creates a write stream and copy stream asset's content to it + const outputFilePath = "./sealedOutput.pdf"; + console.log(`Saving asset at ${outputFilePath}`); + + const writeStream = fs.createWriteStream(outputFilePath); + streamAsset.readStream.pipe(writeStream); + } catch (err) { + if (err instanceof SDKError || err instanceof ServiceUsageError || err instanceof ServiceApiError) { + console.log("Exception encountered while executing operation", err); + } else { + console.log("Exception encountered while executing operation", err); + } + } finally { + sourceFileReadStream?.destroy(); + sealImageReadStream?.destroy(); + } +})(); +``` + #### Rest API ```javascript curl --location --request POST 'https://pdf-services.adobe.io/operation/electronicseal' \ diff --git a/src/pages/overview/pdf-electronic-seal-api/howtos/index.md b/src/pages/overview/pdf-electronic-seal-api/howtos/index.md index 8330786f7..904465193 100644 --- a/src/pages/overview/pdf-electronic-seal-api/howtos/index.md +++ b/src/pages/overview/pdf-electronic-seal-api/howtos/index.md @@ -86,14 +86,8 @@ ClientConfig clientConfig = ClientConfig.ConfigBuilder() Available properties: -- **connectTimeout**: Default: 10000. The maximum allowed time in - milliseconds for creating an initial HTTPS connection. -- **readTimeout**: Default: 10000. The maximum allowed time in - milliseconds between two successive HTTP response packets. -- **processingTimeout**: Default: 600000. The maximum allowed time - in milliseconds for processing the documents. Any operation taking more time than the specified `processingTimeout` will result in an operation timeout exception. - - **Note :** It is advisable to set the `processingTimeout` to higher values for processing large files. - +- **timeout**: Default: 10000. The maximum allowed time in milliseconds before the request times out. If the request + takes longer than `timeout`, the request will be aborted. Override the timeout properties via a custom `ClientConfig` class: @@ -102,9 +96,7 @@ Override the timeout properties via a custom `ClientConfig` class: ### ```javascript -const clientConfig = PDFServicesSdk.ClientConfig - .clientConfigBuilder() - .withConnectTimeout(15000) - .withReadTimeout(15000) - .build(); -``` +const clientConfig = new ClientConfig({ + timeout: 15000 +}) +``` \ No newline at end of file diff --git a/src/pages/overview/pdf-electronic-seal-api/quickstarts/nodejs/index.md b/src/pages/overview/pdf-electronic-seal-api/quickstarts/nodejs/index.md index e5a3d1f03..f6083bedc 100644 --- a/src/pages/overview/pdf-electronic-seal-api/quickstarts/nodejs/index.md +++ b/src/pages/overview/pdf-electronic-seal-api/quickstarts/nodejs/index.md @@ -10,7 +10,7 @@ To get started using Adobe PDF Electronic Seal API, let's walk through a simple To complete this guide, you will need: -* [Node.js](https://nodejs.org) - Node.js version 14.0 or higher is required. +* [Node.js](https://nodejs.org) - Node.js version 18.0 or higher is required. * An Adobe ID. If you do not have one, the credential setup will walk you through creating one. * A way to edit code. No specific editor is required for this guide. @@ -63,12 +63,26 @@ Now you're ready to begin coding. 1) We'll begin by including our required dependencies: ```javascript -const PDFServicesSdk = require('@adobe/pdfservices-node-sdk'); +const { + ServicePrincipalCredentials, + PDFServices, + MimeType, + FieldLocation, + FieldOptions, + CSCAuthContext, + CSCCredential, + PDFElectronicSealParams, + PDFElectronicSealJob, + PDFElectronicSealResult, + AppearanceOptions, + AppearanceItem, + SDKError, + ServiceUsageError, + ServiceApiError, DocumentLevelPermission +} = require("@adobe/pdfservices-node-sdk"); +const fs = require("fs"); ``` -This line includes the Adobe PDF Services Node.js SDK - - 2) Set the environment variables `PDF_SERVICES_CLIENT_ID` and `PDF_SERVICES_CLIENT_SECRET` by running the following commands and replacing placeholders `YOUR CLIENT ID` and `YOUR CLIENT SECRET` with the credentials present in `pdfservices-api-credentials.json` file: - **Windows:** - `set PDF_SERVICES_CLIENT_ID=` @@ -82,262 +96,312 @@ This line includes the Adobe PDF Services Node.js SDK 3) Next, we setup the SDK to use our credentials. ```javascript - // Initial setup, create credentials instance. -const credentials = PDFServicesSdk.Credentials - .servicePrincipalCredentialsBuilder() - .withClientId(process.env.PDF_SERVICES_CLIENT_ID) - .withClientSecret(process.env.PDF_SERVICES_CLIENT_SECRET) - .build(); - -// Create an ExecutionContext using credentials -const executionContext = PDFServicesSdk.ExecutionContext.create(credentials); +// Initial setup, create credentials instance +const credentials = new ServicePrincipalCredentials({ + clientId: process.env.PDF_SERVICES_CLIENT_ID, + clientSecret: process.env.PDF_SERVICES_CLIENT_SECRET +}); + +// Creates a PDF Services instance +const pdfServices = new PDFServices({credentials}); ``` -This code both points to the credentials downloaded previously and sets up an execution context object that will be used later. - -4) Let's define the electronic seal and options object to be used later: +4) Now, let's upload the assets: ```javascript -const pdfElectronicSeal = PDFServicesSdk.PDFElectronicSeal, - options = pdfElectronicSeal.options; - +const [sourceFileAsset, sealImageAsset] = await pdfServices.uploadAssets({ + streamAssets: [{ + readStream: sourceFileReadStream, + mimeType: MimeType.PDF + }, { + readStream: sealImageReadStream, + mimeType: MimeType.PNG + }] +}); ``` -5) Now, let's define our input fields: +5) Now, we will define the document level permission: ```javascript -//Get the input document to perform the sealing operation -const sourceFile = PDFServicesSdk.FileRef.createFromLocalFile('./sampleInvoice.pdf'), - -//Get the background seal image for signature , if required. -sealImageFile = PDFServicesSdk.FileRef.createFromLocalFile('./sampleSealImage.png'); - +// Set the document level permission to be applied for output document +const documentLevelPermission = DocumentLevelPermission.FORM_FILLING; ``` 6) Now, we will define seal field options: ```javascript -//Create AppearanceOptions and add the required signature appearance items -appearanceOptions = new options.AppearanceOptions(); -appearanceOptions.addItem(options.AppearanceOptions.AppearanceItem.DATE); -appearanceOptions.addItem(options.AppearanceOptions.AppearanceItem.SEAL_IMAGE); -appearanceOptions.addItem(options.AppearanceOptions.AppearanceItem.NAME); -appearanceOptions.addItem(options.AppearanceOptions.AppearanceItem.LABELS); -appearanceOptions.addItem(options.AppearanceOptions.AppearanceItem.DISTINGUISHED_NAME); - -// Set the Seal Field Name to be created in input PDF document. -sealFieldName = "Signature1"; - -// Set the page number in input document for applying seal. -sealPageNumber = 1; - -// Set if seal should be visible or invisible. -sealVisible = true; - -//Create FieldLocation instance and set the coordinates for applying signature -fieldLocation = new options.FieldLocation(150,250,350,200); - -//Create FieldOptions instance with required details. -fieldOptions = new options.FieldOptions.Builder(sealFieldName) - .setFieldLocation(fieldLocation) - .setPageNumber(sealPageNumber) - .setVisible(sealVisible) - .build(); +// Create AppearanceOptions and add the required signature appearance items +const sealAppearanceOptions = new AppearanceOptions({ + items: [ + AppearanceItem.DATE, + AppearanceItem.SEAL_IMAGE, + AppearanceItem.NAME, + AppearanceItem.LABELS, + AppearanceItem.DISTINGUISHED_NAME + ] +}); + +// Set the Seal Field Name to be created in input PDF document +const sealFieldName = "Signature1"; + +// Set the page number in input document for applying seal +const sealPageNumber = 1; + +// Set if seal should be visible or invisible +const sealVisible = true; + +// Create FieldLocation instance and set the coordinates for applying signature +const fieldLocation = new FieldLocation({ + left: 150, + top: 250, + right: 350, + bottom: 200 +}); + +// Create FieldOptions instance with required details +const sealFieldOptions = new FieldOptions({ + visible: sealVisible, + location: fieldLocation, + fieldName: sealFieldName, + pageNumber: sealPageNumber, +}); ``` 7) Next, we create a CSC Certificate Credentials instance: ```javascript -//Set the name of TSP Provider being used. -providerName = ""; - -//Set the access token to be used to access TSP provider hosted APIs. -accessToken = ""; +// Set the name of TSP Provider being used +const providerName = ""; + +// Set the access token to be used to access TSP provider hosted APIs +const accessToken = ""; + +// Set the credential ID +const credentialId = ""; + +// Set the PIN generated while creating credentials +const pin = ""; + +// Create CSCAuthContext instance using access token and token type +const authorizationContext = new CSCAuthContext({ + accessToken, + tokenType: "Bearer" +}); + +// Create CertificateCredentials instance with required certificate details +const certificateCredentials = new CSCCredential({ + providerName, + credentialId, + pin, + authorizationContext, +}); +``` -//Set the credential ID. -credentialID = ""; +8) Now, let's create the job with seal parameters using certificate credentials and field options and set the seal image asset: -//Set the PIN generated while creating credentials. -pin = ""; +```javascript +// Create parameters for the job +const params = new PDFElectronicSealParams({ + documentLevelPermission + certificateCredentials, + sealFieldOptions, + sealAppearanceOptions +}); + +// Creates a new job instance +const job = new PDFElectronicSealJob({ + inputAsset: sourceFileAsset, + sealImageAsset, + params, +}); +``` -//Create CSCAuthContext instance using access token and token type. -cscAuthContext = new options.CSCAuthContext(accessToken, "Bearer"); +This set of code defines what we're doing (an Electronic Seal operation), +it defines parameters for the seal job and sets input seal image asset. -//Create CertificateCredentials instance with required certificate details. -certificateCredentials = options.CertificateCredentials.cscCredentialBuilder() - .withProviderName(providerName) - .withCredentialID(credentialID) - .withPin(pin) - .withCSCAuthContext(cscAuthContext) - .build(); +9) The next code block submits the job and gets the job result: +```javascript +// Submit the job and get the job result +const pollingURL = await pdfServices.submit({job}); +const pdfServicesResponse = await pdfServices.getJobResult({ + pollingURL, + resultType: PDFElectronicSealResult +}); + +// Get content from the resulting asset(s) +const resultAsset = pdfServicesResponse.result.asset; +const streamAsset = await pdfServices.getContent({asset: resultAsset}); ``` -8) Now, let's create the seal options with certificate credentials and field options: +10) The next code block saves the result at the specified location: ```javascript - //Create SealOptions instance with sealing parameters. -sealOptions = new options.SealOptions.Builder(certificateCredentials, fieldOptions) - .withAppearanceOptions(appearanceOptions) - .build() -``` +// Creates a write stream and copy stream asset's content to it +const outputFilePath = "./sealedOutput.pdf"; +console.log(`Saving asset at ${outputFilePath}`); +const writeStream = fs.createWriteStream(outputFilePath); +streamAsset.readStream.pipe(writeStream); +``` -9) Now, let's create the operation: +Here's the complete application (`electronic-seal.js`): ```javascript -//Create the PDFElectronicSealOperation instance using the SealOptions instance -const pdfElectronicSealOperation = pdfElectronicSeal.Operation.createNew(sealOptions); +const { + ServicePrincipalCredentials, + PDFServices, + MimeType, + FieldLocation, + FieldOptions, + CSCAuthContext, + CSCCredential, + PDFElectronicSealParams, + PDFElectronicSealJob, + PDFElectronicSealResult, + AppearanceOptions, + AppearanceItem, + SDKError, + ServiceUsageError, + ServiceApiError, DocumentLevelPermission +} = require("@adobe/pdfservices-node-sdk"); +const fs = require("fs"); + +(async () => { + + let sourceFileReadStream; + let sealImageReadStream; + try { + // Initial setup, create credentials instance + const credentials = new ServicePrincipalCredentials({ + clientId: process.env.PDF_SERVICES_CLIENT_ID, + clientSecret: process.env.PDF_SERVICES_CLIENT_SECRET + }); -//Set the input source file for PDFElectronicSealOperation instance -pdfElectronicSealOperation.setInput(sourceFile); + // Creates a PDF Services instance + const pdfServices = new PDFServices({credentials}); + + // Creates an asset(s) from source file(s) and upload + sourceFileReadStream = fs.createReadStream("./sampleInvoice.pdf") + sealImageReadStream = fs.createReadStream("./sampleSealImage.png"); + const [sourceFileAsset, sealImageAsset] = await pdfServices.uploadAssets({ + streamAssets: [{ + readStream: sourceFileReadStream, + mimeType: MimeType.PDF + }, { + readStream: sealImageReadStream, + mimeType: MimeType.PNG + }] + }); -//Set the optional input seal image for PDFElectronicSealOperation instance -pdfElectronicSealOperation.setSealImage(sealImageFile); + // Set the document level permission to be applied for output document + const documentLevelPermission = DocumentLevelPermission.FORM_FILLING; + + // Create AppearanceOptions and add the required signature appearance items + const sealAppearanceOptions = new AppearanceOptions({ + items: [ + AppearanceItem.DATE, + AppearanceItem.SEAL_IMAGE, + AppearanceItem.NAME, + AppearanceItem.LABELS, + AppearanceItem.DISTINGUISHED_NAME + ] + }); -``` -This code creates a seal operation using sealOptions, input source file and input seal image. + // Set the Seal Field Name to be created in input PDF document + const sealFieldName = "Signature1"; -10) Let's execute this seal operation: + // Set the page number in input document for applying seal + const sealPageNumber = 1; -```javascript -// Execute the operation and Save the result to the specified location. -pdfElectronicSealOperation.execute(executionContext) - .then(result => result.saveAsFile("output/sealedOutput.pdf")) - .catch(err => { - if(err instanceof PDFServicesSdk.Error.ServiceApiError - || err instanceof PDFServicesSdk.Error.ServiceUsageError) { - console.log('Exception encountered while executing operation', err); - } else { - console.log('Exception encountered while executing operation', err); - } + // Set if seal should be visible or invisible + const sealVisible = true; + + // Create FieldLocation instance and set the coordinates for applying signature + const fieldLocation = new FieldLocation({ + left: 150, + top: 250, + right: 350, + bottom: 200 }); -``` -Here's the complete application (`electronic-seal.js`): + // Create FieldOptions instance with required details + const sealFieldOptions = new FieldOptions({ + visible: sealVisible, + location: fieldLocation, + fieldName: sealFieldName, + pageNumber: sealPageNumber, + }); -```javascript -/* - * Copyright 2023 Adobe - * All Rights Reserved. - * - * NOTICE: Adobe permits you to use, modify, and distribute this file in - * accordance with the terms of the Adobe license agreement accompanying - * it. If you have received this file from a source other than Adobe, - * then your use, modification, or distribution of it requires the prior - * written permission of Adobe. - */ - -const PDFServicesSdk = require('@adobe/pdfservices-node-sdk'); - -/** - * This sample illustrates how to apply electronic seal over the PDF document using custom appearance options. - * - *

- * To know more about PDF Electronic Seal, please see the <documentation. - *

- * Refer to README.md for instructions on how to run the samples. - */ -try { - // Initial setup, create credentials instance. - const credentials = PDFServicesSdk.Credentials - .servicePrincipalCredentialsBuilder() - .withClientId(process.env.PDF_SERVICES_CLIENT_ID) - .withClientSecret(process.env.PDF_SERVICES_CLIENT_SECRET) - .build(); - - // Create an ExecutionContext using credentials - const executionContext = PDFServicesSdk.ExecutionContext.create(credentials); - - const pdfElectronicSeal = PDFServicesSdk.PDFElectronicSeal, - options = pdfElectronicSeal.options; - - //Get the input document to perform the sealing operation - const sourceFile = PDFServicesSdk.FileRef.createFromLocalFile('./sampleInvoice.pdf'), - - //Get the background seal image for signature , if required. - sealImageFile = PDFServicesSdk.FileRef.createFromLocalFile('./sampleSealImage.png'); - - //Create AppearanceOptions and add the required signature appearance items - appearanceOptions = new options.AppearanceOptions(); - appearanceOptions.addItem(options.AppearanceOptions.AppearanceItem.DATE); - appearanceOptions.addItem(options.AppearanceOptions.AppearanceItem.SEAL_IMAGE); - appearanceOptions.addItem(options.AppearanceOptions.AppearanceItem.NAME); - appearanceOptions.addItem(options.AppearanceOptions.AppearanceItem.LABELS); - appearanceOptions.addItem(options.AppearanceOptions.AppearanceItem.DISTINGUISHED_NAME); - - // Set the Seal Field Name to be created in input PDF document. - sealFieldName = "Signature1"; - - // Set the page number in input document for applying seal. - sealPageNumber = 1; - - // Set if seal should be visible or invisible. - sealVisible = true; - - //Create FieldLocation instance and set the coordinates for applying signature - fieldLocation = new options.FieldLocation(150,250,350,200); - - //Create FieldOptions instance with required details. - fieldOptions = new options.FieldOptions.Builder(sealFieldName) - .setFieldLocation(fieldLocation) - .setPageNumber(sealPageNumber) - .setVisible(sealVisible) - .build(); - - //Set the name of TSP Provider being used. - providerName = ""; - - //Set the access token to be used to access TSP provider hosted APIs. - accessToken = ""; - - //Set the credential ID. - credentialID = ""; - - //Set the PIN generated while creating credentials. - pin = ""; - - //Create CSCAuthContext instance using access token and token type. - cscAuthContext = new options.CSCAuthContext(accessToken, "Bearer"); - - //Create CertificateCredentials instance with required certificate details. - certificateCredentials = options.CertificateCredentials.cscCredentialBuilder() - .withProviderName(providerName) - .withCredentialID(credentialID) - .withPin(pin) - .withCSCAuthContext(cscAuthContext) - .build(); - - //Create SealOptions instance with sealing parameters. - sealOptions = new options.SealOptions.Builder(certificateCredentials, fieldOptions) - .withAppearanceOptions(appearanceOptions) - .build() - - //Create the PDFElectronicSealOperation instance using the SealOptions instance - const pdfElectronicSealOperation = pdfElectronicSeal.Operation.createNew(sealOptions); - - //Set the input source file for PDFElectronicSealOperation instance - pdfElectronicSealOperation.setInput(sourceFile); - - //Set the optional input seal image for PDFElectronicSealOperation instance - pdfElectronicSealOperation.setSealImage(sealImageFile); - - // Execute the operation and Save the result to the specified location. - pdfElectronicSealOperation.execute(executionContext) - .then(result => result.saveAsFile("output/sealedOutput.pdf")) - .catch(err => { - if(err instanceof PDFServicesSdk.Error.ServiceApiError - || err instanceof PDFServicesSdk.Error.ServiceUsageError) { - console.log('Exception encountered while executing operation', err); - } else { - console.log('Exception encountered while executing operation', err); - } - }); - -} catch (err) { - console.log('Exception encountered while executing operation', err); -} + // Set the name of TSP Provider being used + const providerName = ""; + + // Set the access token to be used to access TSP provider hosted APIs + const accessToken = ""; + + // Set the credential ID + const credentialId = ""; + + // Set the PIN generated while creating credentials + const pin = ""; + + // Create CSCAuthContext instance using access token and token type + const authorizationContext = new CSCAuthContext({ + accessToken, + tokenType: "Bearer" + }); + + // Create CertificateCredentials instance with required certificate details + const certificateCredentials = new CSCCredential({ + providerName, + credentialId, + pin, + authorizationContext, + }); + + // Create parameters for the job + const params = new PDFElectronicSealParams({ + documentLevelPermission + certificateCredentials, + sealFieldOptions, + sealAppearanceOptions + }); + + // Creates a new job instance + const job = new PDFElectronicSealJob({ + inputAsset: sourceFileAsset, + sealImageAsset, + params, + }); + + // Submit the job and get the job result + const pollingURL = await pdfServices.submit({job}); + const pdfServicesResponse = await pdfServices.getJobResult({ + pollingURL, + resultType: PDFElectronicSealResult + }); + // Get content from the resulting asset(s) + const resultAsset = pdfServicesResponse.result.asset; + const streamAsset = await pdfServices.getContent({asset: resultAsset}); + + // Creates a write stream and copy stream asset's content to it + const outputFilePath = "./sealedOutput.pdf"; + console.log(`Saving asset at ${outputFilePath}`); + + const writeStream = fs.createWriteStream(outputFilePath); + streamAsset.readStream.pipe(writeStream); + } catch (err) { + if (err instanceof SDKError || err instanceof ServiceUsageError || err instanceof ServiceApiError) { + console.log("Exception encountered while executing operation", err); + } else { + console.log("Exception encountered while executing operation", err); + } + } finally { + sourceFileReadStream?.destroy(); + sealImageReadStream?.destroy(); + } +})(); ``` ## Next Steps diff --git a/src/pages/overview/pdf-extract-api/gettingstarted.md b/src/pages/overview/pdf-extract-api/gettingstarted.md index c8c64521e..302bd261f 100644 --- a/src/pages/overview/pdf-extract-api/gettingstarted.md +++ b/src/pages/overview/pdf-extract-api/gettingstarted.md @@ -5,7 +5,7 @@ title: Getting Started | PDF Accessibility Auto-Tag API | Adobe PDF Services # Getting Started

-PDF Accessibility Auto-Tag API assists in the process of improving accessibility in individual PDFs via auto-tagging, adding document structure tags to the PDF file that are used to read a document's text and presenting it in a way that makes sense to users using assistive technology. The API is accessible through SDKs which help you get up and running quickly. Once you've received your developer credential, download and set up one of the sample projects. After you're familiar with the APIs, leverage the samples in your own server-side code. +The PDF Extract API provides modern cloud-based capabilities for automatically extracting contents from PDF. The API is accessible through SDKs which help you get up and running quickly. Once you've received your developer credential, download and set up one of the sample projects. After you're familiar with the APIs, leverage the samples in your own server-side code.

@@ -472,7 +472,7 @@ After downloading the zip, you can run the samples in the zip directly by settin Running any sample or custom code requires the following steps: -1. Install [Node.js 14.0](https://nodejs.org/en/download/) or higher. +1. Install [Node.js 18.0](https://nodejs.org/en/download/) or higher. diff --git a/src/pages/overview/pdf-extract-api/howtos/extract-api.md b/src/pages/overview/pdf-extract-api/howtos/extract-api.md index 9f103086a..05610e503 100644 --- a/src/pages/overview/pdf-extract-api/howtos/extract-api.md +++ b/src/pages/overview/pdf-extract-api/howtos/extract-api.md @@ -293,48 +293,74 @@ namespace ExtractTextInfoFromPDF // Run the sample: // node src/extractpdf/extract-text-info-from-pdf.js - const PDFServicesSdk = require('@adobe/pdfservices-node-sdk'); - try { - // Initial setup, create credentials instance. - const credentials = PDFServicesSdk.Credentials - .servicePrincipalCredentialsBuilder() - .withClientId("PDF_SERVICES_CLIENT_ID") - .withClientSecret("PDF_SERVICES_CLIENT_SECRET") - .build(); - - // Create an ExecutionContext using credentials - const executionContext = PDFServicesSdk.ExecutionContext.create(credentials); - - // Build extractPDF options - const options = new PDFServicesSdk.ExtractPDF.options.ExtractPdfOptions.Builder() - .addElementsToExtract(PDFServicesSdk.ExtractPDF.options.ExtractElementType.TEXT).build(); - - // Create a new operation instance. - const extractPDFOperation = PDFServicesSdk.ExtractPDF.Operation.createNew(), - input = PDFServicesSdk.FileRef.createFromLocalFile( - 'resources/extractPDFInput.pdf', - PDFServicesSdk.ExtractPDF.SupportedSourceFormat.pdf - ); - - // Set operation input from a source file. - extractPDFOperation.setInput(input); - - // Set options - extractPDFOperation.setOptions(options); - - extractPDFOperation.execute(executionContext) - .then(result => result.saveAsFile('output/ExtractTextInfoFromPDF.zip')) - .catch(err => { - if(err instanceof PDFServicesSdk.Error.ServiceApiError - || err instanceof PDFServicesSdk.Error.ServiceUsageError) { - console.log('Exception encountered while executing operation', err); - } else { - console.log('Exception encountered while executing operation', err); - } - }); - } catch (err) { - console.log('Exception encountered while executing operation', err); - } +const { + ServicePrincipalCredentials, + PDFServices, + MimeType, + ExtractPDFParams, + ExtractElementType, + ExtractPDFJob, + ExtractPDFResult, + SDKError, + ServiceUsageError, + ServiceApiError +} = require("@adobe/pdfservices-node-sdk"); +const fs = require("fs"); + +(async () => { + let readStream; + try { + // Initial setup, create credentials instance + const credentials = new ServicePrincipalCredentials({ + clientId: process.env.PDF_SERVICES_CLIENT_ID, + clientSecret: process.env.PDF_SERVICES_CLIENT_SECRET + }); + + // Creates a PDF Services instance + const pdfServices = new PDFServices({credentials}); + + // Creates an asset(s) from source file(s) and upload + readStream = fs.createReadStream("./extractPDFInput.pdf"); + const inputAsset = await pdfServices.upload({ + readStream, + mimeType: MimeType.PDF + }); + + // Create parameters for the job + const params = new ExtractPDFParams({ + elementsToExtract: [ExtractElementType.TEXT] + }); + + // Creates a new job instance + const job = new ExtractPDFJob({inputAsset, params}); + + // Submit the job and get the job result + const pollingURL = await pdfServices.submit({job}); + const pdfServicesResponse = await pdfServices.getJobResult({ + pollingURL, + resultType: ExtractPDFResult + }); + + // Get content from the resulting asset(s) + const resultAsset = pdfServicesResponse.result.resource; + const streamAsset = await pdfServices.getContent({asset: resultAsset}); + + // Creates a write stream and copy stream asset's content to it + const outputFilePath = "./ExtractTextInfoFromPDF.zip"; + console.log(`Saving asset at ${outputFilePath}`); + + const writeStream = fs.createWriteStream(outputFilePath); + streamAsset.readStream.pipe(writeStream); + } catch (err) { + if (err instanceof SDKError || err instanceof ServiceUsageError || err instanceof ServiceApiError) { + console.log("Exception encountered while executing operation", err); + } else { + console.log("Exception encountered while executing operation", err); + } + } finally { + readStream?.destroy(); + } +})(); ``` #### Python @@ -547,51 +573,74 @@ namespace ExtractTextTableInfoFromPDF // Run the sample: // node src/extractpdf/extract-text-table-info-from-pdf.js +const { + ServicePrincipalCredentials, + PDFServices, + MimeType, + ExtractPDFParams, + ExtractElementType, + ExtractPDFJob, + ExtractPDFResult, + SDKError, + ServiceUsageError, + ServiceApiError +} = require("@adobe/pdfservices-node-sdk"); +const fs = require("fs"); + +(async () => { + let readStream; + try { + // Initial setup, create credentials instance + const credentials = new ServicePrincipalCredentials({ + clientId: process.env.PDF_SERVICES_CLIENT_ID, + clientSecret: process.env.PDF_SERVICES_CLIENT_SECRET + }); - const PDFServicesSdk = require('@adobe/pdfservices-node-sdk'); - try { - // Initial setup, create credentials instance. - const credentials = PDFServicesSdk.Credentials - .servicePrincipalCredentialsBuilder() - .withClientId("PDF_SERVICES_CLIENT_ID") - .withClientSecret("PDF_SERVICES_CLIENT_SECRET") - .build(); - - // Create an ExecutionContext using credentials - const executionContext = PDFServicesSdk.ExecutionContext.create(credentials); - - // Build extractPDF options - const options = new PDFServicesSdk.ExtractPDF.options.ExtractPdfOptions.Builder() - .addElementsToExtract(PDFServicesSdk.ExtractPDF.options.ExtractElementType.TEXT, PDFServicesSdk.ExtractPDF.options.ExtractElementType.TABLES) - .build(); - - // Create a new operation instance. - const extractPDFOperation = PDFServicesSdk.ExtractPDF.Operation.createNew(), - input = PDFServicesSdk.FileRef.createFromLocalFile( - 'resources/extractPDFInput.pdf', - PDFServicesSdk.ExtractPDF.SupportedSourceFormat.pdf - ); - - // Set operation input from a source file. - extractPDFOperation.setInput(input); - - // Set options - extractPDFOperation.setOptions(options); - - extractPDFOperation.execute(executionContext) - .then(result => result.saveAsFile('output/ExtractTextTableInfoFromPDF.zip')) - .catch(err => { - if(err instanceof PDFServicesSdk.Error.ServiceApiError - || err instanceof PDFServicesSdk.Error.ServiceUsageError) { - console.log('Exception encountered while executing operation', err); - } else { - console.log('Exception encountered while executing operation', err); - } - }); - } catch (err) { - console.log('Exception encountered while executing operation', err); - } + // Creates a PDF Services instance + const pdfServices = new PDFServices({credentials}); + + // Creates an asset(s) from source file(s) and upload + readStream = fs.createReadStream("./extractPDFInput.pdf"); + const inputAsset = await pdfServices.upload({ + readStream, + mimeType: MimeType.PDF + }); + + // Create parameters for the job + const params = new ExtractPDFParams({ + elementsToExtract: [ExtractElementType.TEXT, ExtractElementType.TABLES] + }); + + // Creates a new job instance + const job = new ExtractPDFJob({inputAsset, params}); + + // Submit the job and get the job result + const pollingURL = await pdfServices.submit({job}); + const pdfServicesResponse = await pdfServices.getJobResult({ + pollingURL, + resultType: ExtractPDFResult + }); + + // Get content from the resulting asset(s) + const resultAsset = pdfServicesResponse.result.resource; + const streamAsset = await pdfServices.getContent({asset: resultAsset}); + + // Creates a write stream and copy stream asset's content to it + const outputFilePath = "./ExtractTextTableInfoFromPDF.zip"; + console.log(`Saving asset at ${outputFilePath}`); + const writeStream = fs.createWriteStream(outputFilePath); + streamAsset.readStream.pipe(writeStream); + } catch (err) { + if (err instanceof SDKError || err instanceof ServiceUsageError || err instanceof ServiceApiError) { + console.log("Exception encountered while executing operation", err); + } else { + console.log("Exception encountered while executing operation", err); + } + } finally { + readStream?.destroy(); + } +})(); ``` #### Python @@ -808,51 +857,76 @@ namespace ExtractTextTableInfoWithRenditionsFromPDF // Run the sample: // node src/extractpdf/extract-text-table-info-with-tables-renditions-from-pdf.js - const PDFServicesSdk = require('@adobe/pdfservices-node-sdk'); - try { - // Initial setup, create credentials instance. - const credentials = PDFServicesSdk.Credentials - .servicePrincipalCredentialsBuilder() - .withClientId("PDF_SERVICES_CLIENT_ID") - .withClientSecret("PDF_SERVICES_CLIENT_SECRET") - .build(); - - // Create an ExecutionContext using credentials - const executionContext = PDFServicesSdk.ExecutionContext.create(credentials); - - // Build extractPDF options - const options = new PDFServicesSdk.ExtractPDF.options.ExtractPdfOptions.Builder() - .addElementsToExtract(PDFServicesSdk.ExtractPDF.options.ExtractElementType.TEXT, PDFServicesSdk.ExtractPDF.options.ExtractElementType.TABLES) - .addElementsToExtractRenditions(PDFServicesSdk.ExtractPDF.options.ExtractRenditionsElementType.TABLES) - .build(); - - // Create a new operation instance. - const extractPDFOperation = PDFServicesSdk.ExtractPDF.Operation.createNew(), - input = PDFServicesSdk.FileRef.createFromLocalFile( - 'resources/extractPDFInput.pdf', - PDFServicesSdk.ExtractPDF.SupportedSourceFormat.pdf - ); - - // Set operation input from a source file - extractPDFOperation.setInput(input); - - // Set options - extractPDFOperation.setOptions(options); - - extractPDFOperation.execute(executionContext) - .then(result => result.saveAsFile('output/ExtractTextTableInfoWithTablesRenditionsFromPDF.zip')) - .catch(err => { - if(err instanceof PDFServicesSdk.Error.ServiceApiError - || err instanceof PDFServicesSdk.Error.ServiceUsageError) { - console.log('Exception encountered while executing operation', err); - } else { - console.log('Exception encountered while executing operation', err); - } - }); - } catch (err) { - console.log('Exception encountered while executing operation', err); - } - +const { + ServicePrincipalCredentials, + PDFServices, + MimeType, + ExtractPDFParams, + ExtractElementType, + ExtractPDFJob, + ExtractPDFResult, + ExtractRenditionsElementType, + SDKError, + ServiceUsageError, + ServiceApiError +} = require("@adobe/pdfservices-node-sdk"); +const fs = require("fs"); + +(async () => { + let readStream; + try { + // Initial setup, create credentials instance + const credentials = new ServicePrincipalCredentials({ + clientId: process.env.PDF_SERVICES_CLIENT_ID, + clientSecret: process.env.PDF_SERVICES_CLIENT_SECRET + }); + + // Creates a PDF Services instance + const pdfServices = new PDFServices({credentials}); + + // Creates an asset(s) from source file(s) and upload + readStream = fs.createReadStream("./extractPDFInput.pdf"); + const inputAsset = await pdfServices.upload({ + readStream, + mimeType: MimeType.PDF + }); + + // Create parameters for the job + const params = new ExtractPDFParams({ + elementsToExtract: [ExtractElementType.TEXT, ExtractElementType.TABLES], + elementsToExtractRenditions: [ExtractRenditionsElementType.TABLES] + }); + + // Creates a new job instance + const job = new ExtractPDFJob({inputAsset, params}); + + // Submit the job and get the job result + const pollingURL = await pdfServices.submit({job}); + const pdfServicesResponse = await pdfServices.getJobResult({ + pollingURL, + resultType: ExtractPDFResult + }); + + // Get content from the resulting asset(s) + const resultAsset = pdfServicesResponse.result.resource; + const streamAsset = await pdfServices.getContent({asset: resultAsset}); + + // Creates a write stream and copy stream asset's content to it + const outputFilePath = "./ExtractTextTableInfoWithRenditionsFromPDF.zip"; + console.log(`Saving asset at ${outputFilePath}`); + + const writeStream = fs.createWriteStream(outputFilePath); + streamAsset.readStream.pipe(writeStream); + } catch (err) { + if (err instanceof SDKError || err instanceof ServiceUsageError || err instanceof ServiceApiError) { + console.log("Exception encountered while executing operation", err); + } else { + console.log("Exception encountered while executing operation", err); + } + } finally { + readStream?.destroy(); + } +})(); ``` #### Python @@ -1072,50 +1146,76 @@ namespace ExtractTextTableInfoWithFiguresTablesRenditionsFromPDF // Run the sample: // node src/extractpdf/extract-text-table-info-with-figures-tables-renditions-from-pdf.js -const PDFServicesSdk = require('@adobe/pdfservices-node-sdk'); -try { - // Initial setup, create credentials instance. - const credentials = PDFServicesSdk.Credentials - .servicePrincipalCredentialsBuilder() - .withClientId("PDF_SERVICES_CLIENT_ID") - .withClientSecret("PDF_SERVICES_CLIENT_SECRET") - .build(); - - // Create an ExecutionContext using credentials - const executionContext = PDFServicesSdk.ExecutionContext.create(credentials); - - // Build extractPDF options - const options = new PDFServicesSdk.ExtractPDF.options.ExtractPdfOptions.Builder() - .addElementsToExtract(PDFServicesSdk.ExtractPDF.options.ExtractElementType.TEXT, PDFServicesSdk.ExtractPDF.options.ExtractElementType.TABLES) - .addElementsToExtractRenditions(PDFServicesSdk.ExtractPDF.options.ExtractRenditionsElementType.FIGURES, PDFServicesSdk.ExtractPDF.options.ExtractRenditionsElementType.TABLES) - .build(); - - // Create a new operation instance. - const extractPDFOperation = PDFServicesSdk.ExtractPDF.Operation.createNew(), - input = PDFServicesSdk.FileRef.createFromLocalFile( - 'resources/extractPDFInput.pdf', - PDFServicesSdk.ExtractPDF.SupportedSourceFormat.pdf - ); - - // Set operation input from a source file - extractPDFOperation.setInput(input); - - // Set options - extractPDFOperation.setOptions(options); - - extractPDFOperation.execute(executionContext) - .then(result => result.saveAsFile('output/ExtractTextTableWithFigureTableRendition.zip')) - .catch(err => { - if(err instanceof PDFServicesSdk.Error.ServiceApiError - || err instanceof PDFServicesSdk.Error.ServiceUsageError) { - console.log('Exception encountered while executing operation', err); - } else { - console.log('Exception encountered while executing operation', err); - } +const { + ServicePrincipalCredentials, + PDFServices, + MimeType, + ExtractPDFParams, + ExtractElementType, + ExtractPDFJob, + ExtractPDFResult, + ExtractRenditionsElementType, + SDKError, + ServiceUsageError, + ServiceApiError +} = require("@adobe/pdfservices-node-sdk"); +const fs = require("fs"); + +(async () => { + let readStream; + try { + // Initial setup, create credentials instance + const credentials = new ServicePrincipalCredentials({ + clientId: process.env.PDF_SERVICES_CLIENT_ID, + clientSecret: process.env.PDF_SERVICES_CLIENT_SECRET }); -} catch (err) { - console.log('Exception encountered while executing operation', err); -} + + // Creates a PDF Services instance + const pdfServices = new PDFServices({credentials}); + + // Creates an asset(s) from source file(s) and upload + readStream = fs.createReadStream("./extractPDFInput.pdf"); + const inputAsset = await pdfServices.upload({ + readStream, + mimeType: MimeType.PDF + }); + + // Create parameters for the job + const params = new ExtractPDFParams({ + elementsToExtract: [ExtractElementType.TEXT, ExtractElementType.TABLES], + elementsToExtractRenditions: [ExtractRenditionsElementType.FIGURES, ExtractRenditionsElementType.TABLES] + }); + + // Creates a new job instance + const job = new ExtractPDFJob({inputAsset, params}); + + // Submit the job and get the job result + const pollingURL = await pdfServices.submit({job}); + const pdfServicesResponse = await pdfServices.getJobResult({ + pollingURL, + resultType: ExtractPDFResult + }); + + // Get content from the resulting asset(s) + const resultAsset = pdfServicesResponse.result.resource; + const streamAsset = await pdfServices.getContent({asset: resultAsset}); + + // Creates a write stream and copy stream asset's content to it + const outputFilePath = "./ExtractTextTableWithFigureTableRendition.zip"; + console.log(`Saving asset at ${outputFilePath}`); + + const writeStream = fs.createWriteStream(outputFilePath); + streamAsset.readStream.pipe(writeStream); + } catch (err) { + if (err instanceof SDKError || err instanceof ServiceUsageError || err instanceof ServiceApiError) { + console.log("Exception encountered while executing operation", err); + } else { + console.log("Exception encountered while executing operation", err); + } + } finally { + readStream?.destroy(); + } +})(); ``` #### Python @@ -1336,50 +1436,75 @@ namespace ExtractTextTableInfoWithCharBoundsFromPDF // Run the sample: // node src/extractpdf/extract-text-table-info-with-char-bounds-from-pdf.js - const PDFServicesSdk = require('@adobe/pdfservices-node-sdk'); - try { - // Initial setup, create credentials instance. - const credentials = PDFServicesSdk.Credentials - .servicePrincipalCredentialsBuilder() - .withClientId("PDF_SERVICES_CLIENT_ID") - .withClientSecret("PDF_SERVICES_CLIENT_SECRET") - .build(); - - // Create an ExecutionContext using credentials - const executionContext = PDFServicesSdk.ExecutionContext.create(credentials); - - // Build extractPDF options - const options = new PDFServicesSdk.ExtractPDF.options.ExtractPdfOptions.Builder() - .addElementsToExtract(PDFServicesSdk.ExtractPDF.options.ExtractElementType.TEXT, PDFServicesSdk.ExtractPDF.options.ExtractElementType.TABLES) - .addCharInfo(true) - .build(); - - // Create a new operation instance. - const extractPDFOperation = PDFServicesSdk.ExtractPDF.Operation.createNew(), - input = PDFServicesSdk.FileRef.createFromLocalFile( - 'resources/extractPDFInput.pdf', - PDFServicesSdk.ExtractPDF.SupportedSourceFormat.pdf - ); - - // Set operation input from a source file. - extractPDFOperation.setInput(input); - - // Set options - extractPDFOperation.setOptions(options); - - extractPDFOperation.execute(executionContext) - .then(result => result.saveAsFile('output/ExtractTextTableInfoWithCharBoundsFromPDF.zip')) - .catch(err => { - if(err instanceof PDFServicesSdk.Error.ServiceApiError - || err instanceof PDFServicesSdk.Error.ServiceUsageError) { - console.log('Exception encountered while executing operation', err); - } else { - console.log('Exception encountered while executing operation', err); - } - }); - } catch (err) { - console.log('Exception encountered while executing operation', err); - } +const { + ServicePrincipalCredentials, + PDFServices, + MimeType, + ExtractPDFParams, + ExtractElementType, + ExtractPDFJob, + ExtractPDFResult, + SDKError, + ServiceUsageError, + ServiceApiError +} = require("@adobe/pdfservices-node-sdk"); +const fs = require("fs"); + +(async () => { + let readStream; + try { + // Initial setup, create credentials instance + const credentials = new ServicePrincipalCredentials({ + clientId: process.env.PDF_SERVICES_CLIENT_ID, + clientSecret: process.env.PDF_SERVICES_CLIENT_SECRET + }); + + // Creates a PDF Services instance + const pdfServices = new PDFServices({credentials}); + + // Creates an asset(s) from source file(s) and upload + readStream = fs.createReadStream("./extractPDFInput.pdf"); + const inputAsset = await pdfServices.upload({ + readStream, + mimeType: MimeType.PDF + }); + + // Create parameters for the job + const params = new ExtractPDFParams({ + elementsToExtract: [ExtractElementType.TEXT, ExtractElementType.TABLES], + addCharInfo: true + }); + + // Creates a new job instance + const job = new ExtractPDFJob({inputAsset, params}); + + // Submit the job and get the job result + const pollingURL = await pdfServices.submit({job}); + const pdfServicesResponse = await pdfServices.getJobResult({ + pollingURL, + resultType: ExtractPDFResult + }); + + // Get content from the resulting asset(s) + const resultAsset = pdfServicesResponse.result.resource; + const streamAsset = await pdfServices.getContent({asset: resultAsset}); + + // Creates a write stream and copy stream asset's content to it + const outputFilePath = "./ExtractTextTableInfoWithCharBoundsFromPDF.zip"; + console.log(`Saving asset at ${outputFilePath}`); + + const writeStream = fs.createWriteStream(outputFilePath); + streamAsset.readStream.pipe(writeStream); + } catch (err) { + if (err instanceof SDKError || err instanceof ServiceUsageError || err instanceof ServiceApiError) { + console.log("Exception encountered while executing operation", err); + } else { + console.log("Exception encountered while executing operation", err); + } + } finally { + readStream?.destroy(); + } +})(); ``` #### Python @@ -1601,53 +1726,80 @@ namespace ExtractTextTableInfoWithTableStructureFromPDF ```javascript // Get the samples from http://www.adobe.com/go/pdftoolsapi_node_sample // Run the sample: -// node src/extractpdf/extract-text-table-info-with-tables-renditions-from-pdf.js - - const PDFServicesSdk = require('@adobe/pdfservices-node-sdk'); +// node src/extractpdf/extract-text-table-info-with-tables-structure-from-pdf.js + +const { + ServicePrincipalCredentials, + PDFServices, + MimeType, + ExtractPDFParams, + ExtractElementType, + ExtractPDFJob, + ExtractPDFResult, + ExtractRenditionsElementType, + TableStructureType, + SDKError, + ServiceUsageError, + ServiceApiError +} = require("@adobe/pdfservices-node-sdk"); +const fs = require("fs"); + +(async () => { + let readStream; try { - // Initial setup, create credentials instance. - const credentials = PDFServicesSdk.Credentials - .servicePrincipalCredentialsBuilder() - .withClientId("PDF_SERVICES_CLIENT_ID") - .withClientSecret("PDF_SERVICES_CLIENT_SECRET") - .build(); - - // Create an ExecutionContext using credentials - const executionContext = PDFServicesSdk.ExecutionContext.create(credentials); - - // Build extractPDF options - const options = new PDFServicesSdk.ExtractPDF.options.ExtractPdfOptions.Builder() - .addElementsToExtract(PDFServicesSdk.ExtractPDF.options.ExtractElementType.TEXT, PDFServicesSdk.ExtractPDF.options.ExtractElementType.TABLES) - .addElementsToExtractRenditions(PDFServicesSdk.ExtractPDF.options.ExtractRenditionsElementType.TABLES) - .addTableStructureFormat(PDFServicesSdk.ExtractPDF.options.TableStructureType.CSV) - .build(); - - // Create a new operation instance. - const extractPDFOperation = PDFServicesSdk.ExtractPDF.Operation.createNew(), - input = PDFServicesSdk.FileRef.createFromLocalFile( - 'resources/extractPDFInput.pdf', - PDFServicesSdk.ExtractPDF.SupportedSourceFormat.pdf - ); - - // Set operation input from a source file. - extractPDFOperation.setInput(input); - - // Set options - extractPDFOperation.setOptions(options); - - extractPDFOperation.execute(executionContext) - .then(result => result.saveAsFile('output/ExtractTextTableWithTableStructure.zip')) - .catch(err => { - if(err instanceof PDFServicesSdk.Error.ServiceApiError - || err instanceof PDFServicesSdk.Error.ServiceUsageError) { - console.log('Exception encountered while executing operation', err); - } else { - console.log('Exception encountered while executing operation', err); - } - }); + // Initial setup, create credentials instance + const credentials = new ServicePrincipalCredentials({ + clientId: process.env.PDF_SERVICES_CLIENT_ID, + clientSecret: process.env.PDF_SERVICES_CLIENT_SECRET + }); + + // Creates a PDF Services instance + const pdfServices = new PDFServices({credentials}); + + // Creates an asset(s) from source file(s) and upload + readStream = fs.createReadStream("./extractPDFInput.pdf"); + const inputAsset = await pdfServices.upload({ + readStream, + mimeType: MimeType.PDF + }); + + // Create parameters for the job + const params = new ExtractPDFParams({ + elementsToExtract: [ExtractElementType.TEXT, ExtractElementType.TABLES], + elementsToExtractRenditions: [ExtractRenditionsElementType.TABLES], + tableStructureType: TableStructureType.CSV + }); + + // Creates a new job instance + const job = new ExtractPDFJob({inputAsset, params}); + + // Submit the job and get the job result + const pollingURL = await pdfServices.submit({job}); + const pdfServicesResponse = await pdfServices.getJobResult({ + pollingURL, + resultType: ExtractPDFResult + }); + + // Get content from the resulting asset(s) + const resultAsset = pdfServicesResponse.result.resource; + const streamAsset = await pdfServices.getContent({asset: resultAsset}); + + // Creates a write stream and copy stream asset's content to it + const outputFilePath = "./ExtractTextTableWithTableStructure.zip"; + console.log(`Saving asset at ${outputFilePath}`); + + const writeStream = fs.createWriteStream(outputFilePath); + streamAsset.readStream.pipe(writeStream); } catch (err) { - console.log('Exception encountered while executing operation', err); + if (err instanceof SDKError || err instanceof ServiceUsageError || err instanceof ServiceApiError) { + console.log("Exception encountered while executing operation", err); + } else { + console.log("Exception encountered while executing operation", err); + } + } finally { + readStream?.destroy(); } +})(); ``` #### Python @@ -1870,51 +2022,75 @@ namespace ExtractTextTableInfoWithStylingFromPDF // Run the sample: // node src/extractpdf/extract-text-table-with-styling-info-from-pdf.js - - const PDFServicesSdk = require('@adobe/pdfservices-node-sdk'); - try { - // Initial setup, create credentials instance. - const credentials = PDFServicesSdk.Credentials - .servicePrincipalCredentialsBuilder() - .withClientId("PDF_SERVICES_CLIENT_ID") - .withClientSecret("PDF_SERVICES_CLIENT_SECRET") - .build(); - - // Create an ExecutionContext using credentials - const executionContext = PDFServicesSdk.ExecutionContext.create(credentials); - - // Build extractPDF options - const options = new PDFServicesSdk.ExtractPDF.options.ExtractPdfOptions.Builder() - .addElementsToExtract(PDFServicesSdk.ExtractPDF.options.ExtractElementType.TEXT, PDFServicesSdk.ExtractPDF.options.ExtractElementType.TABLES) - .getStylingInfo(true) - .build(); - - // Create a new operation instance. - const extractPDFOperation = PDFServicesSdk.ExtractPDF.Operation.createNew(), - input = PDFServicesSdk.FileRef.createFromLocalFile( - 'resources/extractPDFInput.pdf', - PDFServicesSdk.ExtractPDF.SupportedSourceFormat.pdf - ); - - // Set operation input from a source file. - extractPDFOperation.setInput(input); - - // Set options - extractPDFOperation.setOptions(options); - - extractPDFOperation.execute(executionContext) - .then(result => result.saveAsFile('output/ExtractTextTableInfoWithStylingInfoFromPDF.zip')) - .catch(err => { - if(err instanceof PDFServicesSdk.Error.ServiceApiError - || err instanceof PDFServicesSdk.Error.ServiceUsageError) { - console.log('Exception encountered while executing operation', err); - } else { - console.log('Exception encountered while executing operation', err); - } - }); - } catch (err) { - console.log('Exception encountered while executing operation', err); - } +const { + ServicePrincipalCredentials, + PDFServices, + MimeType, + ExtractPDFParams, + ExtractElementType, + ExtractPDFJob, + ExtractPDFResult, + SDKError, + ServiceUsageError, + ServiceApiError +} = require("@adobe/pdfservices-node-sdk"); +const fs = require("fs"); + +(async () => { + let readStream; + try { + // Initial setup, create credentials instance + const credentials = new ServicePrincipalCredentials({ + clientId: process.env.PDF_SERVICES_CLIENT_ID, + clientSecret: process.env.PDF_SERVICES_CLIENT_SECRET + }); + + // Creates a PDF Services instance + const pdfServices = new PDFServices({credentials}); + + // Creates an asset(s) from source file(s) and upload + readStream = fs.createReadStream("./extractPDFInput.pdf"); + const inputAsset = await pdfServices.upload({ + readStream, + mimeType: MimeType.PDF + }); + + // Create parameters for the job + const params = new ExtractPDFParams({ + elementsToExtract: [ExtractElementType.TEXT, ExtractElementType.TABLES], + getStylingInfo: true, + }); + + // Creates a new job instance + const job = new ExtractPDFJob({inputAsset, params}); + + // Submit the job and get the job result + const pollingURL = await pdfServices.submit({job}); + const pdfServicesResponse = await pdfServices.getJobResult({ + pollingURL, + resultType: ExtractPDFResult + }); + + // Get content from the resulting asset(s) + const resultAsset = pdfServicesResponse.result.resource; + const streamAsset = await pdfServices.getContent({asset: resultAsset}); + + // Creates a write stream and copy stream asset's content to it + const outputFilePath = "./ExtractTextTableInfoWithStylingInfoFromPDF.zip"; + console.log(`Saving asset at ${outputFilePath}`); + + const writeStream = fs.createWriteStream(outputFilePath); + streamAsset.readStream.pipe(writeStream); + } catch (err) { + if (err instanceof SDKError || err instanceof ServiceUsageError || err instanceof ServiceApiError) { + console.log("Exception encountered while executing operation", err); + } else { + console.log("Exception encountered while executing operation", err); + } + } finally { + readStream?.destroy(); + } +})(); ``` #### Python diff --git a/src/pages/overview/pdf-extract-api/howtos/index.md b/src/pages/overview/pdf-extract-api/howtos/index.md index a13fa53b8..760226b0e 100644 --- a/src/pages/overview/pdf-extract-api/howtos/index.md +++ b/src/pages/overview/pdf-extract-api/howtos/index.md @@ -90,14 +90,8 @@ ClientConfig clientConfig = ClientConfig.ConfigBuilder() Available properties: -- **connectTimeout**: Default: 10000. The maximum allowed time in - milliseconds for creating an initial HTTPS connection. -- **readTimeout**: Default: 10000. The maximum allowed time in - milliseconds between two successive HTTP response packets. -- **processingTimeout**: Default: 600000. The maximum allowed time - in milliseconds for processing the documents. Any operation taking more time than the specified `processingTimeout` will result in an operation timeout exception. - - **Note :** It is advisable to set the `processingTimeout` to higher values for processing large files. - +- **timeout**: Default: 10000. The maximum allowed time in milliseconds before the request times out. If the request + takes longer than `timeout`, the request will be aborted. Override the timeout properties via a custom `ClientConfig` class: @@ -106,11 +100,9 @@ Override the timeout properties via a custom `ClientConfig` class: ### ```javascript -const clientConfig = PDFServicesSdk.ClientConfig - .clientConfigBuilder() - .withConnectTimeout(15000) - .withReadTimeout(15000) - .build(); +const clientConfig = new ClientConfig({ + timeout: 15000 +}) ``` ### Python timeout configuration diff --git a/src/pages/overview/pdf-extract-api/quickstarts/nodejs/index.md b/src/pages/overview/pdf-extract-api/quickstarts/nodejs/index.md index fd3fb0d88..3765d78e4 100644 --- a/src/pages/overview/pdf-extract-api/quickstarts/nodejs/index.md +++ b/src/pages/overview/pdf-extract-api/quickstarts/nodejs/index.md @@ -10,7 +10,7 @@ To get started using Adobe PDF Extract API, let's walk through a simple scenario To complete this guide, you will need: -* [Node.js](https://nodejs.org) - Node.js version 14.0 or higher is required. +* [Node.js](https://nodejs.org) - Node.js version 18.0 or higher is required. * An Adobe ID. If you do not have one, the credential setup will walk you through creating one. * A way to edit code. No specific editor is required for this guide. @@ -65,27 +65,20 @@ Now you're ready to begin coding. 1) We'll begin by including our required dependencies: ```js -const PDFServicesSdk = require('@adobe/pdfservices-node-sdk'); -const fs = require('fs'); +const { + ServicePrincipalCredentials, + PDFServices, + MimeType, + ExtractPDFParams, + ExtractElementType, + ExtractPDFJob, + ExtractPDFResult +} = require("@adobe/pdfservices-node-sdk"); +const fs = require("fs"); const AdmZip = require('adm-zip'); ``` -The first line includes the Adobe PDF Services Node.js SDK. The second third include Node's `filesystem` package as well as the package that will work with the ZIP file returned from the API. - -2) Now let's define our input and output: - -```js -const OUTPUT_ZIP = './ExtractTextInfoFromPDF.zip'; - -//Remove if the output already exists. -if(fs.existsSync(OUTPUT_ZIP)) fs.unlinkSync(OUTPUT_ZIP); - -const INPUT_PDF = './Adobe Extract API Sample.pdf'; -``` - -This defines what our output ZIP will be and optionally deletes it if it already exists. Then we define what PDF will be extracted. (You can download the source we used [here](/Adobe%20Extract%20API%20Sample.pdf).) In a real application, these values would be typically be dynamic. - -3) Set the environment variables `PDF_SERVICES_CLIENT_ID` and `PDF_SERVICES_CLIENT_SECRET` by running the following commands and replacing placeholders `YOUR CLIENT ID` and `YOUR CLIENT SECRET` with the credentials present in `pdfservices-api-credentials.json` file: +2) Set the environment variables `PDF_SERVICES_CLIENT_ID` and `PDF_SERVICES_CLIENT_SECRET` by running the following commands and replacing placeholders `YOUR CLIENT ID` and `YOUR CLIENT SECRET` with the credentials present in `pdfservices-api-credentials.json` file: - **Windows:** - `set PDF_SERVICES_CLIENT_ID=` - `set PDF_SERVICES_CLIENT_SECRET=` @@ -94,70 +87,87 @@ This defines what our output ZIP will be and optionally deletes it if it already - `export PDF_SERVICES_CLIENT_ID=` - `export PDF_SERVICES_CLIENT_SECRET=` -4) Next, we setup the SDK to use our credentials. +3) Next, we setup the SDK to use our credentials. ```js -const credentials = PDFServicesSdk.Credentials - .servicePrincipalCredentialsBuilder() - .withClientId(process.env.PDF_SERVICES_CLIENT_ID) - .withClientSecret(process.env.PDF_SERVICES_CLIENT_SECRET) - .build(); - -// Create an ExecutionContext using credentials -const executionContext = PDFServicesSdk.ExecutionContext.create(credentials); +// Initial setup, create credentials instance +const credentials = new ServicePrincipalCredentials({ + clientId: process.env.PDF_SERVICES_CLIENT_ID, + clientSecret: process.env.PDF_SERVICES_CLIENT_SECRET +}); + +// Creates a PDF Services instance +const pdfServices = new PDFServices({credentials}); ``` -This code both points to the credentials downloaded previously as well as sets up an execution context object that will be used later. +4) Now, let's upload the asset: -5) Now, let's create the operation: +```js +const inputAsset = await pdfServices.upload({ + readStream, + mimeType: MimeType.PDF +}); +``` +We define what PDF will be extracted. (You can download the source we used [here](/Adobe%20Extract%20API%20Sample.pdf).) In a real application, these values would be typically be dynamic. +5) Now, let's create the parameters and the job: + +```js +// Create parameters for the job +const params = new ExtractPDFParams({ + elementsToExtract: [ExtractElementType.TEXT] +}); + +// Creates a new job instance +const job = new ExtractPDFJob({inputAsset, params}); +``` + +This set of code defines what we're doing (an Extract operation), +it defines parameters for the Extract job. PDF Extract API has a few different options, but in this example, we're simply asking for the most basic of extractions, the textual content of the document. + +6) The next code block submits the job and gets the job result: ```js -// Create a new operation instance. -const extractPDFOperation = PDFServicesSdk.ExtractPDF.Operation.createNew(), - input = PDFServicesSdk.FileRef.createFromLocalFile( - INPUT_PDF, - PDFServicesSdk.ExtractPDF.SupportedSourceFormat.pdf - ); - -// Build extractPDF options -const options = new PDFServicesSdk.ExtractPDF.options.ExtractPdfOptions.Builder() - .addElementsToExtract(PDFServicesSdk.ExtractPDF.options.ExtractElementType.TEXT).build() - -extractPDFOperation.setInput(input); -extractPDFOperation.setOptions(options); +// Submit the job and get the job result +const pollingURL = await pdfServices.submit({job}); +const pdfServicesResponse = await pdfServices.getJobResult({ + pollingURL, + resultType: ExtractPDFResult +}); + +// Get content from the resulting asset(s) +const resultAsset = pdfServicesResponse.result.resource; +const streamAsset = await pdfServices.getContent({asset: resultAsset}); ``` -This set of code defines what we're doing (an Extract operation), points to our local file and specifies the input is a PDF, and then defines options for the Extract call. PDF Extract API has a few different options, but in this example, we're simply asking for the most basic of extractions, the textual content of the document. +This code runs the Extraction process, gets the content of the result zip in stream asset. -6) The next code block executes the operation: +7) The next code block saves the result at the specified location: ```js -// Execute the operation -extractPDFOperation.execute(executionContext) - .then(result => result.saveAsFile(OUTPUT_ZIP)) - .then(() => { - console.log('Successfully extracted information from PDF.'); - }) - .catch(err => console.log(err)); +// Creates a write stream and copy stream asset's content to it +const outputFilePath = "./ExtractTextInfoFromPDF.zip"; +console.log(`Saving asset at ${outputFilePath}`); + +const writeStream = fs.createWriteStream(outputFilePath); +streamAsset.readStream.pipe(writeStream); ``` -This code runs the Extraction process and then stores the result zip to the file system. +Here's the complete application (`extract.js`): -7) In this block, we read in the ZIP file, extract the JSON result file, and parse it: +8) In this block, we read in the ZIP file, extract the JSON result file, and parse it: ```js -let zip = new AdmZip(OUTPUT_ZIP); +let zip = new AdmZip(outputFilePath); let jsondata = zip.readAsText('structuredData.json'); let data = JSON.parse(jsondata); ``` - -8) Finally we can loop over the result and print out any found element that is an `H1`: +9) Finally, we can loop over the result and print out any found element that is an `H1`: ```js data.elements.forEach(element => { - if(element.Path.endsWith('/H1')) { - console.log(element.Text); - } + if(element.Path.endsWith('/H1')) { + console.log(element.Text); + } }); ``` @@ -166,57 +176,77 @@ data.elements.forEach(element => { Here's the complete application (`extract.js`): ```js -const PDFServicesSdk = require('@adobe/pdfservices-node-sdk'); -const fs = require('fs'); +const { + ServicePrincipalCredentials, + PDFServices, + MimeType, + ExtractPDFParams, + ExtractElementType, + ExtractPDFJob, + ExtractPDFResult +} = require("@adobe/pdfservices-node-sdk"); +const fs = require("fs"); const AdmZip = require('adm-zip'); -const OUTPUT_ZIP = './ExtractTextInfoFromPDF.zip'; - -//Remove if the output already exists. -if(fs.existsSync(OUTPUT_ZIP)) fs.unlinkSync(OUTPUT_ZIP); - -const INPUT_PDF = './Adobe Extract API Sample.pdf'; - -const credentials = PDFServicesSdk.Credentials - .servicePrincipalCredentialsBuilder() - .withClientId(process.env.PDF_SERVICES_CLIENT_ID) - .withClientSecret(process.env.PDF_SERVICES_CLIENT_SECRET) - .build(); - -// Create an ExecutionContext using credentials -const executionContext = PDFServicesSdk.ExecutionContext.create(credentials); - -// Create a new operation instance. -const extractPDFOperation = PDFServicesSdk.ExtractPDF.Operation.createNew(), - input = PDFServicesSdk.FileRef.createFromLocalFile( - INPUT_PDF, - PDFServicesSdk.ExtractPDF.SupportedSourceFormat.pdf - ); - -// Build extractPDF options -const options = new PDFServicesSdk.ExtractPDF.options.ExtractPdfOptions.Builder() - .addElementsToExtract(PDFServicesSdk.ExtractPDF.options.ExtractElementType.TEXT).build() - - -extractPDFOperation.setInput(input); -extractPDFOperation.setOptions(options); - -// Execute the operation -extractPDFOperation.execute(executionContext) - .then(result => result.saveAsFile(OUTPUT_ZIP)) - .then(() => { - console.log('Successfully extracted information from PDF. Printing H1 Headers:\n'); - let zip = new AdmZip(OUTPUT_ZIP); - let jsondata = zip.readAsText('structuredData.json'); - let data = JSON.parse(jsondata); - data.elements.forEach(element => { - if(element.Path.endsWith('/H1')) { - console.log(element.Text); - } - }); - - }) - .catch(err => console.log(err)); +(async () => { + let readStream; + try { + // Initial setup, create credentials instance + const credentials = new ServicePrincipalCredentials({ + clientId: process.env.PDF_SERVICES_CLIENT_ID, + clientSecret: process.env.PDF_SERVICES_CLIENT_SECRET + }); + + // Creates a PDF Services instance + const pdfServices = new PDFServices({credentials}); + + // Creates an asset(s) from source file(s) and upload + readStream = fs.createReadStream("./Adobe Extract API Sample.pdf"); + const inputAsset = await pdfServices.upload({ + readStream, + mimeType: MimeType.PDF + }); + + // Create parameters for the job + const params = new ExtractPDFParams({ + elementsToExtract: [ExtractElementType.TEXT] + }); + + // Creates a new job instance + const job = new ExtractPDFJob({inputAsset, params}); + + // Submit the job and get the job result + const pollingURL = await pdfServices.submit({job}); + const pdfServicesResponse = await pdfServices.getJobResult({ + pollingURL, + resultType: ExtractPDFResult + }); + + // Get content from the resulting asset(s) + const resultAsset = pdfServicesResponse.result.resource; + const streamAsset = await pdfServices.getContent({asset: resultAsset}); + + // Creates a write stream and copy stream asset's content to it + const outputFilePath = "./ExtractTextInfoFromPDF.zip"; + console.log(`Saving asset at ${outputFilePath}`); + + const writeStream = fs.createWriteStream(outputFilePath); + streamAsset.readStream.pipe(writeStream); + + let zip = new AdmZip(outputFilePath); + let jsondata = zip.readAsText('structuredData.json'); + let data = JSON.parse(jsondata); + data.elements.forEach(element => { + if(element.Path.endsWith('/H1')) { + console.log(element.Text); + } + }); + } catch (err) { + console.log("Exception encountered while executing operation", err); + } finally { + readStream?.destroy(); + } +})(); ``` ## Next Steps diff --git a/src/pages/overview/pdf-extract-api/quickstarts/nodejs/shot9.png b/src/pages/overview/pdf-extract-api/quickstarts/nodejs/shot9.png index b09d4ce9f..0eb77ef8e 100644 Binary files a/src/pages/overview/pdf-extract-api/quickstarts/nodejs/shot9.png and b/src/pages/overview/pdf-extract-api/quickstarts/nodejs/shot9.png differ diff --git a/src/pages/overview/pdf-services-api/gettingstarted.md b/src/pages/overview/pdf-services-api/gettingstarted.md index 64ca1461b..9ade0651b 100644 --- a/src/pages/overview/pdf-services-api/gettingstarted.md +++ b/src/pages/overview/pdf-services-api/gettingstarted.md @@ -471,7 +471,7 @@ After downloading the zip, you can run the samples in the zip directly by settin Running any sample or custom code requires the following steps: -1. Install [Node.js 14.0](https://nodejs.org/en/download/) or higher. +1. Install [Node.js 18.0](https://nodejs.org/en/download/) or higher. diff --git a/src/pages/overview/pdf-services-api/quickstarts/nodejs/index.md b/src/pages/overview/pdf-services-api/quickstarts/nodejs/index.md index 4ba1cc9d4..2f5165ea1 100644 --- a/src/pages/overview/pdf-services-api/quickstarts/nodejs/index.md +++ b/src/pages/overview/pdf-services-api/quickstarts/nodejs/index.md @@ -10,7 +10,7 @@ To get started using Adobe PDF Services API, let's walk through a simple scenari To complete this guide, you will need: -* [Node.js](https://nodejs.org) - Node.js version 14.0 or higher is required. +* [Node.js](https://nodejs.org) - Node.js version 18.0 or higher is required. * An Adobe ID. If you do not have one, the credential setup will walk you through creating one. * A way to edit code. No specific editor is required for this guide. @@ -63,24 +63,19 @@ Now you're ready to begin coding. 1) We'll begin by including our required dependencies: ```js -const PDFServicesSdk = require('@adobe/pdfservices-node-sdk'); -const fs = require('fs'); +const { + ServicePrincipalCredentials, + PDFServices, + MimeType, + ExportPDFParams, + ExportPDFTargetFormat, + ExportPDFJob, + ExportPDFResult +} = require("@adobe/pdfservices-node-sdk"); +const fs = require("fs"); ``` -The first line includes the Adobe PDF Services Node.js SDK. The second third include Node's `filesystem` package. - -2) Now let's define our input and output: - -```js -const OUTPUT = './Bodea Brochure.docx'; - -// If our output already exists, remove it so we can run the application again. -if(fs.existsSync(OUTPUT)) fs.unlinkSync(OUTPUT); - -const INPUT = './Bodea Brochure.pdf'; -``` - -3) Set the environment variables `PDF_SERVICES_CLIENT_ID` and `PDF_SERVICES_CLIENT_SECRET` by running the following commands and replacing placeholders `YOUR CLIENT ID` and `YOUR CLIENT SECRET` with the credentials present in `pdfservices-api-credentials.json` file: +2) Set the environment variables `PDF_SERVICES_CLIENT_ID` and `PDF_SERVICES_CLIENT_SECRET` by running the following commands and replacing placeholders `YOUR CLIENT ID` and `YOUR CLIENT SECRET` with the credentials present in `pdfservices-api-credentials.json` file: - **Windows:** - `set PDF_SERVICES_CLIENT_ID=` - `set PDF_SERVICES_CLIENT_SECRET=` @@ -89,51 +84,64 @@ const INPUT = './Bodea Brochure.pdf'; - `export PDF_SERVICES_CLIENT_ID=` - `export PDF_SERVICES_CLIENT_SECRET=` -4) Next, we setup the SDK to use our credentials. +3) Next, we can create our credentials and use them: ```js -const credentials = PDFServicesSdk.Credentials - .servicePrincipalCredentialsBuilder() - .withClientId(process.env.PDF_SERVICES_CLIENT_ID) - .withClientSecret(process.env.PDF_SERVICES_CLIENT_SECRET) - .build(); - -// Create an ExecutionContext using credentials -const executionContext = PDFServicesSdk.ExecutionContext.create(credentials); +// Initial setup, create credentials instance +const credentials = new ServicePrincipalCredentials({ + clientId: process.env.PDF_SERVICES_CLIENT_ID, + clientSecret: process.env.PDF_SERVICES_CLIENT_SECRET +}); + +// Creates a PDF Services instance +const pdfServices = new PDFServices({credentials}); ``` -This code both points to the credentials downloaded previously as well as sets up an execution context object that will be used later. +4) Now, let's upload the asset: -5) Now, let's create the operation: +```js +const inputAsset = await pdfServices.upload({ + readStream, + mimeType: MimeType.PDF +}); +``` + +5) Now, let's create the parameters and the job: ```js -// This creates an instance of the Export operation we're using, as well as specifying output type (DOCX) -const exportPdfOperation = PDFServicesSdk.ExportPDF.Operation.createNew(PDFServicesSdk.ExportPDF.SupportedTargetFormats.DOCX); +// Create parameters for the job +const params = new ExportPDFParams({ + targetFormat: ExportPDFTargetFormat.DOCX +}); -// Set operation input from a source file -const inputPDF = PDFServicesSdk.FileRef.createFromLocalFile(INPUT); -exportPdfOperation.setInput(inputPDF); +// Creates a new job instance +const job = new ExportPDFJob({inputAsset, params}); ``` -This set of code defines what we're doing (an Export operation), points to our local file and specifies the input is a PDF, and then defines options for the Export call. In this example, the only option is the export format, DOCX. +This set of code defines what we're doing (an Export operation), and sets parameter for the Export PDF job. +In this example, the only parameter is the export format ,ie, DOCX. + +6) The next code block submits the job and gets the job result: + +```js +// Submit the job and get the job result +const pollingURL = await pdfServices.submit({job}); +const pdfServicesResponse = await pdfServices.getJobResult({ + pollingURL, + resultType: ExportPDFResult +}); + +// Get content from the resulting asset(s) +const resultAsset = pdfServicesResponse.result.asset; +const streamAsset = await pdfServices.getContent({asset: resultAsset}); +``` -6) The next code block executes the operation: +7) The next code block saves the result at the specified location: ```js -try { - - exportPdfOperation.execute(executionContext) - .then(result => result.saveAsFile(OUTPUT)) - .then(() => { - console.log('Export Done') - }) - .catch(err => { - console.log('Exception encountered while executing operation', err); - }); - -} catch(err) { - console.error('Error:', err); -} +// Creates an output stream and copy stream asset's content to it +const outputStream = fs.createWriteStream("./Bodea Brochure.docx"); +streamAsset.readStream.pipe(outputStream); ``` This code runs the Export process and then stores the result Word document to the file system. @@ -143,50 +151,66 @@ This code runs the Export process and then stores the result Word document to th Here's the complete application (`export.js`): ```js -const PDFServicesSdk = require('@adobe/pdfservices-node-sdk'); -const fs = require('fs'); - -const OUTPUT = './Bodea Brochure.docx'; - -// If our output already exists, remove it so we can run the application again. -if(fs.existsSync(OUTPUT)) fs.unlinkSync(OUTPUT); - -const INPUT = './Bodea Brochure.pdf'; - - -console.log(`About to export ${INPUT} to ${OUTPUT}.`); - -// Set up our credentials object. -const credentials = PDFServicesSdk.Credentials - .servicePrincipalCredentialsBuilder() - .withClientId(process.env.PDF_SERVICES_CLIENT_ID) - .withClientSecret(process.env.PDF_SERVICES_CLIENT_SECRET) - .build(); - -// An exectuionContext object wraps our credentials -const executionContext = PDFServicesSdk.ExecutionContext.create(credentials); - -// This creates an instance of the Export operation we're using, as well as specifying output type (DOCX) -const exportPdfOperation = PDFServicesSdk.ExportPDF.Operation.createNew(PDFServicesSdk.ExportPDF.SupportedTargetFormats.DOCX); - -// Set operation input from a source file -const inputPDF = PDFServicesSdk.FileRef.createFromLocalFile(INPUT); -exportPdfOperation.setInput(inputPDF); - -try { - - exportPdfOperation.execute(executionContext) - .then(result => result.saveAsFile(OUTPUT)) - .then(() => { - console.log('Export Done') - }) - .catch(err => { - console.log('Exception encountered while executing operation', err); - }); - -} catch(err) { - console.error('Error:', err); -} +const { + ServicePrincipalCredentials, + PDFServices, + MimeType, + ExportPDFParams, + ExportPDFTargetFormat, + ExportPDFJob, + ExportPDFResult +} = require("@adobe/pdfservices-node-sdk"); +const fs = require("fs"); + +(async () => { + let readStream; + try { + // Initial setup, create credentials instance + const credentials = new ServicePrincipalCredentials({ + clientId: process.env.PDF_SERVICES_CLIENT_ID, + clientSecret: process.env.PDF_SERVICES_CLIENT_SECRET + }); + + // Creates a PDF Services instance + const pdfServices = new PDFServices({credentials}); + + // Creates an asset(s) from source file(s) and upload + readStream = fs.createReadStream("./Bodea Brochure.pdf"); + const inputAsset = await pdfServices.upload({ + readStream, + mimeType: MimeType.PDF + }); + + // Create parameters for the job + const params = new ExportPDFParams({ + targetFormat: ExportPDFTargetFormat.DOCX + }); + + // Creates a new job instance + const job = new ExportPDFJob({inputAsset, params}); + + // Submit the job and get the job result + const pollingURL = await pdfServices.submit({job}); + const pdfServicesResponse = await pdfServices.getJobResult({ + pollingURL, + resultType: ExportPDFResult + }); + + // Get content from the resulting asset(s) + const resultAsset = pdfServicesResponse.result.asset; + const streamAsset = await pdfServices.getContent({asset: resultAsset}); + + // Creates an output stream and copy stream asset's content to it + const outputFilePath = "./Bodea Brochure.docx"; + console.log(`Saving asset at ${outputFilePath}`); + const outputStream = fs.createWriteStream(outputFilePath); + streamAsset.readStream.pipe(outputStream); + } catch (err) { + console.log("Exception encountered while executing operation", err); + } finally { + readStream?.destroy(); + } +})(); ``` ## Next Steps diff --git a/src/pages/overview/pdf-services-api/quickstarts/nodejs/shot9.png b/src/pages/overview/pdf-services-api/quickstarts/nodejs/shot9.png index b48baa077..f629ac0ac 100644 Binary files a/src/pages/overview/pdf-services-api/quickstarts/nodejs/shot9.png and b/src/pages/overview/pdf-services-api/quickstarts/nodejs/shot9.png differ diff --git a/src/pages/overview/pdf-services-api/releasenotes.md b/src/pages/overview/pdf-services-api/releasenotes.md index 580744f44..8cf6d1975 100644 --- a/src/pages/overview/pdf-services-api/releasenotes.md +++ b/src/pages/overview/pdf-services-api/releasenotes.md @@ -73,7 +73,7 @@ import com.adobe.pdfservices.operation.ExecutionContext; * Update the latest SDK dependency in package.json file of your project ``` -"@adobe/pdfservices-node-sdk": "3.4.2" +"@adobe/pdfservices-node-sdk": "4.0.0" ``` * Require the `@adobe/pdfservices-node-sdk` in the Sample file to access the SDK interface @@ -129,6 +129,15 @@ Upgrading to the latest SDK should not break existing applications. ## Change history +### 4.0.0 (April, 2024; major release) +| Change | Language | Description | +|---------|----------|--------------------------------------------------------------------------------------------------------------------------------| +| New | NodeJS | Released Adobe PDF Services Node SDK v4.0.0, introducing new interfaces fully leveraging power of new PDF Services rest APIs. | +| New | NodeJS | Added support for delete asset, refresh download URI, webhook notifiers. | +| New | NodeJS | Eliminated need of storage to save intermediate result by removed dependency on temporary storage. | +| New | NodeJS | Extended I/O capabilities by introducing external storage for a majority of PDF Services operations. | +| Changed | NodeJS | Updated Extract PDF operation to return content and resource asset along with content JSON object. | + ### 2.3.1 (March, 2024; patch release) | Change | Language | Description | diff --git a/src/pages/overview/releasenotes.md b/src/pages/overview/releasenotes.md index fe854710b..f146cdc89 100644 --- a/src/pages/overview/releasenotes.md +++ b/src/pages/overview/releasenotes.md @@ -116,7 +116,7 @@ import com.adobe.pdfservices.operation.ExecutionContext; * Update the latest SDK dependency in package.json file of your project ``` -"@adobe/pdfservices-node-sdk": "3.4.2" +"@adobe/pdfservices-node-sdk": "4.0.0" ``` * Require the `@adobe/pdfservices-node-sdk` in the Sample file to access the SDK interface @@ -173,6 +173,16 @@ Upgrading to the latest SDK should not break existing applications. ## Change history +### 4.0.0 (April, 2024; major release) +| Change | Language | Description | +|---------|----------|--------------------------------------------------------------------------------------------------------------------------------| +| New | NodeJS | Released Adobe PDF Services Node SDK v4.0.0, introducing new interfaces fully leveraging power of new PDF Services rest APIs. | +| New | NodeJS | Added support for delete asset, refresh download URI, webhook notifiers. | +| New | NodeJS | Eliminated need of storage to save intermediate result by removed dependency on temporary storage. | +| New | NodeJS | Extended I/O capabilities by introducing external storage for a majority of PDF Services operations. | +| Changed | NodeJS | Updated Extract PDF operation to return content and resource asset along with content JSON object. | + + ### 2.3.1 (March, 2024; patch release) | Change | Language | Description |