1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160 |
1×
1×
1×
1×
1×
1×
1×
2×
22×
22×
1×
1×
1×
26504×
26504×
10×
26494×
3×
26491×
7×
26504×
20×
1×
8257×
2×
8255×
8255×
8255×
8255×
1×
1629×
1629×
1629×
1629×
35039×
1629×
1×
19323×
19323×
19323×
19323×
19323×
1393×
19323×
15809×
1806×
15809×
15809×
6372×
6372×
1×
6371×
6371×
9437×
9437×
3514×
1629×
1629×
1629×
3514×
1885×
1885×
1×
1884×
1884×
1884×
19321×
19317×
19317×
19317×
85523×
85523×
85523×
3×
3×
3×
85520×
63281×
22239×
19314×
1×
1× | 'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.parseDoc = exports.invalidIdError = undefined;
var _uuid = require('./../uuid');
var _uuid2 = _interopRequireDefault(_uuid);
var _errors = require('../../deps/errors');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function toObject(array) {
return array.reduce(function (obj, item) {
obj[item] = true;
return obj;
}, {});
}
// List of top level reserved words for doc
var reservedWords = toObject(['_id', '_rev', '_attachments', '_deleted', '_revisions', '_revs_info', '_conflicts', '_deleted_conflicts', '_local_seq', '_rev_tree',
//replication documents
'_replication_id', '_replication_state', '_replication_state_time', '_replication_state_reason', '_replication_stats',
// Specific to Couchbase Sync Gateway
'_removed']);
// List of reserved words that should end up the document
var dataWords = toObject(['_attachments',
//replication documents
'_replication_id', '_replication_state', '_replication_state_time', '_replication_state_reason', '_replication_stats']);
// Determine id an ID is valid
// - invalid IDs begin with an underescore that does not begin '_design' or
// '_local'
// - any other string value is a valid id
// Returns the specific error object for each case
function invalidIdError(id) {
var err;
if (!id) {
err = (0, _errors.createError)(_errors.MISSING_ID);
} else if (typeof id !== 'string') {
err = (0, _errors.createError)(_errors.INVALID_ID);
} else if (/^_/.test(id) && !/^_(design|local)/.test(id)) {
err = (0, _errors.createError)(_errors.RESERVED_ID);
}
if (err) {
throw err;
}
}
function parseRevisionInfo(rev) {
if (!/^\d+\-./.test(rev)) {
return (0, _errors.createError)(_errors.INVALID_REV);
}
var idx = rev.indexOf('-');
var left = rev.substring(0, idx);
var right = rev.substring(idx + 1);
return {
prefix: parseInt(left, 10),
id: right
};
}
function makeRevTreeFromRevisions(revisions, opts) {
var pos = revisions.start - revisions.ids.length + 1;
var revisionIds = revisions.ids;
var ids = [revisionIds[0], opts, []];
for (var i = 1, len = revisionIds.length; i < len; i++) {
ids = [revisionIds[i], { status: 'missing' }, [ids]];
}
return [{
pos: pos,
ids: ids
}];
}
// Preprocess documents, parse their revisions, assign an id and a
// revision for new writes that are missing them, etc
function parseDoc(doc, newEdits) {
var nRevNum;
var newRevId;
var revInfo;
var opts = { status: 'available' };
if (doc._deleted) {
opts.deleted = true;
}
if (newEdits) {
if (!doc._id) {
doc._id = (0, _uuid2.default)();
}
newRevId = (0, _uuid2.default)(32, 16).toLowerCase();
if (doc._rev) {
revInfo = parseRevisionInfo(doc._rev);
if (revInfo.error) {
return revInfo;
}
doc._rev_tree = [{
pos: revInfo.prefix,
ids: [revInfo.id, { status: 'missing' }, [[newRevId, opts, []]]]
}];
nRevNum = revInfo.prefix + 1;
} else {
doc._rev_tree = [{
pos: 1,
ids: [newRevId, opts, []]
}];
nRevNum = 1;
}
} else {
if (doc._revisions) {
doc._rev_tree = makeRevTreeFromRevisions(doc._revisions, opts);
nRevNum = doc._revisions.start;
newRevId = doc._revisions.ids[0];
}
if (!doc._rev_tree) {
revInfo = parseRevisionInfo(doc._rev);
if (revInfo.error) {
return revInfo;
}
nRevNum = revInfo.prefix;
newRevId = revInfo.id;
doc._rev_tree = [{
pos: nRevNum,
ids: [newRevId, opts, []]
}];
}
}
invalidIdError(doc._id);
doc._rev = nRevNum + '-' + newRevId;
var result = { metadata: {}, data: {} };
for (var key in doc) {
/* istanbul ignore else */
Eif (Object.prototype.hasOwnProperty.call(doc, key)) {
var specialKey = key[0] === '_';
if (specialKey && !reservedWords[key]) {
var error = (0, _errors.createError)(_errors.DOC_VALIDATION, key);
error.message = _errors.DOC_VALIDATION.message + ': ' + key;
throw error;
} else if (specialKey && !dataWords[key]) {
result.metadata[key.slice(1)] = doc[key];
} else {
result.data[key] = doc[key];
}
}
}
return result;
}
exports.invalidIdError = invalidIdError;
exports.parseDoc = parseDoc; |