pdfkit on JS/TS Lambda with CDK Error: ENOENT: no such file or directory, open '/var/task/data.trie - pdfkit

I'm trying to use pdfkit v.0.12.1 with AWS CDK and a Lambda function (tried both typescript and js).
When I try to run it I get this error:
Error: ENOENT: no such file or directory, open '/var/task/data.trie
The Lambda looks like this:
const PDFKIT = require("pdfkit")
const pdfPromise = new Promise(resolve => {
const doc = new PDFKIT()
doc.text('hello pdf Kit...Please work', 100, 50)
doc.end()
const buffers = []
doc.on("data", buffers.push.bind(buffers))
doc.on("end", () => {
const pdfData = Buffer.concat(buffers)
resolve(pdfData)
})
})
Lambda runtime is Nodejs_12_x
All the code is importd into the Lambda, but I'm unsure if I have everything to run. Lambda file size is about 650kb.
Any help appreciated on how to get around this.

pdfkit was not loaded properly in the lambda function.
I solved this by following this advice for adding external dependencies to a lambda function in CDK.
Basically, create a separate folder for your lambda in your CDK set up with a seperate node modules folder. On deploy, all of this will be packed together to have the dependencies available.
After that, pdfkit works as expected.

Related

Electron plugin architecture, inject plugin code into the application

As the title say, I am trying to develop a plugin architecture for an electron app.
So far I have handle my custom plugin store the download of the plugin source which consist of an single main.js and a style.css.
I am stuck now since I don't know how to "require" the file from my application.
A little more explanation on this main.js file:
I want to require that main.js file to that I can retrieve the exported class to create a new instance in my PluginManager system.
It would be like so:
// plugin-manager.ts
loadPlugin(pluginId: string) {
const pluginClass = await import(path.join('/somewhere-in-the-fs', pluginId));
const plugin = new PluginClass({ app: myApp });
this.enabledPlugins.push(plugin);
}
tldr: I'm stuck at the await import() part because obviously my plugin is not in my running node environment.

Why does Fpdi fail to extend TCPDF when using PHP8.1?

I'm using:
TCPDF version 6.4.4.
FPDI version 2.3.6
PHP Version 8.1.7 (Running on Apache and Windows Server 2012,a dev environment)
And, I don't think it's relevant but I'm also using
tcpdf-extension
These were installed with composer:
{
"require": {
"tecnickcom/tcpdf": "6.4.4",
"setasign/fpdi": "^2.0",
"naitsirch/tcpdf-extension": "dev-master"
}
}
I am also using a Java/PHP bridge. This is relevant because it changes the error message, however, I doubt this is the cause of the issue.
The problem I'm having is that Fpdi fails to extend TCPDF.
The error message I get looks like this:
PHP Fatal error: During class fetch: Uncaught Error: Call to a member function invokeBegin()
on null in http://127.0.0.1:8080/JavaBridge/java/Java.inc:557
Stack trace:
#0 http://127.0.0.1:8080/JavaBridge/java/Java.inc(56): java_Client->invokeMethod(0, 'typeExists', Array)
#1 C:\Program Files (x86)\PHP\v8.1\vendor\setasign\fpdi\src\Tcpdf\Fpdi.php(33):
java_autoload_function('setasign\\Fpdi\\F...')
...
#8 {main} in C:\Program Files (x86)\PHP\v8.1\vendor\setasign\fpdi\src\Tcpdf\Fpdi.php on line 33
It is failing to fetch a class and the php/java bridge, as a last ditch effort to load it, is attempting to fetch the missing class with a java autoloader, which it fails to do because it's not a java class. Unfortunately, it doesn't give me the full name of the class that's it is trying to load. But this error occurs in setasign\fpdi\src\Tcpdf\Fpdi.php on line 33. Which reads:
class Fpdi extends \TCPDF
My code that invokes this looks like this:
define("COMPOSER_AUTOLOADER","C:\\Program Files (x86)\\PHP\\v8.1\\vendor\\autoload.php");
require_once(COMPOSER_AUTOLOADER);
use setasign\Fpdi\Tcpdf\Fpdi;
class PDF extends Fpdi {
...//functions related to my use case
}
My code that calls this extended class:
// initiate PDF
$pdf = new PDF($data['orientation'], 'mm', USLETTER, true, 'UTF-8', false);
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
$pdf->SetDisplayMode('real');
$pdf->SetAutoPageBreak(true, 1);
//set margins
$pdf->SetMargins(0,0);
$pdf->SetHeaderMargin(0);
$pdf->SetFooterMargin(0);
...
$pdf->AddPage($data['orientation']);
...
$pdf->Output('newpdf.pdf', 'I');
Also probably relevant, I set up a test that uses only the TCPDF library without Fpdi and it fails to load the constants that are supposed to be set up in TCPDF_static.php. (USLETTER for instance), but if I manually define that constant, it does load the PDF as expected:
require_once("C:\\Program Files (x86)\\PHP\\v8.1\\vendor\\autoload.php");
use setasign\Fpdi\Tcpdf\Fpdi;
define ('USLETTER',array( 612.000, 792.000));
$pdf = new TCPDF('', 'in', USLETTER, true, 'UTF-8', false);
...
$pdf->AddPage();
...
$pdf->Output('newpdf.pdf', 'I');
Another detail: this code was working fine with PHP 5.6 and some older versions of TCPDF (6.2.11) and Fpdi (1.4.2). Upgrading to PHP 8.1.7 required updating these libraries.
Why is TCPDF failing to load its constants and, more importantly, why can't Fpdi extend TCPDF?

Import my own files into the electron renderer process

This seems really dumb, but I need help for importing some source code into the renderer process in electron:
I have an electron app:
index.html (loads window.js with a tag)
- index.js
- window.js
- useful_functions.js
In window.js, I want to import some functions from useful_functions.js, so I've tried the following:
// fails with: Uncaught SyntaxError: Unexpected identifier
import { very_useful } from './useful_functions.js';
// fails with: Uncaught ReferenceError: require is not defined
const { very_useful } = require('./useful_functions.js');
// fails with: Uncaught ReferenceError: require is not defined
require('electron').remote.require('./useful_functions.js')
I also tried the nodeIntegration flag, but that didn't help either
Note: I'm not trying to import npm modules but my own code, in an other file right next to it.
I'm looking for examples, but I only find super small samples with just the basic files. (Or huge apps like atom that would take me a while to figure out)
I don't have webpack setup for this project yet, but I'm sure there is a simpler way to do this very basic task...
Thanks for any help.
In index.html, use require() instead of loading window.js with a tag, i.e., replace:
<script src="window.js"></script>
with:
<script>require('./window.js');</script>
Then, in window.js, the following statement should work too:
const { very_useful } = require('./useful_functions.js');
Note that nodeIntegration: true is needed in the options passed to new BrowserWindow() anyway:
webPreferences:
{
nodeIntegration: true
}
See:
Node Modules
Functions and objects are added to the root of a module by
specifying additional properties on the special exports object.
Variables local to the module will be private, because the module is
wrapped in a function by Node.js (see module wrapper).
Module Wrapper
Before a module's code is executed, Node.js will wrap it with a
function wrapper that looks like the following:
(function(exports, require, module, __filename, __dirname) {
// Module code actually lives in here
});

How to load resource files or package: URIs in Dart?

There is a way to get the path of the currently executing script and then find the resource files relative to this location, but there is no guarantee that the directory structure is the same when the application is published.
Does Dart provide a generic way to load resources (files, data, ...) in a way that works also with pub run or pub global run?
Asked another way, how do I dynamically load the contents of a package: URI, in a Dart app, at runtime?
Update
The resource package was published.
Update
This is being reworked. The Resource class will be moved to a package.
Original
There is a new Resource class in Dart (tested with Dart VM version: 1.12.0-edge.d4d89d6f12b44514336f1af748e466607bcd1453 (Fri Aug 7 19:38:14 2015))
resource_example/lib/resource/sample.txt
Sample text file.
resource_example/bin/main.dart
main() async {
var resource = const Resource('package:resource_example/resource/sample.txt');
print(await resource.readAsString());
// or for binary resources
// print(await resource.readAsBytes());
}
Executing
dart bin/main.dart
prints
Sample text file.
Executing
pub global activate -spath .
pub global run resource_example:main
also prints
Sample text file.
It's also possible to pass the content of a variable as a resource. This might for example be convenient in unit tests to pass mock resources.
const sampleText = "Sample const text";
main() async {
var uriEncoded = sampleText.replaceAll(' ', '%20');
var resource = new Resource('data:application/dart;charset=utf-8,$uriEncoded');
print(await resource.readAsString());
}
Arbitrary file or http uris are supported as well but this might not work when using pub run or pub global run when using relative paths.
main() async {
var uri = new Uri.file('lib/resource/sample.txt');
var resource = new Resource(uri.toString());
print(await resource.readAsString());
}
For more details see
- http://blog.sethladd.com/2015/08/dynamically-load-package-contents-with.html
- https://codereview.chromium.org/1276263002/

casperjs: how to include other javascript files during unit tests in tests themselves?

I am doing some unit test in casperjs and I got stuck: how do include dependency file from the test itself? Included javascript file can be just a bunch of functions, and does not declare any interface (module.exports = ... etc).
I know I can include from the command line
$ casperjs test --include=./my-mock.js mytest.js
but how can I include files from the test itself?
Putting following on the top does not work for me... my_mock is undefined
casper.options.clientScripts = ["./my-mock.js"]; //push() does not help either
//mytest.js is below
// ------------------------------------------
casper.test.begin('ajax mock test', function suite(test) {
my_mock.setFetchedData("bla");
my_mock.doRequest();
test.assertEquals( ......);
test.done();
});
// ------------------------------------------
CasperJS version 1.1.0-DEV using phantomjs version 1.9.1
Using phantom.injectJs method is the best option I've found so far. E.g. you're having two files in your directory: "tests.js" and "settings.js". You want to include "settings.js" into "test.js". The first thing you should do with your "test.js" is write the following:
phantom.injectJs('settings.js');
casper.test.begin(...
...
The reason that clientScripts isn't working is that it is loaded on each page load, so you don't have access to the objects/functions defined in the file outside of a casper.evaluate() call.
You can use require() to pull in modules, however you may need to modify your included script to work with this method.
Here is what I changed your mytest.js to:
var my_mock = require('my-mock');
casper.test.begin('ajax mock test', function suite(test) {
my_mock.setFetchedData("bla");
my_mock.doRequest();
//test.assertEquals( ... );
test.done();
});
And this is a quick script (my-mock.js) that I threw together to print out when you use the functions you provided.
module.exports = {
setFetchedData: function(a) {
console.log('setFetchedData: ' + a);
},
doRequest: function() {
console.log('doRequest');
}
};
I found useful this sample demonstrating --includes option:
$ casperjs test tests/ --pre=pre.js --includes=inc.js --post=post.js
to load functions that you often use in your tests.

Resources