UNPKG

6.1 kBJavaScriptView Raw
1"use strict";
2/**
3 * @license
4 * Copyright Google LLC All Rights Reserved.
5 *
6 * Use of this source code is governed by an MIT-style license that can be
7 * found in the LICENSE file at https://angular.io/license
8 */
9Object.defineProperty(exports, "__esModule", { value: true });
10exports.applyTemplates = exports.template = exports.renameTemplateFiles = exports.pathTemplate = exports.applyPathTemplate = exports.contentTemplate = exports.applyContentTemplate = exports.InvalidPipeException = exports.UnknownPipeException = exports.OptionIsNotDefinedException = exports.TEMPLATE_FILENAME_RE = void 0;
11const core_1 = require("@angular-devkit/core");
12const node_os_1 = require("node:os");
13const base_1 = require("./base");
14exports.TEMPLATE_FILENAME_RE = /\.template$/;
15class OptionIsNotDefinedException extends core_1.BaseException {
16 constructor(name) {
17 super(`Option "${name}" is not defined.`);
18 }
19}
20exports.OptionIsNotDefinedException = OptionIsNotDefinedException;
21class UnknownPipeException extends core_1.BaseException {
22 constructor(name) {
23 super(`Pipe "${name}" is not defined.`);
24 }
25}
26exports.UnknownPipeException = UnknownPipeException;
27class InvalidPipeException extends core_1.BaseException {
28 constructor(name) {
29 super(`Pipe "${name}" is invalid.`);
30 }
31}
32exports.InvalidPipeException = InvalidPipeException;
33const decoder = new TextDecoder('utf-8', { fatal: true });
34function applyContentTemplate(options) {
35 return (entry) => {
36 const { path, content } = entry;
37 try {
38 const decodedContent = decoder.decode(content).replace(/\r?\n/g, node_os_1.EOL);
39 return {
40 path,
41 content: Buffer.from((0, core_1.template)(decodedContent, {})(options)),
42 };
43 }
44 catch (e) {
45 if (e instanceof TypeError) {
46 return entry;
47 }
48 throw e;
49 }
50 };
51}
52exports.applyContentTemplate = applyContentTemplate;
53function contentTemplate(options) {
54 return (0, base_1.forEach)(applyContentTemplate(options));
55}
56exports.contentTemplate = contentTemplate;
57function applyPathTemplate(data, options = {
58 interpolationStart: '__',
59 interpolationEnd: '__',
60 pipeSeparator: '@',
61}) {
62 const is = options.interpolationStart;
63 const ie = options.interpolationEnd;
64 const isL = is.length;
65 const ieL = ie.length;
66 return (entry) => {
67 let path = entry.path;
68 const content = entry.content;
69 const original = path;
70 let start = path.indexOf(is);
71 // + 1 to have at least a length 1 name. `____` is not valid.
72 let end = path.indexOf(ie, start + isL + 1);
73 while (start != -1 && end != -1) {
74 const match = path.substring(start + isL, end);
75 let replacement = data[match];
76 if (!options.pipeSeparator) {
77 if (typeof replacement == 'function') {
78 replacement = replacement.call(data, original);
79 }
80 if (replacement === undefined) {
81 throw new OptionIsNotDefinedException(match);
82 }
83 }
84 else {
85 const [name, ...pipes] = match.split(options.pipeSeparator);
86 replacement = data[name];
87 if (typeof replacement == 'function') {
88 replacement = replacement.call(data, original);
89 }
90 if (replacement === undefined) {
91 throw new OptionIsNotDefinedException(name);
92 }
93 replacement = pipes.reduce((acc, pipe) => {
94 if (!pipe) {
95 return acc;
96 }
97 if (!(pipe in data)) {
98 throw new UnknownPipeException(pipe);
99 }
100 if (typeof data[pipe] != 'function') {
101 throw new InvalidPipeException(pipe);
102 }
103 // Coerce to string.
104 return '' + data[pipe](acc);
105 }, '' + replacement);
106 }
107 path = path.substring(0, start) + replacement + path.substring(end + ieL);
108 start = path.indexOf(options.interpolationStart);
109 // See above.
110 end = path.indexOf(options.interpolationEnd, start + isL + 1);
111 }
112 return { path: (0, core_1.normalize)(path), content };
113 };
114}
115exports.applyPathTemplate = applyPathTemplate;
116function pathTemplate(options) {
117 return (0, base_1.forEach)(applyPathTemplate(options));
118}
119exports.pathTemplate = pathTemplate;
120/**
121 * Remove every `.template` suffix from file names.
122 */
123function renameTemplateFiles() {
124 return (0, base_1.forEach)((entry) => {
125 if (entry.path.match(exports.TEMPLATE_FILENAME_RE)) {
126 return {
127 content: entry.content,
128 path: (0, core_1.normalize)(entry.path.replace(exports.TEMPLATE_FILENAME_RE, '')),
129 };
130 }
131 else {
132 return entry;
133 }
134 });
135}
136exports.renameTemplateFiles = renameTemplateFiles;
137function template(options) {
138 return (0, base_1.chain)([
139 contentTemplate(options),
140 // Force cast to PathTemplateData. We need the type for the actual pathTemplate() call,
141 // but in this case we cannot do anything as contentTemplate are more permissive.
142 // Since values are coerced to strings in PathTemplates it will be fine in the end.
143 pathTemplate(options),
144 ]);
145}
146exports.template = template;
147function applyTemplates(options) {
148 return (0, base_1.forEach)((0, base_1.when)((path) => path.endsWith('.template'), (0, base_1.composeFileOperators)([
149 applyContentTemplate(options),
150 // See above for this weird cast.
151 applyPathTemplate(options),
152 (entry) => {
153 return {
154 content: entry.content,
155 path: entry.path.replace(exports.TEMPLATE_FILENAME_RE, ''),
156 };
157 },
158 ])));
159}
160exports.applyTemplates = applyTemplates;