Enable TypeScript eslint rule for only a section of code - typescript-eslint

Is it possible to enable an eslint rule for only a section of code and have it disabled for all other code?
In our case, we have a class:
export class HeaderWidget extends AbstractWidget implements HeaderWidget.State {
// tslint:disable-next-line:variable-name
public readonly widget_type: WidgetType = WidgetType.Header;
public text!: string;
public image_data!: string;
public image_data_alt!: string;
public hide_on_mobile!: boolean;
...
}
We want to make sure that any properties added to this class are snake_case. I found the naming-convention rule that I can enable with:
"#typescript-eslint/naming-convention": [
"error",
{
"format": ["snake_case"],
"selector": "classProperty"
}
]
but that enables the rule for all the code in the project. I just want to enable for properties in that specific class (or even better would be anything that extends AbstractWidget). I see additional config options like filter, custom and suffix but the docs say they apply to the identifier which leads me to believe they can't be used to pick properties within a certain class.
So I'm looking for a way to configure a rule and have it disabled by default but then enable it for a specific section of code without having to add /* eslint-disable naming-convention */ to every file.

I think I found a solution that will work for us. In the eslint.json overrides section you can have multiple configs for different files. So adding:
{
"files": ["*.model.ts"],
"rules": {
"#typescript-eslint/naming-convention": [
"error",
{
"format": ["snake_case"],
"selector": "classProperty"
}
]
}
}
will work for us because the classes we want this rule to apply to will always be in *.model.ts and the only other things in there are namespace and type which this rule will not apply to.

Related

When mapping Typesafe configuration to a bean class (ConfigBeanFactory) is there a way to flag mis-spelled attributes?

Our application is using a reference.conf to provide defaults for one of our POJO's that carries configuration information.
Say the Pojo is:
class Person {
String first;
String last;
// corresponding setters / getters not shown
}
The reference.conf has the defaults:
Person {
first: "joe"
last: "shmoe"
}
So if your application.conf had:
Person {
first: "mike"
}
Thus when you did this:
public static Person getInstance(Config config) {
return ConfigBeanFactory.create(config.getConfig("Person"), Person.class);
}
You'd get back a Person with first/last == mike/shmoe
Now..say I have some users who are not getting enough sleep, and one of them
misconfigures their application like this (mis-spelling 'first'):
Person {
frist: "mike"
}
The way I'm doing things now the Pojo loaded from this config has default first/last == joe/shmoe.
There is no warning about the mis-spelling ("frist").
I could write code to reflect against my Bean class and see what attributes the user provided which don't
correspond to the available setters, and then raise an error if any 'wrong' attributes are found.
But it seems like someone (maybe even the Typesafe config base library) must already have this feature.
Any pointer to a good existing way to do this very much appreciated.

Use Proguard 5.3 ,default type methods change to public type

I want to develop a private SDK(a jar file),some method is default permission,i want it can be called in current package only,like this:
/* package */
static String getApplicationId() {
return mApplicationId;
}
but,when use proguard to make jar later,this method change to public type,and the method name like this:
public static String c() {
return sApplicationId;
}
so i want know how to config proguard file.to make default permission method can't visiable when use this jar by proguard later,thanks
You should check your configuration, most likely you have the following setting enabled:
-allowaccessmodification
When obfuscating a library, you normally do not want this enabled, as you experience the effects as described in the question.

DunglasApiBundle - Trying to get the bundle to use Named Constructors rather than public constructor

I'm using the Dunglas api-platform bundle (https://github.com/api-platform/api-platform) for a new app.
Setup and installation went fine, GET requests are working.
While trying to create new objects using POST requests, I received errors about having a private constructor. My models are all made using a private constructor, and using named constructors instead.
Ideally i'm either looking for a way to have the bundle call my Named constructors, ... or someone to tell me my approach is completely wrong.
Services.yml
services:
resource.player:
parent: "api.resource"
arguments: [ "Name\\Space\\Player" ]
tags: [ { name: "api.resource" } ]
Player Object
class Player
{
private $name;
private function __construct()
{
}
public static function withName($playerName)
{
$player = new Player();
$player->name = $playerName;
return $player;
}
public function getName()
{
return $this->name;
}
}
Settings are pretty much all out of the box, following the introduction and setup in the documentation. I've skimmed through the Factory thing briefly - hoping that i'd be able to use a factory to create the objects, allowing me to call my own named constructors - but that doesn't seem to do what i think it does.
Any input regarding the use, boundaries or the setup is well appreciated.
API Platform (like most Symfony and Doctrine related libraries) is not designed to work with immutable objects like this one.
I suggest to create a typical mutable Entity as suggested in the doc:
class Player
{
private $name;
public static function setName($playerName)
{
$this->name = $playerName;
}
public function getName()
{
return $this->name;
}
}
If you really want to keep your immutable model, you'll need to implement yourself the Symfony\Component\PropertyAccess\PropertyAccessorInterface and use a CompilerPass to make API Platform using your own implementation. You will probably need to submit a patch to API Platform and to the Symfony Serializer Component to update the reference of the given object too because currently, both serializers actually update the current object and will not use the new instance returned by your with method.
I strongly encourage you to switch to typical mutable entities.

Handling plugins with configuration with Ninject

I'm writing an application where various bits of business logic can sit in separate assemblies, then those bits are used to build an object expecting two interfaces, something like this:
public interface ISubjectSource {}
public interface IStudySource {}
public class Worker
{
public Worker(ISubjectSource subjectSource, IStudySource studySource)
{
....
}
}
The seperate assemblies can contain various implementations of ISubjectSource and IStudySource. Then along with a config file:
"Study1":{
"assemblies":["Compare.Sql.dll"],
"mappingSource":"Compare.Sql.SqlSubjectSource,Compare.Sql",
"studySource":"Compare.Sql.SqlStudySource,Compare.Sql",
}
Which describes what is needed to build to worker for "Study1". My problem arrives when the various sources have their own dependencies (e.g. the Sql Sources take an interface that handles creating a connection whose connection string might come from different files).
So, my question boils down to: How do I tell Ninject that when I create a worker for study1, be sure it gets these objects, but when I create a worker for Study2, it gets this other set of objects?
Here's what we do:
We've got an interface IPlugin, with an identifier and an enumerable of modules.
public interface IPlugin
{
string Identification { get; }
IEnumerable<Type> Modules { get; }
}
The Types in Modules must all be inheriting from NinjectModule. Identification is what you refer to in your configuration, like "i want to use plugin SQLStudySource" or "i want to use plugin FileStudySource".
Then we are using https://github.com/ninject/ninject.extensions.conventions to bind all IPlugin implementations from a specific set of assemblies (like all assemblies in the plugin folder):
this.Bind(x => x.FromAssembliesInPath("foo")
.SelectAllClasses()
.InheritedFrom<IPlugin>()
.BindTo<IPlugin>());
Next you activate plugins (or rather their modules, respectively), according to configuration:
IEnumerable<Type> activatedPluginModules = kernel
.GetAll<IPlugin>()
.Where(plugin => configuration.ActivatedPluginIdentifications.Contains(plugin.Identification)
.SelectMany(x => x.Modules)
.Distinct();
foreach(Type module in activatedPluginModules)
{
kernel.Load(module);
}
That's about it.

How good is to have high-level interfaces?

Whats is best? Work with low-level methods receiving some arguments and dealing with it.
Or have a high-level interface in the objects that does exactly whats its name says?
eg.:
Low-level:
<?php
class Html {
public function renderSelect($name, $options) {
//
}
}
class Repository {
public function lists($repositoryName, $keyColumn, $valueColumn) {
//
}
}
# usage
$html->renderSelect('campaign_id', $repository->lists('campaigns', 'id', 'name'));
$html->renderSelect('account_id', $repository->lists('accounts', 'id', 'company'));
High-level:
<?php
class Html {
public function renderSelect($name, $options) {
//
}
public function renderCampaignsSelect() {
return $this->renderSelect('campaign_id', $repository->listsCampaigns());
}
public function renderAccountsSelect() {
return $this->renderSelect('account_id', $repository->listsAccounts());
}
}
class Repository {
public function lists($repositoryName, $keyColumn, $valueColumn) {
//
}
public function listsCampaigns() {
return $this->lists('campaigns', 'id', 'name');
}
public function listsAccounts() {
return $this->lists('accounts', 'id', 'company');
}
}
# usage
$html->renderCampaignsSelect();
$html->renderAccountsSelect();
Notably the high-level option will grow as applications scales, if more entities comes up, more methods will be needed, like: added Sponsor will have renderSponsorsSelect and listsSponsors. But its usage makes the code very smooth to read and we can do different implementations for each method.
What do you think?
Thanks.
Low-level (fine-grained) methods are more reusable. High-level(coarser granularity) methods are easier to use. I think the closer to the user interface layer the more higher level methods are preferred, it can hide implementation details and is easier to read as you metioned.
Use what you call "low-level" in generic API, frameworks. A kind of libraries designed to be used in many other projects in different domains.
Examples: Symfony, Zend Framework.
Use what you call "high-level" in domain models. Projects targeted to solve a specific problem. But instead of calling it high-level, say domain-specific or using ubiquitous language.
Examples: phpBB3, Wordpress, your site generaing funny pictures of cats with customised text.