1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4  value: true
5});
6exports.createGeneratedHeaderComment = createGeneratedHeaderComment;
7exports.createHash = createHash;
8exports.mergeContents = mergeContents;
9exports.removeContents = removeContents;
10exports.removeGeneratedContents = removeGeneratedContents;
11
12function _crypto() {
13  const data = _interopRequireDefault(require("crypto"));
14
15  _crypto = function () {
16    return data;
17  };
18
19  return data;
20}
21
22function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
24/**
25 * Get line indexes for the generated section of a file.
26 *
27 * @param src
28 */
29function getGeneratedSectionIndexes(src, tag) {
30  const contents = src.split('\n');
31  const start = contents.findIndex(line => line.includes(`@generated begin ${tag}`));
32  const end = contents.findIndex(line => line.includes(`@generated end ${tag}`));
33  return {
34    contents,
35    start,
36    end
37  };
38}
39
40/**
41 * Merge the contents of two files together and add a generated header.
42 *
43 * @param src contents of the original file
44 * @param newSrc new contents to merge into the original file
45 * @param identifier used to update and remove merges
46 * @param anchor regex to where the merge should begin
47 * @param offset line offset to start merging at (<1 for behind the anchor)
48 * @param comment comment style `//` or `#`
49 */
50function mergeContents({
51  src,
52  newSrc,
53  tag,
54  anchor,
55  offset,
56  comment
57}) {
58  const header = createGeneratedHeaderComment(newSrc, tag, comment);
59
60  if (!src.includes(header)) {
61    // Ensure the old generated contents are removed.
62    const sanitizedTarget = removeGeneratedContents(src, tag);
63    return {
64      contents: addLines(sanitizedTarget !== null && sanitizedTarget !== void 0 ? sanitizedTarget : src, anchor, offset, [header, ...newSrc.split('\n'), `${comment} @generated end ${tag}`]),
65      didMerge: true,
66      didClear: !!sanitizedTarget
67    };
68  }
69
70  return {
71    contents: src,
72    didClear: false,
73    didMerge: false
74  };
75}
76
77function removeContents({
78  src,
79  tag
80}) {
81  // Ensure the old generated contents are removed.
82  const sanitizedTarget = removeGeneratedContents(src, tag);
83  return {
84    contents: sanitizedTarget !== null && sanitizedTarget !== void 0 ? sanitizedTarget : src,
85    didMerge: false,
86    didClear: !!sanitizedTarget
87  };
88}
89
90function addLines(content, find, offset, toAdd) {
91  const lines = content.split('\n');
92  let lineIndex = lines.findIndex(line => line.match(find));
93
94  if (lineIndex < 0) {
95    const error = new Error(`Failed to match "${find}" in contents:\n${content}`); // @ts-ignore
96
97    error.code = 'ERR_NO_MATCH';
98    throw error;
99  }
100
101  for (const newLine of toAdd) {
102    lines.splice(lineIndex + offset, 0, newLine);
103    lineIndex++;
104  }
105
106  return lines.join('\n');
107}
108/**
109 * Removes the generated section from a file, returns null when nothing can be removed.
110 * This sways heavily towards not removing lines unless it's certain that modifications were not made manually.
111 *
112 * @param src
113 */
114
115
116function removeGeneratedContents(src, tag) {
117  const {
118    contents,
119    start,
120    end
121  } = getGeneratedSectionIndexes(src, tag);
122
123  if (start > -1 && end > -1 && start < end) {
124    contents.splice(start, end - start + 1); // TODO: We could in theory check that the contents we're removing match the hash used in the header,
125    // this would ensure that we don't accidentally remove lines that someone added or removed from the generated section.
126
127    return contents.join('\n');
128  }
129
130  return null;
131}
132
133function createGeneratedHeaderComment(contents, tag, comment) {
134  const hashKey = createHash(contents); // Everything after the `${tag} ` is unversioned and can be freely modified without breaking changes.
135
136  return `${comment} @generated begin ${tag} - expo prebuild (DO NOT MODIFY) ${hashKey}`;
137}
138
139function createHash(src) {
140  // this doesn't need to be secure, the shorter the better.
141  const hash = _crypto().default.createHash('sha1').update(src).digest('hex');
142
143  return `sync-${hash}`;
144}
145//# sourceMappingURL=generateCode.js.map