clanka 0.2.40 → 0.2.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -123,6 +123,29 @@ const findTemplateEnd = (
123
123
  return end
124
124
  }
125
125
 
126
+ const findTemplateEndFirst = (
127
+ text: string,
128
+ start: number,
129
+ isTerminator: (char: string | undefined) => boolean,
130
+ ): number => {
131
+ for (let index = start + 1; index < text.length; index++) {
132
+ if (text[index] !== "`" || isEscaped(text, index)) {
133
+ continue
134
+ }
135
+
136
+ if (isTerminator(text[index + 1])) {
137
+ return index
138
+ }
139
+
140
+ const next = skipWhitespace(text, index + 1)
141
+ if (isTerminator(text[next])) {
142
+ return index
143
+ }
144
+ }
145
+
146
+ return -1
147
+ }
148
+
126
149
  const findTypeAnnotationAssignment = (text: string, start: number): number => {
127
150
  let index = start
128
151
  while (index < text.length) {
@@ -542,6 +565,28 @@ const escapeTemplateLiteralContent = (text: string): string => {
542
565
  const normalizeObjectLiteralTemplateMarkers = (text: string): string =>
543
566
  text.replace(/\\{2,}(?=`|\$\{)/g, "\\")
544
567
 
568
+ const escapeTaggedTemplateLiteralContent = (text: string): string => {
569
+ if (!needsTemplateEscaping(text)) {
570
+ return text
571
+ }
572
+
573
+ let out = ""
574
+ for (let index = 0; index < text.length; index++) {
575
+ const char = text[index]!
576
+ if (char === "`" && !isEscaped(text, index)) {
577
+ out += "\\`"
578
+ continue
579
+ }
580
+ if (char === "$" && text[index + 1] === "{" && !isEscaped(text, index)) {
581
+ out += "\\$"
582
+ continue
583
+ }
584
+ out += char
585
+ }
586
+
587
+ return out
588
+ }
589
+
545
590
  const replaceSlice = (
546
591
  text: string,
547
592
  start: number,
@@ -721,6 +766,58 @@ const findObjectPropertyTemplate = (
721
766
  return undefined
722
767
  }
723
768
 
769
+ const findTaggedTemplate = (
770
+ text: string,
771
+ tag: string,
772
+ from: number,
773
+ ):
774
+ | {
775
+ readonly contentStart: number
776
+ readonly contentEnd: number
777
+ readonly nextCursor: number
778
+ }
779
+ | undefined => {
780
+ let cursor = from
781
+
782
+ while (cursor < text.length) {
783
+ const tagStart = findNextIdentifier(text, tag, cursor)
784
+ if (tagStart === -1) {
785
+ return undefined
786
+ }
787
+
788
+ const templateStart = skipWhitespace(text, tagStart + tag.length)
789
+ if (text[templateStart] !== "`") {
790
+ cursor = tagStart + tag.length
791
+ continue
792
+ }
793
+
794
+ const templateEnd = findTemplateEndFirst(
795
+ text,
796
+ templateStart,
797
+ (char) =>
798
+ char === undefined ||
799
+ char === "+" ||
800
+ char === "," ||
801
+ char === ";" ||
802
+ char === ")" ||
803
+ char === "}" ||
804
+ char === "]",
805
+ )
806
+ if (templateEnd === -1) {
807
+ cursor = templateStart + 1
808
+ continue
809
+ }
810
+
811
+ return {
812
+ contentStart: templateStart + 1,
813
+ contentEnd: templateEnd,
814
+ nextCursor: templateEnd + 1,
815
+ }
816
+ }
817
+
818
+ return undefined
819
+ }
820
+
724
821
  const collectCallArgumentIdentifiers = (
725
822
  script: string,
726
823
  functionName: string,
@@ -982,6 +1079,12 @@ const collectObjectEntryMapSources = (
982
1079
  const rewriteDirectTemplates = (script: string): string => {
983
1080
  let out = script
984
1081
 
1082
+ out = rewriteTemplateContents(
1083
+ out,
1084
+ (text, from) => findTaggedTemplate(text, "String.raw", from),
1085
+ escapeTaggedTemplateLiteralContent,
1086
+ )
1087
+
985
1088
  for (const target of objectPropertyTargets) {
986
1089
  out = rewriteTemplateContents(
987
1090
  out,