Skip to content

Commit

Permalink
feat: allow set tag to mutate existing collections
Browse files Browse the repository at this point in the history
  • Loading branch information
thetutlage committed Mar 24, 2021
1 parent 9b2f7f5 commit b8e4331
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 5 deletions.
15 changes: 15 additions & 0 deletions fixtures/set-mutate-collection/compiled.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
let out = "";
let $lineNumber = 1;
let $filename = "{{__dirname}}index.edge";
try {
let counter = {
value: 0
};
$lineNumber = 2;
template.setValue(counter, 'value', 1);
$lineNumber = 3;
out += `${template.escape(counter.value)}`;
} catch (error) {
template.reThrow(error, $filename, $lineNumber);
}
return out;
3 changes: 3 additions & 0 deletions fixtures/set-mutate-collection/index.edge
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@set('counter', { value: 0 })
@set(counter, 'value', 1)
{{ counter.value }}
3 changes: 3 additions & 0 deletions fixtures/set-mutate-collection/index.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"username": "virk"
}
1 change: 1 addition & 0 deletions fixtures/set-mutate-collection/index.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1
46 changes: 41 additions & 5 deletions src/Tags/Set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import { EdgeError } from 'edge-error'
import { expressions } from 'edge-parser'
import { lodash } from '@poppinss/utils'

import { TagContract } from '../Contracts'
import { isSubsetOf, unallowedExpression, parseJsArg } from '../utils'
Expand Down Expand Up @@ -57,10 +58,10 @@ export const setTag: TagContract = {
/**
* Disallow more than 2 values for the sequence expression
*/
if (parsed.expressions.length > 2) {
if (parsed.expressions.length < 2 || parsed.expressions.length > 3) {
throw new EdgeError(
'maximum of 2 arguments are allowed for the @set tag',
'E_MAX_ARGUMENTS',
'@set tag accepts a minimum of 2 or maximum or 3 arguments',
'E_INVALID_ARGUMENTS_COUNT',
{
line: parsed.loc.start.line,
col: parsed.loc.start.column,
Expand All @@ -69,19 +70,47 @@ export const setTag: TagContract = {
)
}

const [key, value] = parsed.expressions
/**
* Extract key-value and the collection (if any)
*/
let collection: any
let key: any
let value: any

if (parsed.expressions.length === 3) {
collection = parsed.expressions[0]
key = parsed.expressions[1]
value = parsed.expressions[2]
} else {
key = parsed.expressions[0]
value = parsed.expressions[1]
}

/**
* The key has to be a literal value
*/
isSubsetOf(key, [expressions.Literal], () => {
throw unallowedExpression(
'The first argument for @set tag must be a string literal',
`The ${collection ? 'second' : 'first'} argument for @set tag must be a string literal`,
token.filename,
parser.utils.getExpressionLoc(key)
)
})

/**
* Mutate the collection when defined
*/
if (collection) {
buffer.writeExpression(
`template.setValue(${parser.utils.stringify(collection)}, '${
key.value
}', ${parser.utils.stringify(value)})`,
token.filename,
token.loc.start.line
)
return
}

/**
* Write statement to mutate the key. If the variable has already been
* defined, then just update it's value.
Expand All @@ -95,4 +124,11 @@ export const setTag: TagContract = {
buffer.writeExpression(expression, token.filename, token.loc.start.line)
parser.stack.defineVariable(key.value)
},

/**
* Add methods to the template for running the loop
*/
run(template) {
template.macro('setValue', lodash.set)
},
}

0 comments on commit b8e4331

Please sign in to comment.