Skip to content

Instantly share code, notes, and snippets.

@dualyticalchemy
Last active April 8, 2020 23:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dualyticalchemy/1c3ebbe7654c5a31b58bc26e71f1ad0c to your computer and use it in GitHub Desktop.
Save dualyticalchemy/1c3ebbe7654c5a31b58bc26e71f1ad0c to your computer and use it in GitHub Desktop.
{
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    },
    {
      "type": "cosmosDB",
      "name": "inputDocument",
      "databaseName": "humans",
      "collectionName": "humans",
      "connectionStringSetting": "humans_DOCUMENTDB",
      "direction": "in"
    }
  ],
  "disabled": false
}
const _ = require('underscore')

const curry = fn => (...args) => fn.bind(null, ...args)

const join = curry((str, arr) => arr.join(str))

module.exports = async function (context, req) {

    let res = {
        headers: {}
    }

    const glue = ""
    const sep = "/"
    const _proxyUrl = req.query.proxyUrl
    const proxyUrl = join(sep)([req.query.proxyUrl, "humans"]);    
    const originalUrl = _proxyUrl ? req.originalUrl.replace(/https:\/\/anotherfaileddeployment.azurewebsites.net\/api\/getHumansList/g, proxyUrl) : req.originalUrl
    let _baseUrl = _proxyUrl ? proxyUrl : "https://anotherfaileddeployment.azurewebsites.net/humans"
    let baseUrl = _proxyUrl ? proxyUrl : "https://anotherfaileddeployment.azurewebsites.net/humans"
    if (originalUrl.indexOf('page=') !== -1) {
        var pageState = parseInt(originalUrl.split('page=').pop(), 10)
        baseUrl = join(glue)([ baseUrl, '?page=', pageState ]) 
    }
    //context.log(pageState)
    //context.log(baseUrl)
    
    const humansList = context.bindings.inputDocument

    const query = req.query
    
    const page_size = query.page_size || 10
    
    const page = (query && query.page) ? parseInt(query.page, 10) : 1
    const pageMax = page * page_size
    const pageMin = (page - 1) * page_size
        
    const _filters = _.mapObject(query, (ref, key) => key.includes("filter") ? { [key.split('filters')[1]]: ref } : null)
    const filters = _.filter(_filters, (ref) => ref)
    const resultFilter = []
    for (let i = 0; i < filters.length; i++) {
        resultFilter.push( [
            _.keys(filters[i])[0].split('[')[1].split(']')[0], 
            _.values(filters[i])[0]
        ] )
    }
    const _resultFilter = _.object(resultFilter)

    const resultFilterHumansList = _.where(humansList, _resultFilter)

    const _humansList = _.size(resultFilter) ? resultFilterHumansList : humansList

    const filteredHumansList = _humansList.filter((humanRef, index) => { 
        if (pageMin !== 0)
            return (pageMin <= index) && (index < pageMax)
        return (index < pageMax); 
    })

    if (!_.size(filteredHumansList)) {
        res.headers['Content-Type'] = 'application/json'
        res.status = 404
        res.body = { error: "List not found" }
        context.res = res

        return context.done();
    }

    const output = { 
        "$filters": _.object(resultFilter),
        "$resultsCursorStart": pageMin,
        "$resultsCursorEnd": pageMax,
        "$pageLength": _.size(filteredHumansList),
        "$resultsLength": _.size(_humansList),
        "_embedded": { "humans": filteredHumansList } 
    }
    
    const enableNext = (
            _.size(filteredHumansList) === 0 || _.size(filteredHumansList) < (pageMax - pageMin)
        ) ? false : true
    const enablePrev = page > 0 && page !== 1

    const selfLinkBase = (pageMin === 0 ? "" : ("?page=" + page))
    const prevLinkBase = join(glue)(["?page=", (page - 1)])
    const nextLinkBase = join(glue)(["?page=", (page + 1)])

    const links = { 
        "_links": {
            "sort": {
                "status": "unavailable",
                "href": baseUrl.indexOf('page=') !== -1 ? join(glue)([ baseUrl, "&sort=:property&order={asc|desc}" ]) : join(glue)([ _baseUrl, "?sort=:property&order={asc|desc}" ])
            },
            "filter": {
                "status": "available",
                "href": baseUrl.indexOf('page=') !== -1 ? join(glue)([ baseUrl, "&filter[:property]=:any" ]) : join(glue)([ _baseUrl, "?filter[:property]=:any" ])
            },
            "page-size": {
                "status": "available",
                "href": baseUrl.indexOf('page=') !== -1 ? join(glue)([ baseUrl, "&page_size=:number" ]) : join(glue)([ _baseUrl, "?page_size=:number" ])
            },
            "prev": {
                "status": "available",
                "href": join(glue)([ _baseUrl, prevLinkBase ])
            },
            "self": {
                "status": "available",
                "href": baseUrl.indexOf('page=') === -1 ? join(glue)([ baseUrl, selfLinkBase ]) : baseUrl
            },
            "next": {
                "status": "available",
                "href": join(glue)([ _baseUrl, nextLinkBase ])
            }
        }
    }

    if (!enableNext)
        delete links._links.next

    if (!enablePrev)
        delete links._links.prev

    let _res = Object.assign(output, links)

    res.headers['Content-Type'] = 'application/json';
    res.status = 200
    res.body = _res
    context.res = res;
};
{
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    },
    {
      "type": "cosmosDB",
      "name": "outputDocument",
      "databaseName": "humans",
      "collectionName": "humans",
      "createIfNotExists": false,
      "connectionStringSetting": "humans_DOCUMENTDB",
      "direction": "out"
    }
  ],
  "disabled": false
}
module.exports = async function (context, req) {
    if (req.body && req.body.name) {

        context.bindings.outputDocument = req.body;

        context.res = {
            headers: { 'Content-Type': 'application/json' },
            status: 201, // 201 Created https://httpstatuses.com/201
            body: req.body
        };
    }
    else if (req.query.name) {
        context.bindings.outputDocument = req.query;

        context.res = {
            headers: { 'Content-Type': 'application/json' },
            status: 201,
            body: req.query
        };
    }
    else {
        context.res = {
            headers: { 'Content-Type': 'application/json' },
            status: 400,
            body: { error: "The body property 'name' is be required." }
        };
    }
};
{
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    },
    {
      "type": "cosmosDB",
      "name": "inputDocument",
      "databaseName": "humans",
      "collectionName": "humans",
      "connectionStringSetting": "humans_DOCUMENTDB",
      "direction": "in"
    }
  ],
  "disabled": false
}
const _ = require('underscore')
//const { compose } = require('ramda');
module.exports = async function (context, req) {
    context.log(req.params.humanId)
    const id = req.query.id || req.params.humanId

    if (id) {
        //const last = (x) => _.last(x)
        //const where = (x) => (x) => _.where(x, { id: id })
        //const selectHuman = compose(last, where)
        //const selectHuman(context.bindings.inputDocument)
        const human = _.last(_.where(context.bindings.inputDocument, { id: id }))

        if (!human) {
            context.res = {
                headers: { 'Content-Type': 'application/json' },
                status: 404,
                body: "Not found"
            };
            return;
        }

        context.res = {
            headers: { 'Content-Type': 'application/json' },
            body: human
        };
    }
    else {
        context.res = {
            headers: { 'Content-Type': 'application/json' },
            status: 400,
            body: "Please pass an ID on the query string"
        };
    }
};
{
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "delete"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    },
    {
      "type": "cosmosDB",
      "name": "outputDocument",
      "databaseName": "humans",
      "collectionName": "humans",
      "createIfNotExists": false,
      "connectionStringSetting": "humans_DOCUMENTDB",
      "direction": "out"
    },
    {
      "type": "cosmosDB",
      "name": "inputDocument",
      "databaseName": "humans",
      "collectionName": "humans",
      "connectionStringSetting": "humans_DOCUMENTDB",
      "direction": "in"
    }
  ],
  "disabled": false
}
const _ = require('underscore')

module.exports = async function (context, req) {

    const id = req.query.id || req.params.humanId

    if (id) {
        const human = _.last(_.where(context.bindings.inputDocument, { id: id }))

        human['deletion'] = "pending"; // Tag the user with the relevant status, use a stored procedure to handle on an interval with a timed function
        // set to "deletion/completed" before actually deleting, in case the deletion fails for whatever reason;
        // so batch setting the status first and then actually delete anything with "deletion/completed"; the front end
        // should always hide elements that have a substring "deletion/*"...
        context.bindings.outputDocument = _.without(context.bindings.outputDocument, _.findWhere(context.bindings.outputDocument, {
            id: id
        }));
        context.bindings.outputDocument.push(human)
        
        context.res = {
            headers: { 'Content-Type': 'application/json' },
            status: 202, // ... Accepted? Usually 200 OK for removal? or 204 No Content? 102 Processing (probably too meta for the context? 
            body: { id: id, "deletion": "pending" }
        };

        context.done(null, context.bindings.outputDocument)
    }
    else {
        context.res = {
            headers: { 'Content-Type': 'application/json' },
            status: 400,
            body: { error: "The query string must include an ID." }
        };
    }
};
function storedProcedure(prefix) {
    const collection = getContext().getCollection();
    console.log(prefix + ' ' + JSON.stringify(collection));
    const string = 'Austin';
    const isAccepted = collection.queryDocuments(
        collection.getSelfLink(),
        `SELECT * FROM humans WHERE CONTAINS(humans.location, '${string}')`,
        function (err, feed, options) {
            if (err) throw err;

            if (!feed || !feed.length) {
                const response = getContext().getResponse();
                response.setBody('no docs found');
            } else {
                const response = getContext().getResponse();
                const body = { prefix: prefix, feed: feed[0] };
                response.setBody(JSON.stringify(body));
            }
        });

    if (!isAccepted) throw new Error('The query was not accepted by the server.');
}
{
    "$schema": "http://json.schemastore.org/proxies",
    "proxies": {
        "humans": {
            "matchCondition": {
                "route": "humans/{humanId}",
                "methods": [
                    "GET"
                ]
            },
            "backendUri": "https://anotherfaileddeployment.azurewebsites.net/api/getHumanById?code=SEVnr4zmTvzx76xS3VZNkysN2ovSQbaV2Mwtl/exTVPUOVeIcUXwpA=="
        },
        "humansAll": {
            "matchCondition": {
                "route": "humans",
                "methods": [
                    "GET"
                ]
            },
            "backendUri": "https://anotherfaileddeployment.azurewebsites.net/api/getHumansList?code=K0MtifNQ79ATooUjDO7VdeVInCFIz8VXAoDxXlarO3QBBuK3IjzNDg=="
        },
        "humansCreate": {
            "matchCondition": {
                "route": "humans",
                "methods": [
                    "POST"
                ]
            },
            "backendUri": "https://anotherfaileddeployment.azurewebsites.net/api/createHuman?code=8RMypv5p9oiMhYJrVnaCj4v4/u/49AAzY8fcWF3PhMoaWUdzE7WGGg=="
        },
        "humansRemove": {
            "matchCondition": {
                "route": "humans/{humanId}",
                "methods": [
                    "DELETE"
                ]
            },
            "backendUri": "https://anotherfaileddeployment.azurewebsites.net/api/removeHumanById?code=1c14mHBfa7CmdsVNGgOd75A0OwMIjXajsHB5wpPFq5HJceek1DiLQg=="
        }
    }
}
var proxy = require('express-http-proxy');
var app = require('express')();
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:1234');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
app.use('/', proxy('https://anotherfaileddeployment.azurewebsites.net'));
app.listen('9091', () => {
console.log('Proxy on http://localhost:9091')
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment