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