├── .circleci
└── config.yml
├── .editorconfig
├── .eslintignore
├── .eslintrc
├── .gitattributes
├── .gitignore
├── .husky
├── _
│ └── husky.sh
├── post-commit
├── pre-commit
└── validate-circleci-config.sh
├── .idea
├── aws-lambda-libreoffice.iml
├── codeStyles
│ ├── Project.xml
│ └── codeStyleConfig.xml
├── inspectionProfiles
│ └── Project_Default.xml
├── misc.xml
├── modules.xml
└── vcs.xml
├── .npmrc
├── .prettierignore
├── changelog.md
├── license
├── package.json
├── readme.md
├── renovate.json
├── src
├── cleanup.ts
├── convert.ts
├── index.ts
├── logs.test.ts
├── logs.ts
├── validations.test.ts
└── validations.ts
├── test
├── Dockerfile
├── test.js
└── test.sh
├── tsconfig.json
└── yarn.lock
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | orbs:
2 | node: circleci/node@5.1.0
3 |
4 | version: 2.1
5 |
6 | parameters:
7 | node_version:
8 | type: string
9 | default: '16.15.1'
10 |
11 | commands:
12 | install_deps:
13 | steps:
14 | - node/install-packages:
15 | pkg-manager: yarn
16 | cache-version: v1-all
17 | cache-only-lockfile: true
18 | app-dir: ~/repo
19 | override-ci-command: yarn install --pure-lockfile --no-progress
20 |
21 | jobs:
22 | build:
23 | executor:
24 | name: node/default
25 | tag: << pipeline.parameters.node_version >>
26 | working_directory: ~/repo
27 | steps:
28 | - checkout
29 | - install_deps
30 | - run: yarn test
31 | - run: yarn type-check
32 | - run: yarn lint:ci
33 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | end_of_line = lf
5 | charset = utf-8
6 | trim_trailing_whitespace = true
7 | insert_final_newline = true
8 | indent_style = space
9 | indent_size = 2
10 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | coverage/
2 | lib/
3 | renovate.json
4 | tsconfig.json
5 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "extends": [
4 | "@shelf/eslint-config/typescript"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
2 | *.js text eol=lf
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .vscode/
2 | .serverless/
3 | coverage/
4 | lib/
5 | node_modules/
6 |
7 | *.log
8 | junit.xml
9 | draft.js
10 | *.draft.js
11 | yarn.lock
12 |
13 | .env
14 |
15 | # User-specific stuff
16 | .idea/**/workspace.xml
17 | .idea/**/tasks.xml
18 | .idea/**/usage.statistics.xml
19 | .idea/**/shelf
20 |
21 | # File-based project format
22 | *.iws
23 |
24 | .idea/$CACHE_FILE$
25 | .idea/$PRODUCT_WORKSPACE_FILE$
26 | .idea/.gitignore
27 | !.husky/_/husky.sh
28 |
29 | ./test/cid
30 | ./test/lib
31 | ./test/node_modules
32 |
--------------------------------------------------------------------------------
/.husky/_/husky.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | if [ -z "$husky_skip_init" ]; then
3 | debug () {
4 | if [ "$HUSKY_DEBUG" = "1" ]; then
5 | echo "husky (debug) - $1"
6 | fi
7 | }
8 |
9 | readonly hook_name="$(basename "$0")"
10 | debug "starting $hook_name..."
11 |
12 | if [ "$HUSKY" = "0" ]; then
13 | debug "HUSKY env variable is set to 0, skipping hook"
14 | exit 0
15 | fi
16 |
17 | if [ -f ~/.huskyrc ]; then
18 | debug "sourcing ~/.huskyrc"
19 | . ~/.huskyrc
20 | fi
21 |
22 | export readonly husky_skip_init=1
23 | sh -e "$0" "$@"
24 | exitCode="$?"
25 |
26 | if [ $exitCode != 0 ]; then
27 | echo "husky - $hook_name hook exited with code $exitCode (error)"
28 | fi
29 |
30 | exit $exitCode
31 | fi
32 |
--------------------------------------------------------------------------------
/.husky/post-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 | git update-index --again
4 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 | yarn lint-staged
4 |
--------------------------------------------------------------------------------
/.husky/validate-circleci-config.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | if ! command -v circleci > /dev/null 2>&1; then
4 | echo "\033[0;31m" \
5 | "Please, install CircleCI CLI to validate config:" \
6 | "https://circleci.com/docs/2.0/local-cli/"
7 |
8 | exit 0
9 | fi
10 |
11 | circleci config validate
12 |
--------------------------------------------------------------------------------
/.idea/aws-lambda-libreoffice.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | package-lock=false
2 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | package.json
2 |
--------------------------------------------------------------------------------
/changelog.md:
--------------------------------------------------------------------------------
1 | # v5.0.0
2 |
3 | - Requires LibreOffice 7.4, instead of 7.3 previously
4 |
--------------------------------------------------------------------------------
/license:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) Gemshelf Inc. (shelf.io)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@shelf/aws-lambda-libreoffice",
3 | "version": "7.2.0",
4 | "description": "Utility to work with Docker version of LibreOffice in Lambda",
5 | "keywords": [
6 | "aws lambda",
7 | "libreoffice",
8 | "serverless",
9 | "pdf"
10 | ],
11 | "repository": "shelfio/aws-lambda-libreoffice",
12 | "license": "MIT",
13 | "author": {
14 | "name": "Vlad Holubiev",
15 | "email": "vlad@shelf.io",
16 | "url": "https://shelf.io"
17 | },
18 | "files": [
19 | "lib"
20 | ],
21 | "main": "lib",
22 | "types": "lib/index.d.ts",
23 | "scripts": {
24 | "build": "rm -rf lib/ && yarn build:types && yarn build:code",
25 | "build:code": "babel src --out-dir lib --ignore '**/*.test.ts' --extensions '.ts' && find ./lib -name '*.test.d.ts' -delete",
26 | "build:types": "tsc --emitDeclarationOnly --declaration --isolatedModules false --declarationDir lib",
27 | "coverage": "jest --coverage",
28 | "lint": "eslint . --ext .js,.ts,.json --fix",
29 | "lint:ci": "eslint . --ext .js,.ts,.json",
30 | "prepack": "yarn build",
31 | "test": "jest src",
32 | "type-check": "tsc --noEmit",
33 | "type-check:watch": "npm run type-check -- --watch"
34 | },
35 | "lint-staged": {
36 | "*.{html,json,md,yml}": [
37 | "prettier --write"
38 | ],
39 | "*.{js,ts}": [
40 | "eslint --fix"
41 | ],
42 | ".circleci/config.yml": [
43 | ".husky/validate-circleci-config.sh"
44 | ]
45 | },
46 | "babel": {
47 | "extends": "@shelf/babel-config/backend"
48 | },
49 | "prettier": "@shelf/prettier-config",
50 | "jest": {
51 | "testEnvironment": "node"
52 | },
53 | "dependencies": {
54 | "@shelf/is-audio-filepath": "2.0.0",
55 | "del": "5.1.0",
56 | "is-image": "3.1.0",
57 | "is-video": "1.0.1"
58 | },
59 | "devDependencies": {
60 | "@babel/cli": "7.27.0",
61 | "@babel/core": "7.26.10",
62 | "@shelf/babel-config": "2.0.1",
63 | "@shelf/eslint-config": "2.29.3",
64 | "@shelf/prettier-config": "1.0.0",
65 | "@types/jest": "29.5.14",
66 | "@types/node": "16",
67 | "babel-jest": "29.7.0",
68 | "eslint": "8.57.1",
69 | "husky": "8.0.3",
70 | "jest": "29.7.0",
71 | "lint-staged": "13.3.0",
72 | "prettier": "2.8.8",
73 | "typescript": "5.8.3"
74 | },
75 | "engines": {
76 | "node": ">=16"
77 | },
78 | "publishConfig": {
79 | "access": "public"
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # aws-lambda-libreoffice 
2 |
3 | > Utility to work with Docker version of LibreOffice in Lambda
4 |
5 | ## Install
6 |
7 | ```
8 | $ yarn add @shelf/aws-lambda-libreoffice
9 | ```
10 |
11 | ## Features
12 |
13 | - Includes CJK and X11 fonts bundled in the [base Docker image](https://github.com/shelfio/libreoffice-lambda-base-image)!
14 | - Relies on the latest LibreOffice 7.4 version which is not stripped down from features as a previous layer-based version of this package
15 | - Requires node.js 16x runtime (x86_64)
16 |
17 | ## Requirements
18 |
19 | ### Lambda Docker Image
20 |
21 | First, you need to create a Docker image for your Lambda function.
22 | See the example at [libreoffice-lambda-base-image](https://github.com/shelfio/libreoffice-lambda-base-image) repo.
23 |
24 | Example:
25 |
26 | ```Dockerfile
27 | FROM public.ecr.aws/shelf/lambda-libreoffice-base:7.6-node18-x86_64
28 |
29 | COPY ./ ${LAMBDA_TASK_ROOT}/
30 |
31 | RUN yarn install
32 |
33 | CMD [ "handler.handler" ]
34 | ```
35 |
36 | ### Lambda Configuration
37 |
38 | - At least 3008 MB of RAM is recommended
39 | - At least 45 seconds of Lambda timeout is necessary
40 | - For larger files support, you can [extend Lambda's /tmp space](https://aws.amazon.com/blogs/aws/aws-lambda-now-supports-up-to-10-gb-ephemeral-storage/) using the `ephemeral-storage` parameter
41 | - Set environment variable `HOME` to `/tmp`
42 |
43 | ## Usage (For version 4.x; based on a Lambda Docker Image)
44 |
45 | Given you have packaged your Lambda function as a Docker image, you can now use this package:
46 |
47 | ```javascript
48 | const {convertTo, canBeConvertedToPDF} = require('@shelf/aws-lambda-libreoffice');
49 |
50 | module.exports.handler = async () => {
51 | // assuming there is a document.docx file inside /tmp dir
52 | // original file will be deleted afterwards
53 |
54 | // it is optional to invoke this function, you can skip it if you're sure about file format
55 | if (!canBeConvertedToPDF('document.docx')) {
56 | return false;
57 | }
58 |
59 | return convertTo('document.docx', 'pdf'); // returns /tmp/document.pdf
60 | };
61 | ```
62 |
63 | ## Usage (For version 3.x; based on a Lambda Layer)
64 |
65 | This version requires Node 12.x or higher.
66 |
67 | **NOTE:** Since version 2.0.0 npm package no longer ships the 85 MB LibreOffice
68 | but relies upon [libreoffice-lambda-layer](https://github.com/shelfio/libreoffice-lambda-layer) instead.
69 | Follow the instructions on how to add a lambda layer in [that repo](https://github.com/shelfio/libreoffice-lambda-layer).
70 |
71 | ```js
72 | const {convertTo, canBeConvertedToPDF} = require('@shelf/aws-lambda-libreoffice');
73 |
74 | module.exports.handler = async () => {
75 | // assuming there is a document.docx file inside /tmp dir
76 | // original file will be deleted afterwards
77 |
78 | if (!canBeConvertedToPDF('document.docx')) {
79 | return false;
80 | }
81 |
82 | return convertTo('document.docx', 'pdf'); // returns /tmp/document.pdf
83 | };
84 | ```
85 |
86 | Or if you want more control:
87 |
88 | ```js
89 | const {unpack, defaultArgs} = require('@shelf/aws-lambda-libreoffice');
90 |
91 | await unpack(); // default path /tmp/instdir/program/soffice.bin
92 |
93 | execSync(
94 | `/tmp/instdir/program/soffice.bin ${defaultArgs.join(
95 | ' '
96 | )} --convert-to pdf file.docx --outdir /tmp`
97 | );
98 | ```
99 |
100 | ## Troubleshooting
101 |
102 | - Please allocate at least **3008 MB** of RAM for your Lambda function.
103 | - If some file fails to be converted to PDF, try converting it to PDF on your computer first. This might be an issue with LibreOffice itself
104 | - If you want to include some fonts/plugins to the libreoffice, contribute to the [libreoffice-lambda-base-image](https://github.com/shelfio/libreoffice-lambda-base-image) instead
105 |
106 | ## See Also
107 |
108 | - [libreoffice-lambda-base-image](https://github.com/shelfio/libreoffice-lambda-base-image) - a base Docker image for you Lambdas
109 | - [libreoffice-lambda-layer](https://github.com/shelfio/libreoffice-lambda-layer) - deprecated, not updated anymore, used the Docker image above
110 | - [serverless-libreoffice](https://github.com/vladgolubev/serverless-libreoffice) - original implementation
111 | - [aws-lambda-tesseract](https://github.com/shelfio/aws-lambda-tesseract)
112 | - [aws-lambda-brotli-unpacker](https://github.com/shelfio/aws-lambda-brotli-unpacker)
113 | - [chrome-aws-lambda](https://github.com/alixaxel/chrome-aws-lambda)
114 |
115 | ## Test
116 |
117 | Beside unit tests that could be run via `yarn test`, there are integration tests.
118 |
119 | Smoke test that it works:
120 |
121 | ```sh
122 | cd test
123 | ./test.sh
124 |
125 | # copy converted PDF file from container to the host to see if it's ok
126 | export CID=$(cat ./cid)
127 | docker cp $CID:/tmp/test.pdf ./test.pdf
128 | ```
129 |
130 | ## Publish
131 |
132 | ```sh
133 | $ git checkout master
134 | $ yarn version
135 | $ yarn publish
136 | $ git push origin master --tags
137 | ```
138 |
139 | ## License
140 |
141 | MIT © [Shelf](https://shelf.io)
142 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["github>shelfio/renovate-config-public"],
3 | "labels": ["backend"],
4 | "ignoreDeps": ["cimg/node"]
5 | }
6 |
--------------------------------------------------------------------------------
/src/cleanup.ts:
--------------------------------------------------------------------------------
1 | import fs from 'fs/promises';
2 | import del from 'del';
3 |
4 | // Removes temp files generated by LibreOffice
5 | export async function cleanupTempFiles(): Promise {
6 | const files = await fs.readdir(`/tmp`);
7 | for (const file of files) {
8 | if (file.endsWith('.tmp') === true || file.startsWith('OSL_PIPE')) {
9 | try {
10 | await del([`/tmp/${file}`, `/tmp/${file}/*`], {force: true});
11 | // eslint-disable-next-line no-empty
12 | } catch (error) {}
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/convert.ts:
--------------------------------------------------------------------------------
1 | import childProcess from 'child_process';
2 | import util from 'util';
3 | import path from 'node:path';
4 | import {cleanupTempFiles} from './cleanup';
5 | import {getConvertedFilePath} from './logs';
6 |
7 | const exec = util.promisify(childProcess.exec);
8 |
9 | export const DEFAULT_ARGS = [
10 | '--headless',
11 | '--invisible',
12 | '--nodefault',
13 | '--view',
14 | '--nolockcheck',
15 | '--nologo',
16 | '--norestore',
17 | ];
18 | const LO_BINARY_PATH = 'libreoffice7.6';
19 |
20 | export async function convertTo(filename: string, format: string): Promise {
21 | await cleanupTempFiles();
22 |
23 | const argumentsString = DEFAULT_ARGS.join(' ');
24 | const outputFilename = filename.split(/\\ /).join(' ');
25 |
26 | const cmd = `cd /tmp && ${LO_BINARY_PATH} ${argumentsString} --convert-to ${format} --outdir /tmp '/tmp/${outputFilename}'`;
27 |
28 | let logs;
29 | let err;
30 |
31 | // due to an unknown issue, we need to run command twice
32 | try {
33 | const {stdout, stderr} = await exec(cmd);
34 | logs = stdout;
35 | err = stderr;
36 | } catch (e) {
37 | const {stdout, stderr} = await exec(cmd);
38 | logs = stdout;
39 | err = stderr;
40 | } finally {
41 | await exec(`rm '/tmp/${outputFilename}'`);
42 | await cleanupTempFiles();
43 | }
44 |
45 | if (err) {
46 | throw new Error(`Cannot generate PDF preview for .${path.extname(outputFilename)} file`, {
47 | cause: logs,
48 | });
49 | }
50 |
51 | return getConvertedFilePath(logs.toString());
52 | }
53 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './convert';
2 | export * from './validations';
3 |
--------------------------------------------------------------------------------
/src/logs.test.ts:
--------------------------------------------------------------------------------
1 | import {getConvertedFilePath} from './logs';
2 |
3 | describe('getConvertedFilePath', () => {
4 | it('should return converted file path', () => {
5 | const logsString = `\tconvert /tmp/test.txt -> /tmp/test.docx using filter : MS Word 2007 XML`;
6 |
7 | expect(getConvertedFilePath(logsString)).toEqual('/tmp/test.docx');
8 | });
9 |
10 | it('should throw extended error message when passed incorrect format string', () => {
11 | const logsString = 'log string that produces error';
12 |
13 | expect(() => getConvertedFilePath(logsString)).toThrow(
14 | new TypeError(
15 | `TypeError: Cannot read properties of null (reading '1');\tTried to parse string: "log string that produces error"`
16 | )
17 | );
18 | });
19 | });
20 |
--------------------------------------------------------------------------------
/src/logs.ts:
--------------------------------------------------------------------------------
1 | export function getConvertedFilePath(logs: string): string {
2 | try {
3 | return logs.match(/\/tmp\/.+->\s(\/tmp\/.+) using/)[1];
4 | } catch (e) {
5 | const ErrorWithExtendedMessage: Error = new Error(e);
6 | ErrorWithExtendedMessage.message += `;\tTried to parse string: "${logs}"`;
7 |
8 | throw ErrorWithExtendedMessage;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/validations.test.ts:
--------------------------------------------------------------------------------
1 | import {canBeConvertedToPDF} from './validations';
2 |
3 | it.each`
4 | filename
5 | ${'document.docx'}
6 | ${'document.pdf'}
7 | `('should return true for supported filename $filename', ({filename}) => {
8 | expect(canBeConvertedToPDF(filename)).toEqual(true);
9 | });
10 |
11 | it.each`
12 | filename
13 | ${'table.xlsx'}
14 | ${'book.epub'}
15 | ${'project.mpp'}
16 | ${'email.msg'}
17 | ${'image.jpg'}
18 | ${'video.mp4'}
19 | ${'audio.mp3'}
20 | ${'sound.wav'}
21 | ${'help.chm'}
22 | ${'google-doc.gdoc'}
23 | ${'drawing.dwg'}
24 | `('should return false for unsupported filename $filename', ({filename}) => {
25 | expect(canBeConvertedToPDF(filename)).toEqual(false);
26 | });
27 |
--------------------------------------------------------------------------------
/src/validations.ts:
--------------------------------------------------------------------------------
1 | import isVideo from 'is-video';
2 | import isImage from 'is-image';
3 | import isAudio from '@shelf/is-audio-filepath';
4 |
5 | const UNSUPPORTED_FILE_EXTENSIONS = [
6 | '.chm',
7 | '.heic',
8 | '.gdoc',
9 | '.gsheet',
10 | '.gslides',
11 | '.zip',
12 | '.dwg',
13 | '.msg',
14 | '.mpp',
15 | '.epub',
16 | '.xlsx',
17 | ];
18 |
19 | export function canBeConvertedToPDF(filename: string): boolean {
20 | filename = filename.toLowerCase();
21 |
22 | const isFileExtensionUnsupported = UNSUPPORTED_FILE_EXTENSIONS.some(ext =>
23 | filename.endsWith(ext)
24 | );
25 |
26 | if (isFileExtensionUnsupported) {
27 | return false;
28 | }
29 |
30 | return !isImage(filename) && !isVideo(filename) && !isAudio(filename);
31 | }
32 |
--------------------------------------------------------------------------------
/test/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM public.ecr.aws/shelf/lambda-libreoffice-base:7.6-node18-x86_64
2 |
3 | COPY . ${LAMBDA_TASK_ROOT}/
4 | CMD [ "test.handler" ]
5 |
--------------------------------------------------------------------------------
/test/test.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable @typescript-eslint/no-var-requires */
2 | const {writeFileSync} = require('fs');
3 | const {convertTo} = require('./lib');
4 |
5 | module.exports.handler = async () => {
6 | writeFileSync('/tmp/test.txt', Buffer.from('Hello World!'));
7 |
8 | const convertedFilePath = await convertTo('test.txt', `pdf`);
9 |
10 | console.log({convertedFilePath});
11 | };
12 |
--------------------------------------------------------------------------------
/test/test.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | cp -r ../lib ./
4 | cp -r ../node_modules ./
5 | docker build -t lo-lambda-test .
6 |
7 | (sleep 7; curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}') &
8 | (sleep 30; CID=$(cat ./cid) && docker stop $CID && rm ./cid) &
9 |
10 | docker run -p 9000:8080 --rm --cidfile ./cid lo-lambda-test
11 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowSyntheticDefaultImports": true,
4 | "esModuleInterop": true,
5 | "isolatedModules": true,
6 | "module": "commonjs",
7 | "resolveJsonModule": true,
8 | "skipLibCheck": true,
9 | "sourceMap": false,
10 | "target": "esnext"
11 | },
12 | "exclude": ["node_modules", "test/test.js"],
13 | "include": ["src"]
14 | }
15 |
--------------------------------------------------------------------------------