I have these dependencies:
A -> B -> C -> D
D has a vulnerability and there's no version out with the fix (the PR is out there but the repo is dead).
I'd like to do something like:
"resolutions": {
"D": "myDwithTheFix#1.0.0"
}
Is there a way to do something like that?
If not I have to create my own myA -> myB -> myC -> myD ...
If you want to know, D is underscore.string and its ReDOS.
EDIT:
I think my question only makes sense if it is combined with some redirection feature from a bundler, like webpack aliases.
Because if I replace D for myDwithTheFix, I'd need to replace or redirect also the references from C to point to myDwithTheFix instead of D.
Related
I have a prolog-file (name definitions.pl) of this kind of type:
:- module(definitions,[]).
:-op(699, xfx, :=).
:-op(599, xfy, ∪).
C := (A ∪ B) :- union(A, B, C).
My aim is to use this file as module in another file test.pl. To integrate it I tried:
:-use_module(definitions).
But for some reason its not possible to make statements like:
X:=[1,2]∪[3,4].
after loading test.pl into swipl. I also tried:
:- module(definitions,[:=/2, ∪/2]).
:-op(699, xfx, :=).
:-op(599, xfy, ∪).
but this gives some operator exprected error. What is the correct way to use operators in prolog-modules?
Move the operator definitions into the module export list:
:- module(definitions, [
(:=)/2, op(699, xfx, :=),
op(599, xfy, ∪)
]).
:- use_module(library(lists), [union/3]).
C := (A ∪ B) :-
union(A, B, C).
Usage example (assuming a definitions.pl file with the above contents in the current working directory):
?- use_module(definitions).
true.
?- X:=[1,2]∪[3,4].
X = [1, 2, 3, 4].
I am seeking to re-use the same role/class names in a child module as in its parent. You know, like a specialization.
The aim is to be able to re-use the same script code for both the parent and child Series variants by simply changing use Dan to use Dan::Pandas at the top.
I am trying to stick to role rather than class compostion where I can so that the behaviours can be applied to other objects with eg. class GasBill does Series;
Here is the MRE:
me#ubuntu:~/spike# tree
.
├── lib
│ ├── Dan
│ │ └── Pandas.rakumod
│ └── Dan.rakumod
└── spike.raku
Dan.rakumod:
1 unit module Dan;
2
3 role Series is export {
4 method no { "no" }
5 }
Pandas.rakumod:
1 unit module Dan::Pandas;
2
3 use Dan;
4
5 role Series does Dan::Series is export {
6 method yo { "yo" }
7 }
spike.raku:
1 use lib './lib';
2 use Dan::Pandas;
3
4 my $s = Series.new; #version 1
5 #my $s = Dan::Pandas::Series.new; #version 2 "fqm"
6
7 say $s.no, $s.yo, $s.^name;
My version 1 says:
No appropriate parametric role variant available for 'Dan::Series':
Ambiguous call to '(Dan::Series)'; these signatures all match:
(::$?CLASS ::::?CLASS Mu $)
(::$?CLASS ::::?CLASS Mu $)
in block <unit> at spike.raku line 4
My version 2 says:
Could not find symbol '&Series' in 'Dan::Pandas'
in block <unit> at spike.raku line 5
I am trusting that raku does have a way to do this, but darned if I can work it out!
TL;DR You need a solution that avoids having two roles with the same full name.
Golf
role R {}
role R {}
R.new
displays:
No appropriate parametric role variant available for 'R':
Ambiguous call to '(R)'; these signatures all match:
(::$?CLASS ::::?CLASS Mu $)
(::$?CLASS ::::?CLASS Mu $)
(See Gut-referencing warning when composing stubbed role for a bit more discussion of the error message.)
A solution
Just Dan.
Dan.rakumod:
unit module Dan;
role Series is export { method no { "no" } }
spike.raku:
use lib '.';
use Dan;
my $s = Series.new;
.say for $s.?no, $s.?yo, $s.^name;
Running spike displays:
no
Nil
Dan::Series
Introduce Dan::Pandas.
Alter Dan so variant modules can use it without them importing Dan's unqualified Series symbol into their lexical scopes.
(Because otherwise Dan's unqualified Series symbol ends up being in their lexical scopes as well as their own unqualified Series symbol, and you get the "Ambiguous call" error.)
Dan:
unit module Dan;
role Series is export { method no { "no" } }
class Dan::Variant-Export-Dummy-Type is export(:Variant-Exports) {}
The change is the last line, a dummy declaration with a new export tag. (Introducing the new tag some cleaner way is left as an exercise for readers.)
Dan::Pandas:
unit module Dan::Pandas;
use Dan :Variant-Exports;
role Series does Dan::Series is export { method yo { "yo" } }
The change is using the new :Variant-Exports tag with the use Dan ... statement. This stops Dan's Series role being imported under that unqualified name into Dan::Pandas.
User programs will now work as expected/wanted.
Just change the use statement in spike.raku:
use lib '.';
use Dan::Pandas;
my $s = Series.new;
.say for $s.?no, $s.?yo, $s.^name;
Running with just this change for user programs:
no
yo
Dan::Pandas::Series
Note how there's no need for programs using using these modules to know about the :Variant-Exports tag. That's just an internal detail of the Dan module and the Dan::Pandas etc modules that lets them avoid the unintended role variant duplication problem shown at the start of this answer.
If I'm understanding correctly, you don't need/want to use the non-specialized role in the final module (that is, you aren't using the Series defined in Dan.rakumod in spike.raku – you're only using the specialized Series defined in Pandas.rakumod). Is that correct?
If so, the solution is simple: just don't export the Series from Dan.rakumod – it's still our scoped (the default for roles) so you can still use it in Pandas.rakumod exactly the way you currently do (Dan::Series). But, since it's not exported, you it won't create a name clash with the non-prefixed Series.
My Solution
Taking the advice of #codesections [that FQMs can be used without is export] and #raiph [that you can qualify the export with e.g. is export(:ALL)], then - yes - there is a neat way to do this.
viz. https://docs.raku.org/language/modules#Exporting_and_selective_importing
Turns out that this is low touch (just change two lines) and, as I originally hoped, something that raku designers have anticipated.
Here is the code from my OP adjusted...
Dan.rakumod:
1 unit module Dan;
2
3 role Series is export(:ALL) { #<== added the selective export
4 method no { "no" }
5 }
Pandas.rakumod (no change):
1 unit module Dan::Pandas;
2
3 use Dan;
4
5 role Series does Dan::Series is export {
6 method yo { "yo" }
7 }
spike.raku:
1 use lib './lib';
2 #use Dan::Pandas; #\ either of these work
3 use Dan :ALL; #/ <== use :ALL to get 'Series'
4
5 my $s = Series.new;
6
7 say $s.no, $s.yo, $s.^name; #No such method 'yo' if Pandas not used
Warning: The explanation may be a bit long. In case you are in a hurry, just skip directly to the end of the question, where I summarise what I'm looking for based in my problem.
Here is the problem: I have to load a LESS file (from domain A) from another LESS file (from domain B), and build them on real time with LESS.js. Until then, no harm; the instructions in the start of the official website work out of the box.
<link rel="stylesheet/less" type="text/css" href="styles.less" />
<script src="//cdnjs.cloudflare.com/ajax/libs/less.js/3.9.0/less.min.js" ></script>
However, there are other LESS files inside B (let's say module1/less, module2/less, and so on), and A should contain the #imports to those files. Also, there are multiple other domains similar to B (C, D, E...). That's where the problem starts. I couldn't find a proper way to do that, considering that I can't update C, D and E (other people need to do it, and for bureaucracy reasons they will only be able to do it after me), only A and B, so A needs to be compatible with the older version of C, D and E (in case they need any change).
When doing an #import inside an imported LESS file, its relative path is according to that same LESS file path, but since that LESS file may be loaded from B, C, D or E, I can't provide an absolute path out of the box.
What I tried (1): I surely need to find a way to provide the domain name from B to A. Firstly, I tried by adding something like that before the less.min.js line in the B domain HTML file:
<script>
less = {plugins: [{
install: function(less, pluginManager, functions) {
functions.add('getRootLessFolder', function() {
var getDomain = function() {
return window.location.protocol + "//" + window.location.host + "/";
}
return getDomain() + "less/";
});
}
}]}
</script>
And then adding that to the start of B's main LESS file:
#root-less-folder: getRootLessFolder();
So I could update the #imports in A to be like that:
#import "#{root-less-folder}module1/less";
That approach worked... until I tried using it with the older version of B, before making the changes mentioned above. In that way, LESS claims that #root-less-folder is undefined, even if I add (optional) to the #import.
What I tried (2): I also tried to use the paths property in server B, like that:
var getDomain = function() {
return window.location.protocol + "//" + window.location.host + "/";
}
var lessFolder = getDomain() + "less/";
less = {paths:[lessFolder]};
Because according to the documentation:
lessc --include-path=PATH1;PATH2 { paths: ['PATH1', 'PATH2'] }
If the file in an #import rule does not exist at that exact location, Less will look for it at the location(s) passed to this option. You might use this for instance to specify a path to a library which you want to be referenced simply and relatively in the Less files.
So I figured I could use it to make less find the LESS files automatically by just using the line below in A:
#import (optional) "module1/less";
So it wouldn't find module1/less in server A, but would find it in server B because of the paths property. Although, it doesn't seem to try to find module1/less in B. Instead, the Chrome Console spills the 404 error from server A, and the contents of module1/less from B are not present in the produced CSS style (no Console error either), like if it don't even tried.
What I need: I need a way to make method 1 or 2 work under those conditions, or even a method 3.
Being able to populate a LESS variable (if it is not populated only) would solve method 1;
Figuring out how LESS's paths is supposed to work may help using method 2;
Although, maybe you have another suggestion to that problem, which could work out as well.
I've managed to solve my problem. In case anyone else is having this trouble, I will describe what I did: apparently, while you can't reference variables that weren't defined, you can reference plugins that were not defined (in those cases, they are identified as strings).
So I added that before the less.min.js line in the B domain HTML file:
<script>
less = {plugins: [{
install: function(less, pluginManager, functions) {
functions.add('getRootLessFolder', function() {
var getDomain = function() {
return window.location.protocol + "//" + window.location.host + "/";
}
return getDomain() + "less/";
});
}
}]}
</script>
And updated the #imports in A to be like that:
#root-less-folder: getRootLessFolder();
#import (optional) "#{root-less-folder}module1/less";
So when getRootLessFolder is defined, the path is based in its returned value, and when it isn't, the path is "getRootLessFolder()module1/less", which will return a 404, but since it's an optional #import, that won't be a problem.
So if server B is updated, the change in server A is going to work. In case server B is not updated, the change is server A won't break it either.
Two questions:
How can I find what are the modules that are pre-loaded in my ocaml session?
Given a module, how can I list its contents?
In SML, a standard "trick" was to define a dummy module and open in it a module the contents of which I wanted to inspect. The signature of the dummy module would then list the contents of the module in SML. This does not work in ocaml.
Found this: To see the packages pre-loaded, use #use "topfind";; to use the topfind package, and the #list;; will list the pre-loaded packages!
I don't know a way to list the modules currently loaded.
To show the contents of a module:
# #show_module Pervasives;;
module Pervasives :
sig
external raise : exn -> 'a = "%raise"
external raise_notrace : exn -> 'a = "%raise_notrace"
val invalid_arg : string -> 'a
. . .
val unsafe_really_input : in_channel -> bytes -> int -> int -> unit
val do_at_exit : unit -> unit
end
The initial set of top-level directives is given in Section 9.2 of the OCaml manual.
I'm currently learning to code Erlang. I have a web application on top of Chicago Boss.
I have a model called Todo, and I would like to offer CRUD operations on it as a REST API.
In my PUT method I have this code:
index('PUT', [Id]) ->
Todo = boss_db:find(Id),
Body = element(2, mochijson:decode(Req:request_body())),
%% Set the new values
NewTodo = Todo:attributes([
{subject, proplists:get_value("subject", Body)},
{done, proplists:get_value("done", Body)}
])
,
{json, [{todo, element(2, NewTodo:save())}]}.
How can I optimize this code fragment? Or is this already the best possible?
Is there some "smarter" way to change the keys of a proplist to atom keys? Like this:
[{"subject", "Foo"}] -> [{subject, "Foo"}].
I also find it kind of tedious to assign a Todo variable and then have a NewTodo. Sadly I can't find some good example Erlang Chicago Boss apps on github that I can check out.
You always can do something like this:
t([{"subject", V}|T]) -> [{subject, V}|t(T)];
t([{"done" , V}|T]) -> [{done, V}|t(T)];
t([_ |T]) -> t(T) ; % optional garbage ignoring clause
t([]) -> [].
But I doubt, it will be significant speed improvement in your case.
May be you will be able squeeze last bit from this:
-compile({inline, [t/1]}).
t(L) -> t(L, []).
t([{"subject", V}|T], A) -> t(T, [{subject, V}|A]);
t([{"done" , V}|T], A) -> t(T, [{done, V}|A]);
t([_ |T], A) -> t(T, A); % optional garbage ignoring clause
t([], A) -> A.
Which is worth only for benchmark code competitions ;-) (Note there is not lists:reverse/1 call in last clause. It would be ruining improvement form previous version.)
P.S.: If you think I'm micro-optimization freak, you are right, so I would replace lists:reverse/1 call with lists:reverse/2 to use BIF directly and save some more time ;-)
Unfortunately I cannot comment on Hynek's answer, but as Erlang newbie, my first guess would have been to go for something along the lines of:
lists:map(fun({A, B}) -> {list_to_atom(A), B} end, [X || {Y, Z}=X <- List, is_list(Y)]).
You cannot really avoid the NewTodo assignment
How about
index('PUT', [Id]) ->
Body = element(2, mochijson:decode(Req:request_body())),
OldTodo = boss_db:find(Id),
NewTodo = OldTodo:attributes([ {list_to_atom(A),B} || {A,B}<-Body ]),
{json, [{todo, element(2, NewTodo:save())}]}.