Code Monkey home page Code Monkey logo

json-document-transforms's Introduction

JSON Document Transfoms

NuGet package Build status

JSON Document Transforms (JDT) library. Perform transformations on JSON files using another JSON as the specification. This is the C# implementation.

For more information on how JDT works, see the JDT Wiki

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

json-document-transforms's People

Contributors

davilimap avatar icnocop avatar jviau avatar microsoft-github-policy-service[bot] avatar microsoftopensource avatar msftgits avatar ttstanley avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

json-document-transforms's Issues

Release request

Hello,
Could you please create new nuget release which would include fix for issue #16?

Thank you

Add support for root-level arrays

Currently, the root-level element cannot be an array, the transformation will fail. First off, I think we need to add better error handling to improve the user experience. Then, look into supporting this without breaking transformations.

See: microsoft/slow-cheetah#92

Json transformation loses data

Copied from: microsoft/slow-cheetah#107

Trying to replace whole file which contains date with zero'es as milliseconds results in transformed file losing those zero'es

Transformation file:
{ "value": "2017-12-20T20:10:00.0000000" }

Transformed file:
{ "value": "2017-12-20T20:10:00" }

Expected transformed file:
{ "value": "2017-12-20T20:10:00.0000000" }

Concurrent transforms with the same source and/or transform file can fail

When using slow cheetah to transform json files we discovered that the transforms would fail intermittently. This was particularly frequent when building a project targeting multiple frameworks (net461 and netcore2.1 in this instance). The parallel build behaviour of msbuild meant it would regularly attempt to perform the same transforms at the same time (once for each target framework).

This would result in msbuild output similar to:

[17:52:50] [Step 6/12]      2>UpdateLocalAppSettings:
[17:52:50] [Step 6/12]          Beginning transformation.
[17:52:50] [Step 6/12]     15>UpdateLocalAppSettings:
[17:52:50] [Step 6/12]          Beginning transformation.
[17:52:50] [Step 6/12]          Transformation failed.

This seems to be caused by the source file being opened with exclusive access for the duration of the transform. The files need to be opened with a FileShare mode of Read to allow concurrent transformations.

Is it possible to rearrange nodes in source json

Considering this example, I have a json that looks like this

{
    "root": {
        "second-level":{
            "third-level":[1,2,3,4]
        }
    }
}

If I want to move the value of "third-level" up to the second level, like this

{
    "root": {
        "second-level":[1,2,3,4]
    }
}

How should I write the transform string, or is it supported?

SlowCheetah failing quietly.

Hello all. First, my issue could very well be solved if I could find the correct and complete documentation for slow cheetah usage, specifically in PowerShell.

I'm trying to add the ability to transform json config files via powershell for use in certain cases (but not ALL environments/situations, so adding this to source/project files is not an option).

I'm able to do this exact same thing using XDT for web.config files in other builds, so I know its possible with the correct usage.

So far, I'm able to get all the way to the point where the transform should occur, but then get an error that is completely silent other than 'false'.

I was able to find someones example on stack exchange (https://stackoverflow.com/questions/62944828/can-you-run-microsoft-visualstudio-slowcheetah-from-powershell), which has been modified/simplified to eliminate issues. I'm left with this:

function GetNuget(){
  process{
    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
    'Downloading nuget.exe' | Write-Verbose
    $webclient = New-Object System.Net.WebClient
    $webclient.DownloadFile('https://dist.nuget.org/win-x86-commandline/latest/nuget.exe', "$env:LOCALAPPDATA\NuGet\BuildTools\nuget.exe")

    return "$env:LOCALAPPDATA\NuGet\BuildTools\nuget.exe"
  }
}

function GetNugetPackage(){

  if(!(Test-Path "$env:LOCALAPPDATA\NuGet\BuildTools\")){ 
      New-Item -Path "$env:LOCALAPPDATA\NuGet\BuildTools\" -ItemType Directory | Out-Null
  }
  
  $cmdArgs = @(
    'install',
    'Microsoft.VisualStudio.SlowCheetah',
    '-OutputDirectory',
    (Resolve-Path "$env:LOCALAPPDATA\NuGet\BuildTools\").ToString()
  )

  &(GetNuget `
      -toolsDir "$env:LOCALAPPDATA\NuGet\BuildTools\" `
      -nugetDownloadUrl 'https://dist.nuget.org/win-x86-commandline/latest/nuget.exe') `
      $cmdArgs | Out-Null

  $toolPath = (
    Get-ChildItem `
    -Path "$env:LOCALAPPDATA\NuGet\BuildTools\" `
    -Include 'Microsoft.VisualStudio.SlowCheetah.dll' `
    -Recurse
    ) | Select-Object -First 1

  return $toolPath
}


function TransformConfig{
    [cmdletbinding()]
    param(
        [Parameter(
            Mandatory=$true,
            Position=0)]
        $sourceFile,

        [Parameter(
            Mandatory=$true,
            Position=1)]
        $transformFile,

        [Parameter(
            Mandatory=$true,
            Position=2)]
        $destFile,

        $toolsDir = "$env:LOCALAPPDATA\NuGet\BuildTools\"
    )
    process{
        $sourcePath    = (Resolve-Path $sourceFile).ToString()
        $transformPath = (Resolve-Path $transformFile).ToString()

        $cheetahPath = GetNugetPackage `
                        -packageName 'Microsoft.VisualStudio.SlowCheetah' `
                        -toolFileName 'Microsoft.VisualStudio.SlowCheetah.dll' `
                        -toolsDir "$env:LOCALAPPDATA\NuGet\BuildTools\"

        [Reflection.Assembly]::LoadFrom($cheetahPath.FullName) | Out-Null       
        Add-Type -TypeDefinition $loggingStubSource -Language CSharp -ReferencedAssemblies $cheetahPath.FullName

        $logStub = New-Object Microsoft.VisualStudio.SlowCheetah.LoggingStub

        $transformer = [Microsoft.VisualStudio.SlowCheetah.TransformerFactory]::GetTransformer($sourcePath, $logStub);
        $transformer.Transform($sourcePath, $transformPath, $destFile);
    }
}



$loggingStubSource = @"
    using System;

    namespace Microsoft.VisualStudio.SlowCheetah
    {
        public class LoggingStub : ITransformationLogger
        {
            public void LogError(string message, params object[] messageArgs) { }
            public void LogError(string file, int lineNumber, int linePosition, string message, params object[] messageArgs) { }
            public void LogErrorFromException(Exception ex) { }
            public void LogErrorFromException(Exception ex, string file, int lineNumber, int linePosition) { }
            public void LogMessage(LogMessageImportance importance, string message, params object[] messageArgs) { }
            public void LogWarning(string message, params object[] messageArgs) { }
            public void LogWarning(string file, int lineNumber, int linePosition, string message, params object[] messageArgs) { }
        }
    }
"@

TransformConfig -sourceFile $sourceFile -transformFile $transformFile -destFile $destFile

I would appreciate, above all else, links to docs explaining proper usage. Understanding and being able to implement this more properly is ideal, but any help is welcome.

Replace all with transform file

I have a JSON file with an object with one property called "Groups", which is an array of objects. In my base JSON, i have 2 objects in the array. for my PROD environment, i want to replace everything in the base JSON file with everything in the PROD transform file, which only has one object in the array. Unless i am missing something, i do not see a way to do that.

Synchronize encoding

JsonTransformation.Apply should detect the encoding of the input (either stream or file) and return a stream with the same encoding.

Note that StreamReader.CurrentEncoding does not seem to work properly (see this). I have confirmed this problem through some testing.

Easier way to replace an array?

Under the "Default Transformation" section there is an array listed as "SupportedVersions" that says the default transformation for arrays is append but when going to the "Replace" section, it does not show how to replace an array.

Let's assume I have 2 appsettings.json files that need merged so that the SupportedVersions array is replaced when listed under the Settings section.

First file

{
    "Settings": {
        "SupportedVersions" : [1, 2]
    }
}

Second file

{
    "Settings": {
        "SupportedVersions" : [3, 4]
    }
}

Expected output

{
    "Settings": {
        "SupportedVersions" : [3, 4]
    }
}

I can get this to work by using the following but is there an easier way that I can't find in the documentation?
This works but is long

{
    "Settings": {
        "@jdt.replace" : {
            "@jdt.path" : "$.SupportedVersions",
            "@jdt.value" : [3, 4]
        }
    }
}

Tranformation help

I'm transforming to intermediary values, not the final values;
I'm unable to transform this:

"ClientStoreExpiration": 300,

into this:

"ClientStoreExpiration": $IdentityServerClientStoreExpiration,

Is this possible?

When it's a string there is no problem because it sits inside quotes, ex:

"UserStoreUrl": "http:\\localhost" into "UserStoreUrl": "$UserStoreUrl"

JSON Replace transformation not working

I'm trying to transform

 { "outputs": [
    { "type": "Sample" },
    {
      "type": "Sample1",
      "indexNamePrefix": "Sample2",
      "serviceUri": "Sample3",
      "eventDocumentTypeName": "Sample4"
    }
  ]
}

into something like this

{ "outputs": [
   { "type": "Sample" },
   {
     "type": "Sample1",
     "indexNamePrefix": "Sample2",
     "serviceUri": "NewValue",
     "eventDocumentTypeName": "Sample4"
   }
 ]
}

I have tried the couple of transforms based on your examples
Try 1:
I just tried to replace the serviceUri which was the only change, following the transform

{
  "outputs": {
    "@jdt.replace": {
      "@jdt.path": "@[?(@.serviceUri == Sample3)]",
      "@jdt.value": {
        "serviceUri": "NewValue"
      }
    }
  }
}

Result was something like below , which is similar to the transform and doesn't seem like transformation happened

{
 "outputs": {
    "@jdt.replace": {
      "@jdt.path": "@[?(@.serviceUri == Sample3)]",
      "@jdt.value": {
        "serviceUri": "NewValue"
      }
    }
}

Try 2:
I tried to replace the entire outputs node

{
  "outputs": {
    // Double brackets are needed to specify
    // the array as the transformation value
    "@jdt.replace": [
      [
        {
          "type": "Sample"
        },
        {
          "type": "Sample1",
          "indexNamePrefix": "Sample2",
          "serviceUri": "NewValue",
          "eventDocumentTypeName": "Sample4"
        }
      ]
    ]
  }
}

Result was the same as the transform here too , am I missing something ? because the basic remove and rename transforms are working fine.

Thanks in Advance

"@jdt.Path" is not a valid attribute for this transformation.

When I was trying to use the JDT by following the https://github.com/Microsoft/json-document-transforms/wiki.

Everytime when i use the @jdt.path in the transformation file, i continuously get the below Exception message

"@jdt.Path" is not a valid attribute for this transformation.

Below is the C# code, I have used by referring the wiki https://github.com/microsoft/json-document-transforms/wiki/Rename-Transformation

`
var engine = new JsonTransformation($"./{specName}");

var json = engine.Apply($"./{inputName}");

json.Position = 0;
using (StreamReader reader = new StreamReader(json, Encoding.UTF8))
{
    var anotherVaue =  reader.ReadToEnd();

    Console.WriteLine(anotherVaue);
}`

Source file is
{ "A" : { "RenameThis" : true }, "B" : { "RenameThis" : false }, "C" : [ { "Name" : "C01", "Value" : 1 }, { "Name" : "C02", "Value" : 2 } ] }

Transform file

{ "@jdt.rename" : { "@jdt.Path " : "$[?(@.Rename == true)]", "@jdt.Value" : "Astar" }, "C" : { "@jdt.rename" : { "@jdt.path" : "@[*].Name", "@jdt.value" : "Nstar" } } }

When i try to do it i continuously received the below error.

"@jdt.Path" is not a valid attribute for this transformation.

After all the Trial and error by assuming something wrong with the source or transformation file. I downloaded the source code to find out the reason.

It seems, In JdtRename file. https://github.com/microsoft/json-document-transforms/blob/a9bf106829b3c9d8b73fdf67d37891f95d3f6ee8/src/Microsoft.VisualStudio.Jdt/Processors/Attributes/JdtAttributeValidator.cs Line Number 67. It tries to validate the property name and AttributeNames are equal.
Currently in our case, The property name would be @jdt.path and AttributeNames contains the EnumValues of [Path,Value].

Since it always fail and return the "@jdt.Path" is not a valid attribute for this transformation.

When i try modifying it in a below way. it started working fine.

MicrosoftTeams-image (1)

I changed. from

internal static JdtAttributes GetByName(this IEnumerable<JdtAttributes> collection, string name) { // The default value for the enum is 0, which is None return collection.SingleOrDefault(a => a.FullName().Equals(name)); }

To This

internal static JdtAttributes GetByName(this IEnumerable<JdtAttributes> collection, string name) { // The default value for the enum is 0, which is None return collection.SingleOrDefault(a => a.FullName().ToLower().Contains(name.ToLower())); }

Is it a bug?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.