I am using Postman v6.1.4. I am using environment variables heavily. But it appears that pm.environment.get() is not evaluating embedded variables.
I have the following env vars defined in the environment:
addFavDest1:{"ownerId":"{{addFavDest1_ownerId}}","url":"{{addFavDest1_url}}",...}
...
addFavDestArray1:[{{addFavDest1}},{{addFavDest2}},{{addFavDest3}}]
The request body of my API contains:
{{addFavDestArray1}}
The request is sent successfully, with the data I expect, evaluating all of the embedded variables in my environment.
However, when I try to access that env var in my test script, the embedded variables are not being evaluated. For instance, the following:
var addFavDestArray1 = pm.environment.get('addFavDestArray1')
Returns [{{addFavDest1}},{{addFavDest2}},{{addFavDest3}}], with the variables not evaluated.
Is there some way to have the embedded variables evaluated in the environment?
So, in order to handle this situation, I created the following common function that I call from all my tests instead of pm.environment.get('var1') or environment['var1] or environment.var1.
/* funcGetAndEvalEnvVar */
var funcGetAndEvalEnvVar = (varName) => {
const EMBEDDED_VAR_REGEX = new RegExp(`{{\\w+}}`, 'g');
var varValue = environment[varName];
var evalVarValue = varValue;
var reMatch;
while (reMatch = EMBEDDED_VAR_REGEX.exec(varValue)) {
var embeddedVar = reMatch[0];
var embeddedVarName = embeddedVar.slice(2, -2);
if (environment.hasOwnProperty(embeddedVarName)) {
var embeddedVarValue = funcGetAndEvalEnvVar(embeddedVarName);
evalVarValue = evalVarValue.replace(new RegExp(embeddedVar, 'g'), embeddedVarValue);
}
}
return evalVarValue;
};
Related
I'm trying to insert an environment variable "GATSBY_EX_ENV" inside a window property to make it available to external scripts.
and GATSBY_EX_ENV is defined in my environment files alongside numerous other env variables which are accessed at runtime within React components. So I know it's declared correctly and that our env variables are generally working.
Right now in my gatsby-browser.js I am doing this:
export const onClientEntry = () => {
window.onload = () => {
var EXT = location.host
.split('.')
.filter(x => x !== 'www' && x && x !== DOMAIN && x !== 'com')[0];
// additional parsing
window._external.properties = { env: EXT };
}
}
This does work, but it's clunky and brittle. I want to replace that URL parsing with:
window._external.properties = { env: process.env.GATSBY_EX_ENV }
But when I do, my local develop site fails to load with the error "process is not defined". Should I be placing this code in a different method?
I am trying to pass arguments to MSBuild 2.0. After research it appears that I need to do this using variables, but I cannot figure out how to incorporate this into my queue request below. I have tried parameters but that does not seem to work. Here is what I am trying to tell MSBuild #" /p:OctoPackPackageVersion=" + releaseNumber. This worked with the XAML build using IBuildRequest.ProcessParameters.
var buildClient = new BuildHttpClient(new Uri(collectionURL), new
VssCredentials(true));
var res = await buildClient.QueueBuildAsync(new Build
{
Definition = new DefinitionReference
{
Id = targetBuild.Id
},
Project = targetBuild.Project,
SourceVersion = ChangeSetNumber,
Parameters = buildArg
});
return res.Id.ToString();
vNext build system is different with legacy XAML build system, you cannot pass variable to build tasks in the build definition directly when queue the build. The code you used updated the build definition before queue the build which means that the build definition may keep changing if the variable changed.
The workaround for this would be add a variable in your build definition for example "var1" and then use this variable as the arguments for MSBuild Task:
With this, you will be able to pass the value to "var1" variable when queue the build without updating the build definition.
Build build = new Build();
build.Parameters = "{\"var1\":\"/p:OctoPackPackageVersion=version2\"}";
// OR using Newtonsoft.Json.JsonConvert
var dict = new Dictionary<string, string>{{"var1", "/p:OctoPackPackageVersion=version2"}};
build.Parameters = JsonConvert.SerializeObject(dict)
I have found this solution and it works for me excellent. I set custom parameters for convenience in build definition without updating on server:
foreach (var variable in targetBuildDef.Variables.Where(p => p.Value.AllowOverride))
{
var customVar = variables.FirstOrDefault(p => p.Key == variable.Key);
if (customVar == null)
continue;
variable.Value.Value = customVar.Value.TrimEnd('\\');
}
And then set variables values in build parameters:
using (TfsTeamProjectCollection ttpc = new TfsTeamProjectCollection(new Uri(tFSCollectionUri)))
{
using (BuildHttpClient buildServer = ttpc.GetClient<BuildHttpClient>())
{
var requestedBuild = new Build
{
Definition = targetBuildDef,
Project = targetBuildDef.Project
};
var dic = targetBuildDef.Variables.Where(z => z.Value.AllowOverride).Select(x => new KeyValuePair<string, string>(x.Key, x.Value.Value));
var paramString = $"{{{string.Join(",", dic.Select(p => $#"""{p.Key}"":""{p.Value}"""))}}}";
var jsonParams = HttpUtility.JavaScriptStringEncode(paramString).Replace(#"\""", #"""");
requestedBuild.Parameters = jsonParams;
var queuedBuild = buildServer.QueueBuildAsync(requestedBuild).Result;
First, the new build on TFS2015 which is called vNext build not MSbuild 2.0.
Which you are looking for should be Build variables. Variables give you a convenient way to get key bits of data into various parts of your build process. For the variable with Allow at queue time box checked you could be enable allow your team to modify the value when they manually queue a build.
Some tutorials may be helpful for using variables:
TFS Build 2015 (vNext) – Scripts and Variables
Passing Visual Studio Team Services build properties to MSBuild
Patrick, I was able to find a work around to my issue by updating the build definition. This is definitely not ideal but it works. As you can see below I am trying to add to the msbuild args already present. If you know a better way let me know. I really appreciate you taking the time to look at my question.
public static async Task<string> QueueNewBuild(string project, BuildDefinitionReference targetBuild, string collectionURL, string ChangeSetNumber, string ReleaseNumber, bool CreateRelease)
{
var buildClient = new BuildHttpClient(new Uri(collectionURL), new VssCredentials(true));
await Task.Delay(1000).ConfigureAwait(false);
var buildDef = await buildClient.GetDefinitionAsync(targetBuild.Project.Id, targetBuild.Id);
BuildDefinitionVariable OrigMSbuildvar = buildDef.Variables["MSBuildArgs"];
buildDef.Variables["MSBuildArgs"].Value = OrigMSbuildvar.Value + " /p:OctoPackPackageVersion=" + ReleaseNumber.ToString();
await Task.Delay(1000).ConfigureAwait(false);
buildDef = await buildClient.UpdateDefinitionAsync(buildDef);
await Task.Delay(1000).ConfigureAwait(false);
Build build = new Build
{
Definition = new DefinitionReference
{
Id = targetBuild.Id
},
Project = targetBuild.Project,
SourceVersion = ChangeSetNumber
};
await Task.Delay(1000).ConfigureAwait(false);
var res = await buildClient.QueueBuildAsync(build);
buildDef.Variables["MSBuildArgs"].Value = OrigMSbuildvar.Value;
await Task.Delay(1000).ConfigureAwait(false);
buildDef = await buildClient.UpdateDefinitionAsync(buildDef);
return res.Id.ToString();
}
I'm new to breeze, this looks like a bug, but thought I'd ask here in case I just don't get it.
Setup loading metadata:
var metadataStore = new breeze.MetadataStore();
metadataStore.importMetadata(metadata);
queryOptions = new breeze.QueryOptions( {
fetchStrategy: breeze.FetchStrategy.FromLocalCache
});
mgr = new breeze.EntityManager({
serviceName: 'breeze',
metadataStore: metadataStore,
queryOptions: queryOptions
});
Executing local query explicitly works:
var q = breeze.EntityQuery.from("Boards")
.toType('Board')
.where('isImplicit', 'equals', withImplicits)
.orderBy('name');
return manager.executeQueryLocally(q) // returns result
But using query.using doesn't:
var q = breeze.EntityQuery.from("Boards")
.toType('Board')
.where('isImplicit', 'equals', withImplicits)
.orderBy('name');
q = q.using(breeze.FetchStrategy.FromLocalCache)
return manager.executeQuery(q)
UPDATE: To clarify, the above throws an error as it tries to fetchMetdata and there is no endpoint to fetch from. If I monkey patch the code below, it works fine. It seems like if the dataService .hasServerMetadata, you don't need to fetch it. I'm creating a test harness for a breeze adapter, so I want to be able to run without the backend
Looks like problem is this line in EntityManager:
if ( (!dataService.hasServerMetadata ) || this.metadataStore.hasMetadataFor(dataService.serviceName)) {
promise = executeQueryCore(this, query, queryOptions, dataService);
} else {
var that = this;
promise = this.fetchMetadata(dataService).then(function () {
return executeQueryCore(that, query, queryOptions, dataService);
});
}
I believe line should be if( dataService.hasServerMetadata || ..., but being new to Breeze thought I'd ask here before opening GH issue.
EntityManager.executeQueryLocally is a synchronous function and you can use its result immediately. i.e.
var myEntities = myEntityManager.executeQueryLocally(myQuery);
Whereas EntityManager.executeQuery is an asynchonous function ( even if the query has a 'using' call that specifies that this is a local query). So you need to call it like this:
var q2 = myQuery.using(breeze.FetchStrategy.FromLocalCache);
myEntityManager.executeQuery(q2).then(function(data) {
var myEntities = data.results;
});
The idea behind this is that with executeQuery you treat all queries in exactly the same fashion, i.e. asynchronously, regardless of whether they are actually asynchronous under the hood.
If you want to create an EntityManager that does not go to the server for metadata you can do the following:
var ds = new breeze.DataService({
serviceName: "none",
hasServerMetadata: false
});
var manager = new breeze.EntityManager({
dataService: ds
});
I get a bunch of different URL from my sources and what I would like is to redirect to the same URL, but with campaign data added to URL (to track the referred clicks).
For example I have these URLs:
www.example.com/category/product/name.html
www.example.com/id_product=5
I want to add at the end the following: utm_source=SOURCE&utm_medium=MEDIUM&utm_campaign=CAMPAIGN
And the URLs to become
www.example.com/category/product/name.html?utm_source=SOURCE&utm_medium=MEDIUM&utm_campaign=CAMPAIGN
www.example.com/id_product=5&utm_source=SOURCE&utm_medium=MEDIUM&utm_campaign=CAMPAIGN
How to I correctly check and cover all the cases if a URL string has parameters, and add mine?
I want to do it in node.js
Thank you
Elaborating on #snkashis, a similar but arguably more elegant solution, again using node's url module, is:
var addQueryParams = function (cleanUrl) {
var obj = url.parse(cleanUrl, true, false);
obj.query['utm_source'] = 'SOURCE';
obj.query['utm_medium'] = 'MEDIUM';
obj.query['utm_campaign'] = 'CAMPAIGN';
delete obj.search; // this makes format compose the search string out of the query object
var trackedUrl = url.format(obj);
return trackedUrl;
};
This works, because url.format first looks for search and, if it can't find it, it composes the query string from the query object
(taken from node url module documentation http://nodejs.org/api/url.html#url_url_format_urlobj )
search will be used in place of query
query (object; see querystring) will only be used if search is absent.
Here is a example showing different scenarios using Node's URL module.
var url = require('url');
var exurls = ["www.example.com/category/product/name.html","www.example.com/id_product=5?hasparam=yes"]
var to_append = "utm_source=SOURCE&utm_medium=MEDIUM&utm_campaign=CAMPAIGN";
for (i=0;i<exurls.length;i++) {
var parsedobj = url.parse(exurls[i],true,false);
//Below checks if param obj is empty.
if (Object.keys(parsedobj.query).length!==0) {
var newpath = parsedobj.href+"&"+to_append;
}
else {
var newpath = parsedobj.href+"?"+to_append;
}
console.log(newpath);
}
Connect will help you:
var connect = require('connect');
var app = connect();
app.use(connect.query());
app.use(function (req, res, next) {
console.log(req.query);
res.end(JSON.stringify(req.query));
});
app.listen(3000);
This script is getting Microsoft JScript runtime error: Object expected on If (out_params.bGranted) line. It seems like this is related to a syntax error, but I can't find it. This code, in its current form, was basically copied from Invoking functions with `out` arguments, passing arguments by reference in JScript.
function main()
{
var provider_name = "StdRegProv";
var func_name = "CheckAccess";
var services = GetObject("winmgmts:{impersonationLevel=impersonate}!\\\\.\\root\\default"); // connect to WMI
var registry = services.Get(provider_name); // get provider
var in_params = registry.Methods_(func_name).InParameters.SpawnInstance_();
in_params.hDefKey = 0x80000001;
in_params.sSubKeyName = "Software\\Microsoft\\Shared Tools\\Proofing Tools\\1.0\\Override";
in_params.uRequired = 65536;
var out_params = services.ExecMethod(provider_name, func_name, in_params);
If (out_params.bGranted)
{
WScript.Echo("Has DELETE Access Rights on HKCU " + strKeyPath);
registry.DeleteKey (HKCU, strKeyPath);
}
Else
{
WScript.Echo("No DELETE Access Rights on HKCU " + strKeyPath);
}
}
main();
In JScript, keywords (and identifiers) are case-sensitive, so you cannot use If instead of if, Elseinstead of else, and so on.
In your example the script engine interprets If (out_params.bGranted) as a function call, which results in a runtime error since you obviously did not defined an If function.