1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 | (function (define) {
|
9 | 'use strict';
|
10 |
|
11 | var undef;
|
12 |
|
13 | define(function (require) {
|
14 |
|
15 | var uriEncoder, operations, prefixRE;
|
16 |
|
17 | uriEncoder = require('./uriEncoder');
|
18 |
|
19 | prefixRE = /^([^:]*):([0-9]+)$/;
|
20 | operations = {
|
21 | '': { first: '', separator: ',', named: false, empty: '', encoder: uriEncoder.encode },
|
22 | '+': { first: '', separator: ',', named: false, empty: '', encoder: uriEncoder.encodeURL },
|
23 | '#': { first: '#', separator: ',', named: false, empty: '', encoder: uriEncoder.encodeURL },
|
24 | '.': { first: '.', separator: '.', named: false, empty: '', encoder: uriEncoder.encode },
|
25 | '/': { first: '/', separator: '/', named: false, empty: '', encoder: uriEncoder.encode },
|
26 | ';': { first: ';', separator: ';', named: true, empty: '', encoder: uriEncoder.encode },
|
27 | '?': { first: '?', separator: '&', named: true, empty: '=', encoder: uriEncoder.encode },
|
28 | '&': { first: '&', separator: '&', named: true, empty: '=', encoder: uriEncoder.encode },
|
29 | '=': { reserved: true },
|
30 | ',': { reserved: true },
|
31 | '!': { reserved: true },
|
32 | '@': { reserved: true },
|
33 | '|': { reserved: true }
|
34 | };
|
35 |
|
36 | function apply(operation, expression, params) {
|
37 |
|
38 | return expression.split(',').reduce(function (result, variable) {
|
39 | var opts, value;
|
40 |
|
41 | opts = {};
|
42 | if (variable.slice(-1) === '*') {
|
43 | variable = variable.slice(0, -1);
|
44 | opts.explode = true;
|
45 | }
|
46 | if (prefixRE.test(variable)) {
|
47 | var prefix = prefixRE.exec(variable);
|
48 | variable = prefix[1];
|
49 | opts.maxLength = parseInt(prefix[2]);
|
50 | }
|
51 |
|
52 | variable = uriEncoder.decode(variable);
|
53 | value = params[variable];
|
54 |
|
55 | if (value === undef || value === null) {
|
56 | return result;
|
57 | }
|
58 | if (Array.isArray(value)) {
|
59 | result += value.reduce(function (result, value) {
|
60 | if (result.length) {
|
61 | result += opts.explode ? operation.separator : ',';
|
62 | if (operation.named && opts.explode) {
|
63 | result += operation.encoder(variable);
|
64 | result += value.length ? '=' : operation.empty;
|
65 | }
|
66 | }
|
67 | else {
|
68 | result += operation.first;
|
69 | if (operation.named) {
|
70 | result += operation.encoder(variable);
|
71 | result += value.length ? '=' : operation.empty;
|
72 | }
|
73 | }
|
74 | result += operation.encoder(value);
|
75 | return result;
|
76 | }, '');
|
77 | }
|
78 | else if (typeof value === 'object') {
|
79 | result += Object.keys(value).reduce(function (result, name) {
|
80 | if (result.length) {
|
81 | result += opts.explode ? operation.separator : ',';
|
82 | }
|
83 | else {
|
84 | result += operation.first;
|
85 | if (operation.named && !opts.explode) {
|
86 | result += operation.encoder(variable);
|
87 | result += value[name].length ? '=' : operation.empty;
|
88 | }
|
89 | }
|
90 | result += operation.encoder(name);
|
91 | result += opts.explode ? '=' : ',';
|
92 | result += operation.encoder(value[name]);
|
93 | return result;
|
94 | }, '');
|
95 | }
|
96 | else {
|
97 | value = String(value);
|
98 | if (opts.maxLength) {
|
99 | value = value.slice(0, opts.maxLength);
|
100 | }
|
101 | result += result.length ? operation.separator : operation.first;
|
102 | if (operation.named) {
|
103 | result += operation.encoder(variable);
|
104 | result += value.length ? '=' : operation.empty;
|
105 | }
|
106 | result += operation.encoder(value);
|
107 | }
|
108 |
|
109 | return result;
|
110 | }, '');
|
111 | }
|
112 |
|
113 | function expandExpression(expression, params) {
|
114 | var operation;
|
115 |
|
116 | operation = operations[expression.slice(0,1)];
|
117 | if (operation) {
|
118 | expression = expression.slice(1);
|
119 | }
|
120 | else {
|
121 | operation = operations[''];
|
122 | }
|
123 |
|
124 | if (operation.reserved) {
|
125 | throw new Error('Reserved expression operations are not supported');
|
126 | }
|
127 |
|
128 | return apply(operation, expression, params);
|
129 | }
|
130 |
|
131 | function expandTemplate(template, params) {
|
132 | var start, end, uri;
|
133 |
|
134 | uri = '';
|
135 | end = 0;
|
136 | while (true) {
|
137 | start = template.indexOf('{', end);
|
138 | if (start === -1) {
|
139 |
|
140 | uri += template.slice(end);
|
141 | break;
|
142 | }
|
143 | uri += template.slice(end, start);
|
144 | end = template.indexOf('}', start) + 1;
|
145 | uri += expandExpression(template.slice(start + 1, end - 1), params);
|
146 | }
|
147 |
|
148 | return uri;
|
149 | }
|
150 |
|
151 | return {
|
152 |
|
153 | |
154 |
|
155 |
|
156 |
|
157 |
|
158 |
|
159 |
|
160 |
|
161 |
|
162 |
|
163 | expand: expandTemplate
|
164 |
|
165 | };
|
166 |
|
167 | });
|
168 |
|
169 | }(
|
170 | typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
|
171 |
|
172 | ));
|