1082815dcSEvan Bacon"use strict";
2082815dcSEvan Bacon
3082815dcSEvan BaconObject.defineProperty(exports, "__esModule", {
4082815dcSEvan Bacon  value: true
5082815dcSEvan Bacon});
6082815dcSEvan Baconexports.createGeneratedHeaderComment = createGeneratedHeaderComment;
7082815dcSEvan Baconexports.createHash = createHash;
8082815dcSEvan Baconexports.mergeContents = mergeContents;
9082815dcSEvan Baconexports.removeContents = removeContents;
10082815dcSEvan Baconexports.removeGeneratedContents = removeGeneratedContents;
11082815dcSEvan Baconfunction _crypto() {
12082815dcSEvan Bacon  const data = _interopRequireDefault(require("crypto"));
13082815dcSEvan Bacon  _crypto = function () {
14082815dcSEvan Bacon    return data;
15082815dcSEvan Bacon  };
16082815dcSEvan Bacon  return data;
17082815dcSEvan Bacon}
18082815dcSEvan Baconfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19082815dcSEvan Bacon/**
20082815dcSEvan Bacon * Get line indexes for the generated section of a file.
21082815dcSEvan Bacon *
22082815dcSEvan Bacon * @param src
23082815dcSEvan Bacon */
24*ee216927STomasz Sapeta
25082815dcSEvan Baconfunction getGeneratedSectionIndexes(src, tag) {
26082815dcSEvan Bacon  const contents = src.split('\n');
27082815dcSEvan Bacon  const start = contents.findIndex(line => line.includes(`@generated begin ${tag}`));
28082815dcSEvan Bacon  const end = contents.findIndex(line => line.includes(`@generated end ${tag}`));
29082815dcSEvan Bacon  return {
30082815dcSEvan Bacon    contents,
31082815dcSEvan Bacon    start,
32082815dcSEvan Bacon    end
33082815dcSEvan Bacon  };
34082815dcSEvan Bacon}
35082815dcSEvan Bacon/**
36082815dcSEvan Bacon * Merge the contents of two files together and add a generated header.
37082815dcSEvan Bacon *
38082815dcSEvan Bacon * @param src contents of the original file
39082815dcSEvan Bacon * @param newSrc new contents to merge into the original file
40082815dcSEvan Bacon * @param identifier used to update and remove merges
41082815dcSEvan Bacon * @param anchor regex to where the merge should begin
42082815dcSEvan Bacon * @param offset line offset to start merging at (<1 for behind the anchor)
43082815dcSEvan Bacon * @param comment comment style `//` or `#`
44082815dcSEvan Bacon */
45082815dcSEvan Baconfunction mergeContents({
46082815dcSEvan Bacon  src,
47082815dcSEvan Bacon  newSrc,
48082815dcSEvan Bacon  tag,
49082815dcSEvan Bacon  anchor,
50082815dcSEvan Bacon  offset,
51082815dcSEvan Bacon  comment
52082815dcSEvan Bacon}) {
53082815dcSEvan Bacon  const header = createGeneratedHeaderComment(newSrc, tag, comment);
54082815dcSEvan Bacon  if (!src.includes(header)) {
55082815dcSEvan Bacon    // Ensure the old generated contents are removed.
56082815dcSEvan Bacon    const sanitizedTarget = removeGeneratedContents(src, tag);
57082815dcSEvan Bacon    return {
58082815dcSEvan Bacon      contents: addLines(sanitizedTarget !== null && sanitizedTarget !== void 0 ? sanitizedTarget : src, anchor, offset, [header, ...newSrc.split('\n'), `${comment} @generated end ${tag}`]),
59082815dcSEvan Bacon      didMerge: true,
60082815dcSEvan Bacon      didClear: !!sanitizedTarget
61082815dcSEvan Bacon    };
62082815dcSEvan Bacon  }
63082815dcSEvan Bacon  return {
64082815dcSEvan Bacon    contents: src,
65082815dcSEvan Bacon    didClear: false,
66082815dcSEvan Bacon    didMerge: false
67082815dcSEvan Bacon  };
68082815dcSEvan Bacon}
69082815dcSEvan Baconfunction removeContents({
70082815dcSEvan Bacon  src,
71082815dcSEvan Bacon  tag
72082815dcSEvan Bacon}) {
73082815dcSEvan Bacon  // Ensure the old generated contents are removed.
74082815dcSEvan Bacon  const sanitizedTarget = removeGeneratedContents(src, tag);
75082815dcSEvan Bacon  return {
76082815dcSEvan Bacon    contents: sanitizedTarget !== null && sanitizedTarget !== void 0 ? sanitizedTarget : src,
77082815dcSEvan Bacon    didMerge: false,
78082815dcSEvan Bacon    didClear: !!sanitizedTarget
79082815dcSEvan Bacon  };
80082815dcSEvan Bacon}
81082815dcSEvan Baconfunction addLines(content, find, offset, toAdd) {
82082815dcSEvan Bacon  const lines = content.split('\n');
83082815dcSEvan Bacon  let lineIndex = lines.findIndex(line => line.match(find));
84082815dcSEvan Bacon  if (lineIndex < 0) {
85*ee216927STomasz Sapeta    const error = new Error(`Failed to match "${find}" in contents:\n${content}`);
86*ee216927STomasz Sapeta    // @ts-ignore
87082815dcSEvan Bacon    error.code = 'ERR_NO_MATCH';
88082815dcSEvan Bacon    throw error;
89082815dcSEvan Bacon  }
90082815dcSEvan Bacon  for (const newLine of toAdd) {
91082815dcSEvan Bacon    lines.splice(lineIndex + offset, 0, newLine);
92082815dcSEvan Bacon    lineIndex++;
93082815dcSEvan Bacon  }
94082815dcSEvan Bacon  return lines.join('\n');
95082815dcSEvan Bacon}
96*ee216927STomasz Sapeta
97082815dcSEvan Bacon/**
98082815dcSEvan Bacon * Removes the generated section from a file, returns null when nothing can be removed.
99082815dcSEvan Bacon * This sways heavily towards not removing lines unless it's certain that modifications were not made manually.
100082815dcSEvan Bacon *
101082815dcSEvan Bacon * @param src
102082815dcSEvan Bacon */
103082815dcSEvan Baconfunction removeGeneratedContents(src, tag) {
104082815dcSEvan Bacon  const {
105082815dcSEvan Bacon    contents,
106082815dcSEvan Bacon    start,
107082815dcSEvan Bacon    end
108082815dcSEvan Bacon  } = getGeneratedSectionIndexes(src, tag);
109082815dcSEvan Bacon  if (start > -1 && end > -1 && start < end) {
110*ee216927STomasz Sapeta    contents.splice(start, end - start + 1);
111*ee216927STomasz Sapeta    // TODO: We could in theory check that the contents we're removing match the hash used in the header,
112082815dcSEvan Bacon    // this would ensure that we don't accidentally remove lines that someone added or removed from the generated section.
113082815dcSEvan Bacon    return contents.join('\n');
114082815dcSEvan Bacon  }
115082815dcSEvan Bacon  return null;
116082815dcSEvan Bacon}
117082815dcSEvan Baconfunction createGeneratedHeaderComment(contents, tag, comment) {
118*ee216927STomasz Sapeta  const hashKey = createHash(contents);
119082815dcSEvan Bacon
120*ee216927STomasz Sapeta  // Everything after the `${tag} ` is unversioned and can be freely modified without breaking changes.
121082815dcSEvan Bacon  return `${comment} @generated begin ${tag} - expo prebuild (DO NOT MODIFY) ${hashKey}`;
122082815dcSEvan Bacon}
123082815dcSEvan Baconfunction createHash(src) {
124082815dcSEvan Bacon  // this doesn't need to be secure, the shorter the better.
125082815dcSEvan Bacon  const hash = _crypto().default.createHash('sha1').update(src).digest('hex');
126082815dcSEvan Bacon  return `sync-${hash}`;
127082815dcSEvan Bacon}
128082815dcSEvan Bacon//# sourceMappingURL=generateCode.js.map