Strapi: What would be the best way to create import job? - javascript

I am very new to the strapi, and I am looking for the best way to create an import job for it.
This job is supposed to be run as a cron and get its data from a temporary database, which means no uploaded files etc.
Strapi is deployed as a docker container to the kubernetes.
There is an example of importer plugin, but it is too huger for has unnecessary frontend while I am looking for something lighter.

You can use strapi controller e.g Restaurant is a controller
call it in browser like
localhost/restaurant/import
module.exports = {
import: async (ctx) => {
// getRecord(// code goes here)
// strapi.services.restaurant.create(passData)
}}
1 - get data e.g from api https://www.example.com/wp-json/wp/v2/
2 - create strapi record strapi.services.restaurant.create()
You can call localhost/restaurant/import using cron

Related

How to generate polkadot account file using polkadot-js API

When using Polkadot-JS App, a new account is saved in the polkadot-accounts directory with the following file format:
{"encoded":"DBSPyMN8LAWsoejHHMfqU2/m5YxxeGtD0HJpzQzyY44AgAAAAQAAAAgAAADug5JmpYwzc9oxUJXUY2zIWkZFQRtqoS3lgu/wdhRSLPwx5TKjaMRrIqrrSyO3uxRytoPmKT5wTDV/zGyh2S9xwozzqhQhBmJG7TJwA+oNqDKpQpj6cooWNSivRzKmpqPaMO+af0LPPOREvVGHESwBSf+xHMZ5fISIG97xbXhGXV89Oo4iEBSwpIhjz6+u7AiVtF2akpyxLkhqiIXC","encoding":{"content":["pkcs8","sr25519"],"type":["scrypt","xsalsa20-poly1305"],"version":"3"},"address":"14BrSo66a3zvZmTksQFBmtZYEHvyWGJEBQypVfDynPXbsz2T","meta":{"genesisHash":"0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3","isHardware":false,"name":"POLKY123TESTONLY","tags":[],"whenCreated":1665704506323}}
I would like to achieve the same result using the polkadot-js API.
When I add an account to the keyring it is not there when I run the script the next time. Is there some way to store all accounts in a file and then load them all when creating the keyring object?
const keyring = new Keyring({type: 'sr25519'});
It seems odd to me that there isn't an obvious way to do this. How does the App work? it loads all the accounts in the polkadot-accounts directory. So why is there no API call to achieve this? Or is there?
Also if I wanted to create an account and then easily load it into the Polkadot-JS APP, I would need it in the format above, so surely there must be a way to save an account in that format ?
Basically i'm looking for a method to 'create backup file' the same way the App does.
It seems like there should be a simple function to do this?
To generate a backup file similar to the one in Polkadot-JS App you need to use:
console.log(JSON.stringify(keyring.toJson(pair.address)));
Also when creating the key pair you need to add the meta data for genesisHash:
const pair = keyring.addFromUri(mnemonic, { name: 'POLKA_KEY_1', genesisHash:'0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3', isHardware:false}, 'sr25519');

Is there anyway to list existing routes in FeathersJS framework?

In Laravel i can use
php artisan route list
To see all routes in my Laravel project .. I am asking for the same behavior but in FeathersJS framework which built on top of ExpressJS.
If not, is there anyway to create that as a custom command using node js to obtain the same behavior ?
Thanks
Usually it is just a list of all folders in src/services but you can also get a dynamic list as shown in the documentation for app.services. This can be quickly turned into a command like this:
// list-services.js
const app = require('./src/app');
const serviceList = Object.keys(app.services);
console.log(serviceList.join('\n');
Now you can run this with node list-services

How can we pass parameters to an already built Vue JS app?

We have a Vue app that connects to a Web Service and get's some data. The web service URL is different, depending on the location we install the app on.
I first thought of using .env files, but later I realized these files get injected into the minified .js files.
Having this in my main.js was very convenient in the case of .env files:
Vue.prototype.ApiBaseUrl = process.env.VUE_APP_APIBASEURL
Vue.prototype.PrintDocsFolder = process.env.VUE_APP_PRINTDOCSFOLDER
Vue.prototype.TicketPrintWSocket = process.env.VUE_APP_TICKETPRINTWSOCKET
The app is already built. I don't want to build the app for each of the hundred locations we have to deploy to. I'm not sure about the "official" approach for this.
Is there any out of the box solution in Vue that can allow this configuration? Basically we need to have a file in the root folder of the built app, and read values for our Vue.prototype.VARIABLES.
We are using vue-cli 3.
Like others have said, you can do this at runtime via a network request. If you don't know where you're deploying to until you're live, you'll need to do something like this.
Alternatively, you can do this at an infrastructure and networking level. Sometimes for A/B testing systems, that's how it's done.
Alternatively, you can do this at build time. I've done both... for static assets like images, sometimes you cannot do this at runtime and you need to replace the public urls at build time. For the network request approach, fetching a static json file with the mappings you host is a definite possibility.
You were very close with the idea of using .env files.
Build-time approach with Vue CLI
In Vue CLI, you get to use the Webpack's DefinePlugin for free by specifying variables in your .env files prefixed as such: VUE_APP_THE_API_URL and then using it like process.env.VUE_APP_THE_API_URL. Docs.
Usage
In your source, use process.env.VUE_APP_THE_API_URL and .env files. Reference your API url in your source code as process.env.VUE_APP_THE_API_URL and then you should use the .env files, like you were planning to, to switch between the dev-only value and a production-only value.
The production-only value is gonna be fake and very unique so that when you find + replace it, it will be distinct.
Find + Replace the fake API_URL you built with
After you're done building your application for production, you're going to loop over a mapping file (json, js, whatever) which contains the API urls you're going to deploy to.
You'll use the filesystem and find + replace to replicate your app as many times as you need before doing a deploy via S3, fastly, etc. You can do this in a bash script or using node + execa or node + fs.
Why you might need to do this
I had to do this at build time because modifying certain assets is not possible at runtime due to optimizations done by webpack loaders where they hard-code things like the public path so it is faster. With hundreds of API/CDN urls, it would be extremely inefficient to rebuild the application over and over.
How Vue CLI does it (if you don't wanna do VUE_APP_*)
Vue CLI is ontop of webpack and this is kind of an advanced use case, so you'll want to set configureWebpack inside of vue.config.js and point that to a require('webpack.config.js') file. You want to do this in Webpack or just within your build process (bash, node, gulp, whatever).
Vue CLI 3 is tied to the major webpack version. Right now that's Webpack 4. I'm going to give you the Webpack 4 answer for your problem, but I think they're changing the plugin name in Webpack v5.
Define Plugin
The plugin you want is the DefinePlugin. Just do the above steps, but you'd be manually setting { plugins: [ new DefinePlugin() ] } with the options you want. You'd do this if you didn't wanna do VUE_APP_* as the prefix to your env variables.
This can be done simply by making an XMLHttpRequest to a URL (e.g., to a local JSON file), and reading the data contents.
For instance, you could use fetch (supported by 95% browsers) to request the config from <projectroot>/config.json (which can be unique to each deployment location), and then set the global properties with the result:
// main.js
fetch('config.json')
.then(res => res.json())
.catch(error => {
// ignore any errors
console.warn(error)
return {}
})
.then(config => {
Vue.prototype.ApiBaseUrl = config.ApiBaseUrl
Vue.prototype.PrintDocsFolder = config.PrintDocsFolder
Vue.prototype.TicketPrintWSocket = config.TicketPrintWSocket
// initialize app here
new Vue(...)
})
demo
If there are literally 100's of locations where the app is supposed to be deployed with different APIs/params for each location AND YOU DON'T WANT TO LEAVE ANY TRACE OF THE WHOLE DATA apart from the variables which are necessary for proper functioning of the app, I would have personally stored all the different params in one central database and create one single common API which is able to decide which params to feed to which particular deployment. So that at initial app load, the app would just have to make 1 extra API to call to get the correct params. (provided there is some unique identifier for each deployment).
For example, if the unique identifier is the domain name over which the app is served.
You can store the params like this in the database:
+-------------------+----------------------------+-----------------+--------------------+--+
| domainName | ApiBaseUrl | PrintDocsFolder | TicketPrintWSocket | |
+-------------------+----------------------------+-----------------+--------------------+--+
| example.com | http://api-base-url-1.com/ | print-doc-1 | ticket-print-1 | |
+-------------------+----------------------------+-----------------+--------------------+--+
| secondExample.com | http://api-base-url-2.com/ | print-doc-2 | ticket-print-2 | |
+-------------------+----------------------------+-----------------+--------------------+--+
| thirdExample.com | http://api-base-url-3.com/ | print-doc-3 | ticket-print-3 | |
+-------------------+----------------------------+-----------------+--------------------+--+
then at app load, you can make a axios (Promise based HTTP client) call and pass the current domain name as a param like this:
const details = await axios.get('/common-api-with-all-the-details', {
params: {
domainName: location.hostname
});
This common API should match the domain with db and fetch the correct record accordingly.
Advantages:
You never need to rebuild the app or config the environment variables
individually.
You will always be in control over which params to feed
to which particular deployment.
You can CHANGE/UPDATE the params on
the FLY.
Your whole data store is not public.
Disadvantages:
Requires one extra server setup.
1 extra API call at app's initial load.
Other approaches:
You can avoid the use of database (if your dataset is not too large) by storing all your details in an array. Then on every COMMON API call, you can match the domain name against the array (lodash can help), thereby increasing response time, lowering complexity and avoiding a database setup completely.
You can use server-less architecture to avoid setting up a completely new server to host your COMMON API, Firebase Cloud functions or AWS Lambda have generous free tiers to cover a decent amount of traffic.

What does NextJS .prepare() actually do?

When running nextjs with a custom server, what does .prepare() called on the next application do?
it does 5 things in this order in an async/await fashion
Verify TypeScript Setup
load Custom Routes
add ExportPathMap to Routes
Makes next export exportPathMap work in development mode.
So that the user doesn't have to define a custom server reading the exportPathMap
start hotReloader
records telemetry
[source code]
It prepare or make the next.js code ready to use another server (In their example express) for handling SSR.

How to run a script on a newly created EC2 instance via AWS SDK?

I'm currently using AWS's Javascript SDK to launch custom EC2 instances and so far so good.
But now, I need these instances to be able to run some tasks when they are created, for example, clone a repo from Github, install a software stack and configure some services.
This is meant to emulate a similar behaviour I have for local virtual machine deployment. In this case, I run some provisioning scripts with Ansible that get the job done.
For my use case, which would be the best option amongst AWS's different services to achieve this using AWS's Javascript SDK?
Is there anyway I could maybe have a template script to which I passed along some runtime obtained variables to execute some tasks in the instance I just created? I read about user-data but I can't figure out how that wraps with AWS's SDK. Also, it doesn't seem to be customisable.
At the end of the day, I think I need a way to use the SDK to do this:
"On the newly created instance, run this script that is stored in such place, replacing these
placeholder values in the script with these I'm giving you now"
Any hints?
As Mark B. stated, UserData is the way to go for executing commands on instance launch. As you tagged the question with javascript here's an example on passing this in the ec2.runInstances command:
let AWS = require('aws-sdk')
let ec2 = new AWS.EC2({region: 'YOUR_REGION'})
// Example commands to create a folder, a file and delete it
let commands = [
'#!/usr/bin/env bash',
'mkdir /home/ubuntu/test',
'touch /home/ubuntu/test/examplefile',
'rm -rf /home/ubuntu/test'
];
let params = {
...YOUR PARAMS HERE...
UserData: new Buffer(commands.join("\n")).toString('base64')
}
// You need to encode it with Base64 for it to be executed by the userdata interpreter
ec2.runInstances(params).promise().then(res => { console.log(res); })
When you launch the new instances you can provide the user-data at that time, in the same AWS SDK/API call. That's the best place to put any server initialization code.
The only other way to kick off a script on the instance via the SDK is via the SSM service's Run Command feature. But that requires the instance to already have the AWS SSM agent installed. This is great for remote server administration, but user-data is more appropriate for initializing an instance on first boot.

Categories

Resources