Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
The base of Frint
App
: The base for Core and Widgets.Core
: The root app, that renders to DOM directly.Widget
: Apps that register themselves to Core.Provider
: Dependency for your apps (Core and Widgets).Plugin
: Modules that extend the core framework.Let's import the necessary functions from the library first:
const Frint = require('frint');
const { createCore } = Frint;
Now we can create our App:
const CoreApp = createCore({ name: 'MyAppName' });
Instantiate the Core app:
const app = new CoreApp(); // now you have the Core app's instance
// usually we set the core app to `window.app`,
// so Widgets coming in from separate bundles can register themselves
window.app = app;
const { createWidget } = Frint;
const MyWidget = createWidget({ name: 'MyWidgetName' });
To register the Widget in your Core App:
window.app.registerWidget(MyWidget);
Providers are dependencies for your Frint application (not to be confused with npm
packages).
They can be set at Core app level, at Widget level, or even only at Core app level but cascade them to the Widgets.
For values that are already known:
const CoreApp = createCore({
name: 'MyAppName',
providers: [
{
name: 'foo',
useValue: 'foo value here'
}
]
});
const app = new CoreApp();
app.get('foo') === 'foo value here';
If you want to get the value from a function (will be called only once during App construction):
const CoreApp = createCore({
name: 'MyAppName',
providers: [
{
name: 'bar',
useFactory: function () {
return 'bar value';
}
},
]
});
const app = new CoreApp();
app.get('bar') === 'bar value';
You can also have classes defined as providers. They will be instantiated when the App is constructed, and then made available to you:
class Baz {
getValue() {
return 'baz value';
}
}
const CoreApp = createCore({
name: 'MyAppName',
providers: [
{
name: 'baz',
useClass: Baz
}
]
});
const app = new CoreApp();
app.get('baz').getValue() === 'baz value';
If you wish to cascade a provider from Core App to your Widgets, you can:
const CoreApp = createCore({
name: 'MyCoreApp',
providers: [
{
name: 'window',
useValue: window, // the global `window` object
cascade: true,
}
]
});
const MyWidget = createWidget({
name: 'MyWidget'
});
const app = new CoreApp();
app.registerWidget(MyWidget);
app.get('window') === window;
app.getWidgetInstance('MyWidget').get('window') === window;
app
: The current App in scope (Core or Widget)rootApp
: Always refers to the top-most App (which is Core)Providers can also list their dependencies (by their names).
class Baz {
constructor({ foo, bar, app }) {
// I have access to both `foo` and `bar` here.
// And I can access the scoped `app` instance too.
}
}
const CoreApp = createCore({
name: 'MyCoreApp',
providers: [
{
name: 'foo',
useValue: 'foo value'
},
{
name: 'bar',
useFactory: function ({ foo }) {
return `In bar, I have foo's value: ${foo}`
},
deps: ['foo'] // value's of provider names listed here will be fed as arguments
},
{
name: 'baz',
useClass: Baz,
deps: ['foo', 'bar', 'app']
}
],
})
When cascading providers from Core to Widgets, it is likely you may want to scope those values by the Widget they are targeting. It is applicable in only useFactory
and useClass
usage, since they generate values.
const CoreApp = createCore({
name: 'MyCoreApp',
providers: [
{
name: 'theNameOfTheApp',
useFactory: function ({ app }) {
return app.getOption('name');
},
deps: ['app'],
cascade: true,
scoped: true,
}
]
});
const MyWidget = createWidget({
name: 'MyWidget'
});
const app = new CoreApp();
app.registerWidget(MyWidget);
app.get('theNameOfTheApp') === 'MyCoreApp';
app.getWidgetInstance('MyWidget').get('theNameOfTheApp') === 'MyWidget';
Plugins help extend the core of the framework.
Plugins can be installed as follows:
const Frint = require('frint');
const FooPlugin = require('frint-plugin-foo');
Frint.use(FooPlugin);
A plugin in its simplest form, is an object exposing a install
function. The function accepts Frint
, which can be extended further from there.
// frint-plugin-foo/index.js
module.exports = {
install: function (Frint, options = {}) {
// extend `Frint` here
}
};
use(Plugin, options = {})
Plugin
(Object
[required])options
(Object
[optional])void
App
The base App class.
Core and Widget extend this class.
createCore(options)
options
(Object
)
options.name
: (String
[required]): Name of your Appoptions.initialize
: (Function
[optional]): Called when App is constructedoptions.providers
: (Array
[optional]): Array of provider objectsApp
: The generated App class based on options
.
createWidget(options)
Same as createCore
, but intended for creating Widgets, that get registered to Core apps.
createClass(methods)
Creates and returns a ES6 compatible class.
Useful in non-ES6 compatible environments.
options
(Object
)
initialize
(Function
): To be used as a regular class constructor.Function
: ES6 compatible class.
const app = new App();
The App
instance (either Core or Widget):
app.getOption(key)
key
(String
)Any
.
app.getOption('name')
would give you MyAppName
string.
app.getRootApp()
Gives you the Core App instance.
app.getProviders()
Gives you an array of provider definitions as passed while creating the App class.
Array
.
app.getProvider(name)
Gives you the provider's original definition.
name
(String
): The name of the provider that you wantObject
: The provider definition
Not to be confused with the computed value of the provider.
app.get(name)
Gives you the computed value of the provider.
name
(String
): The name of the providerAny
: The computed value of the provider.
app.getWidgets$(regionName = null)
regionName
(String
[optional]): Filter the list of widgets by region names if neededObservable
: That emits an array of most recent available Widgets.
app.registerWidget(Widget, options = {})
Register Widget class to Core app.
Widget
(App
): The widget class created via createWidget
.options
(Object
[optional])
name
(String
[optional]): If the Widget's name needs to be overridden.multi
(Boolean
[optional]): If the Widget is a multi-instance widget (defaults to false
)void
app.hasWidgetInstance(name, region = null, regionKey = null)
Check if Widget instance is available or not.
name
(String
): The name of the Widget that you are looking forregion
(String
[optional]): If you want the Widget of a specific regionregionKey
(String
[optional]): If it is a multi-instance Widget, then the lookup can be scoped by region's keys.Boolean
.
app.getWidgetInstance(name, region = null, regionKey = null)
Gets the Widget instance if available.
name
(String
): The name of the Widget that you are looking forregion
(String
[optional]): If you want the Widget of a specific regionregionKey
(String
[optional]): If it is a multi-instance Widget, then the lookup can be scoped by region's keys.App|Boolean
: The widget instance, or false if not availble.
app.getWidgetOnceAvailable$(name, region = null, regionKey = null)
Returns an Observable, which emits with the Widget's instance once it is available.
name
(String
): The name of the Widget that you are looking forregion
(String
[optional]): If you want the Widget of a specific regionregionKey
(String
[optional]): If it is a multi-instance Widget, then the lookup can be scoped by region's keys.Observable
: Emits the Widget instance once found, only once.
app.instantiateWidget(name, region = null, regionKey = null)
Instantiates the registered Widget class, (for the targetted region/regionKey if it is a multi-instance Widget).
name
(String
): The name of the Widget that you are looking forregion
(String
[optional]): If you want the Widget of a specific regionregionKey
(String
[optional]): If it is a multi-instance Widget, then the lookup can be scoped by region's keys.Array
: The updated collection of widgets.
FAQs
Core plugin for Frint
The npm package frint receives a total of 227 weekly downloads. As such, frint popularity was classified as not popular.
We found that frint demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 8 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
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.