Security News
New Python Packaging Proposal Aims to Solve Phantom Dependency Problem with SBOMs
PEP 770 proposes adding SBOM support to Python packages to improve transparency and catch hidden non-Python dependencies that security tools often miss.
An experimental framework to serve as proof of concept for a robust, resilient, and distributed web components' delivery system.
Node version: 0.10.0 required
Build status: Linux: | Windows:
#Index
The framework consists mainly of 4 parts.
The components
are small units of isomorphic code mainly consisting of html, javascript, css. They can optionally contain some logic, allowing a server-side node.js application to compose a model that is used to render the html view. When they are rendered
they become pieces of pure html to be injected in any html page.
The library
is where the components are stored. When components depend on static resources (such as images, css files, etc.) these are stored, during packaging and publishing, in a publicly-exposed part of the library that serves as cdn.
The registry
is a rest api that is used to consume, retrieve, and publish components. Since they are immutable, the registry is the entity that handles the traffic between the library and the consumers.
The consumers
are websites or microsites (small independently deployable web sites all connected by a front-door service or any form of routing mechanism) that need to use components to render partial contents in their web pages.
The goal is to explore the possibility of having a system that allows big corporations (that may involve hundreds of engineers on a number of projects) to have tools to facilitate code sharing, reduce dependencies, and easily approach new features and experiments.
A component is a directory composed by
package.json
- contains the component definition, dependencies, and more.view.html
- a template containing the markup. Currently we support handlebars
and jade
. It can contain some css under the <style>
tag and cliend-side javascript under the <script>
tag.server.js
- If the component has some logic, including consuming services, this is the entity that will produce the view-model to compile the view.static contents
such as images, js, and files that will be referenced in the html markup.Components are immutable and semantic versioned.
At first you can create a component in a folder:
npm install oc -g
oc init hello-world
You may want to start a local test registry using a components' folder as a library with a watcher. This will allow to consume and debug it:
oc dev . 3030
Then you may want to create a blank html page to start playing with it and see how it looks:
<html>
<body>
<oc-component href="http://localhost:3030/hello-world">
Optionally, some failover text here
</oc-component>
<script src="http://localhost:3030/oc-client/client.js" />
</body>
</html>
That's it. As soon as you make changes on the component, you will be able to refresh this page and see how it looks.
You will need an online registry connected to a library to do that. The only requisite is that a component with the same name and version cannot be already existing on that registry.
# you have to do the registry config first, just once
oc registry add http://my-components-registry.mydomain.com
# then, ship it
oc publish hello-world/
Now, it should be there at http://my-components-registry.mydomain.com/hello-world
.
At the moment the only supported library is Amazon S3. Create an account and get the api credentials, you will need them while setting up the registry.
The registry is a node.js express app that serves the components. You can have multiple registries connected to a library, but you can't have multiple libraries connected to a registry. First, create a dir and install oc:
mkdir oc-registry && cd oc-registry
npm init
npm install oc --save
Then on the entry point, what you need on an index.js
file is pretty much:
var oc = require('oc');
var configuration = {
verbosity: 0,
baseUrl: 'https://my-components-registry.mydomain.com/',
port: 3000,
tempDir: './temp/',
cache: { verbose: false, refreshInterval: 600 },
s3: {
key: 'your-s3-key',
secret: 'your-s3-secret',
bucket: 'your-s3-bucket',
region: 'your-s3-region',
path: '//s3.amazonaws.com/your-s3-bucket/',
componentsDir: 'components'
},
env: { name: 'production' }
};
var registry = new oc.Registry(configuration);
if(registry.err){
return console.log(registry.err);
}
registry.start(function(err, app){
if(err){
console.log('Registry not started: ', err);
process.exit(1);
}
});
A component needs to end up as a html fragment. You can render components just on the client-side. Or, just on the server-side. Or, use the client-side rendering just as failover strategy for when the server-side rendering fails because the registry is not responding quickly or is down.
You do not need node.js to consume components on the server-side. The registry can provide you rendered components so that you can get server-side rendered components using any tech stack.
Then, components are immutable and the registry allows consumers to get any version of the component. So, when you create a component and you are the consumer too, you may choose to bind your site to the latest version of a component; if anyone else creates a component and you want to be sure it does not break your stuff, you can connect your site to just the latest patch, or minor version, etc.
You can get rendered components via the registry rest api.
curl http://my-components-registry.mydomain.com/hello-world
{
"href": "https://my-components-registry.mydomain.com/hello-world",
"version": "1.0.13",
"requestVersion": "",
"html": "<oc-component href=\"https://my-components-registry.mydomain.com/hello-world\" data-hash=\"cad2a9671257d5033d2abfd739b1660993021d02\" id=\"2890594349\" data-rendered=\"true\" data-version=\"1.0.13\">Hello John doe!</oc-component>",
"renderMode": "rendered"
}
Just place the html result anywhere and it will just work.
In case you would like to do the rendering yourself, try:
curl http://my-components-registry.mydomain.com/hello-world/~1.0.5 -H render-mode:pre-rendered
{
"href": "https://my-components-registry.mydomain.com/hello-world/~1.0.5",
"version": "1.0.13",
"requestVersion": "~1.0.5",
"data": {
"name": "John doe"
},
"template": {
"src": "https://s3.amazonaws.com/your-s3-bucket/components/hello-world/1.0.13/template.js",
"type": "handlebars",
"key": "cad2a9671257d5033d2abfd739b1660993021d02"
},
"type": "oc-component",
"renderMode": "pre-rendered"
}
In this case you can get the compiled view + the data, and you can do the rendering, eventually, interpolating the view-model data and rendering the compiled view with it.
First install the node.js client in your project, setup the api binding, and then link a component:
npm install oc -g
npm install oc --save
oc registry add http://my-components-registry.mydomain.com/
oc link hello-world 1.0.X
Then, this is what you would do with a simple node.js http app:
var http = require('http'),
oc = require('oc');
var client = new oc.Client();
http.createServer(function (req, res) {
client.renderComponent('hello-world', function(err, html){
res.writeHead(200, {'Content-Type': 'text/html'});
res.end('<html><head></head><body>' + html + '</body></html>');
});
}).listen(4000);
Open http://localhost:4000/
and enjoy!
To make this happen, your components' registry has to be publicly available. This is all you need:
<html>
<head></head>
<body>
<oc-component href="http://my-components-registry.mydomain.com/hello-world/1.X.X"></oc-component>
<script src="http://my-components-registry.mydomain.com/oc-client/client.js" />
</body>
</html>
When the registry is slow or returns errors while doing server-side rendering, you may want to unblock the rendering and postpone the rendering to make it happen on the client-side after the DOM is loaded. If your registry is publicly available and you use the node.js client, this is done automatically. Cool, isn't it? When on the client-side, once the dom is loaded, a retry rendering attempt via javascript will happen every 10 seconds until the component is rendered.
If for some reasons you want to avoid client-side rendering when using the node.js client, you can do:
var http = require('http'),
oc = require('oc');
var client = new oc.Client({ disableFailoverRendering: true });
http.createServer(function (req, res) {
client.renderComponent('hello-world', function(err, html){
res.writeHead(200, {'Content-Type': 'text/html'});
res.end('<html><head></head><body>' + html + '</body></html>');
});
}).listen(4000);
MIT
FAQs
A framework for developing and distributing html components
The npm package oc receives a total of 883 weekly downloads. As such, oc popularity was classified as not popular.
We found that oc demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
PEP 770 proposes adding SBOM support to Python packages to improve transparency and catch hidden non-Python dependencies that security tools often miss.
Security News
Socket CEO Feross Aboukhadijeh discusses open source security challenges, including zero-day attacks and supply chain risks, on the Cyber Security Council podcast.
Security News
Research
Socket researchers uncover how threat actors weaponize Out-of-Band Application Security Testing (OAST) techniques across the npm, PyPI, and RubyGems ecosystems to exfiltrate sensitive data.