@valbuild/server 0.20.2 → 0.21.0
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.
- package/dist/valbuild-server.cjs.dev.js +18 -97
- package/dist/valbuild-server.cjs.prod.js +18 -97
- package/dist/valbuild-server.esm.js +18 -97
- package/package.json +3 -3
- package/src/ProxyValServer.ts +1 -0
- package/src/patch/ts/ops.test.ts +34 -17
- package/src/patch/ts/ops.ts +37 -8
- package/src/patch/ts/richtext.test.ts +0 -100
- package/src/patch/ts/richtext.ts +0 -113
@@ -246,99 +246,6 @@ function analyzeValModule(sourceFile) {
|
|
246
246
|
return analysis;
|
247
247
|
}
|
248
248
|
|
249
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
250
|
-
|
251
|
-
const HeaderRegEx = /^h([\d+])$/;
|
252
|
-
function richTextToTaggedStringTemplate(source) {
|
253
|
-
const texts = [""];
|
254
|
-
const nodes = [];
|
255
|
-
let didAppendNewLines = false;
|
256
|
-
let listContext = null;
|
257
|
-
function rec(node) {
|
258
|
-
if (typeof node === "string") {
|
259
|
-
texts[texts.length - 1] += node;
|
260
|
-
} else if ("tag" in node && node.tag) {
|
261
|
-
var _node$children, _node$tag;
|
262
|
-
if (node.tag === "h1" || node.tag === "h2" || node.tag === "h3" || node.tag === "h4" || node.tag === "h5" || node.tag === "h6") {
|
263
|
-
var _node$tag$match;
|
264
|
-
const depth = Number((_node$tag$match = node.tag.match(HeaderRegEx)) === null || _node$tag$match === void 0 ? void 0 : _node$tag$match[1]);
|
265
|
-
if (Number.isNaN(depth)) {
|
266
|
-
throw new Error("Invalid header depth");
|
267
|
-
}
|
268
|
-
for (let i = 0; i < Number(depth); i++) {
|
269
|
-
texts[texts.length - 1] += "#";
|
270
|
-
}
|
271
|
-
texts[texts.length - 1] += " ";
|
272
|
-
} else if (node.tag === "p") ; else if (node.tag === "ul") {
|
273
|
-
listContext = "ul";
|
274
|
-
texts[texts.length - 1] += "\n";
|
275
|
-
} else if (node.tag === "ol") {
|
276
|
-
listContext = "ol";
|
277
|
-
texts[texts.length - 1] += "\n";
|
278
|
-
} else if (node.tag === "li") {
|
279
|
-
if (listContext === "ul") {
|
280
|
-
texts[texts.length - 1] += "\n- ";
|
281
|
-
} else if (listContext === "ol") {
|
282
|
-
texts[texts.length - 1] += "\n1. ";
|
283
|
-
} else {
|
284
|
-
throw new Error("Unexpected list context");
|
285
|
-
}
|
286
|
-
} else if (node.tag === "span") {
|
287
|
-
if (node.classes.includes("bold") && !node.classes.includes("italic")) {
|
288
|
-
texts[texts.length - 1] += "**";
|
289
|
-
}
|
290
|
-
if (node.classes.includes("italic") && !node.classes.includes("bold")) {
|
291
|
-
texts[texts.length - 1] += "*";
|
292
|
-
}
|
293
|
-
if (node.classes.includes("italic") && node.classes.includes("bold")) {
|
294
|
-
texts[texts.length - 1] += "***";
|
295
|
-
}
|
296
|
-
if (node.classes.includes("line-through")) {
|
297
|
-
texts[texts.length - 1] += "~~";
|
298
|
-
}
|
299
|
-
} else {
|
300
|
-
//exhaustive match
|
301
|
-
const exhaustiveCheck = node.tag;
|
302
|
-
throw new Error("Unexpected node tag: " + JSON.stringify(node, exhaustiveCheck, 2));
|
303
|
-
}
|
304
|
-
(_node$children = node.children) === null || _node$children === void 0 ? void 0 : _node$children.forEach(rec);
|
305
|
-
didAppendNewLines = false;
|
306
|
-
if (node.tag === "span") {
|
307
|
-
if (node.classes.includes("line-through")) {
|
308
|
-
texts[texts.length - 1] += "~~";
|
309
|
-
}
|
310
|
-
if (node.classes.includes("italic") && node.classes.includes("bold")) {
|
311
|
-
texts[texts.length - 1] += "***";
|
312
|
-
}
|
313
|
-
if (node.classes.includes("italic") && !node.classes.includes("bold")) {
|
314
|
-
texts[texts.length - 1] += "*";
|
315
|
-
}
|
316
|
-
if (node.classes.includes("bold") && !node.classes.includes("italic")) {
|
317
|
-
texts[texts.length - 1] += "**";
|
318
|
-
}
|
319
|
-
} else if (node.tag === "p") {
|
320
|
-
didAppendNewLines = true;
|
321
|
-
texts[texts.length - 1] += "\n\n";
|
322
|
-
} else if (node.tag === "ul" || node.tag === "ol") {
|
323
|
-
listContext = null;
|
324
|
-
texts[texts.length - 1] += "\n";
|
325
|
-
} else if ((_node$tag = node.tag) !== null && _node$tag !== void 0 && _node$tag.startsWith("h")) {
|
326
|
-
didAppendNewLines = true;
|
327
|
-
texts[texts.length - 1] += "\n\n";
|
328
|
-
}
|
329
|
-
} else {
|
330
|
-
nodes.push(node); // ImageSource
|
331
|
-
texts.push("\n");
|
332
|
-
}
|
333
|
-
}
|
334
|
-
source.children.forEach(rec);
|
335
|
-
if (texts[texts.length - 1] && didAppendNewLines) {
|
336
|
-
// remove last \n\n
|
337
|
-
texts[texts.length - 1] = texts[texts.length - 1].slice(0, -2);
|
338
|
-
}
|
339
|
-
return [texts, nodes];
|
340
|
-
}
|
341
|
-
|
342
249
|
function isValidIdentifier(text) {
|
343
250
|
if (text.length === 0) {
|
344
251
|
return false;
|
@@ -363,11 +270,20 @@ function createValFileReference(value) {
|
|
363
270
|
}
|
364
271
|
return ts__default["default"].factory.createCallExpression(ts__default["default"].factory.createPropertyAccessExpression(ts__default["default"].factory.createIdentifier("val"), ts__default["default"].factory.createIdentifier("file")), undefined, args);
|
365
272
|
}
|
273
|
+
function createValLink(value) {
|
274
|
+
const args = [ts__default["default"].factory.createStringLiteral(value.children[0]), toExpression({
|
275
|
+
href: value.href
|
276
|
+
})];
|
277
|
+
return ts__default["default"].factory.createCallExpression(ts__default["default"].factory.createPropertyAccessExpression(ts__default["default"].factory.createIdentifier("val"), ts__default["default"].factory.createIdentifier("link")), undefined, args);
|
278
|
+
}
|
366
279
|
function createValRichTextTaggedStringTemplate(value) {
|
367
|
-
const
|
280
|
+
const {
|
281
|
+
templateStrings: [head, ...others],
|
282
|
+
exprs
|
283
|
+
} = value;
|
368
284
|
const tag = ts__default["default"].factory.createPropertyAccessExpression(ts__default["default"].factory.createIdentifier("val"), ts__default["default"].factory.createIdentifier("richtext"));
|
369
|
-
if (
|
370
|
-
return ts__default["default"].factory.createTaggedTemplateExpression(tag, undefined, ts__default["default"].factory.createTemplateExpression(ts__default["default"].factory.createTemplateHead(head, head), others.map((s, i) => ts__default["default"].factory.createTemplateSpan(toExpression(
|
285
|
+
if (exprs.length > 0) {
|
286
|
+
return ts__default["default"].factory.createTaggedTemplateExpression(tag, undefined, ts__default["default"].factory.createTemplateExpression(ts__default["default"].factory.createTemplateHead(head, head), others.map((s, i) => ts__default["default"].factory.createTemplateSpan(toExpression(exprs[i]), i < others.length - 1 ? ts__default["default"].factory.createTemplateMiddle(s, s) : ts__default["default"].factory.createTemplateTail(s, s)))));
|
371
287
|
}
|
372
288
|
return ts__default["default"].factory.createTaggedTemplateExpression(tag, undefined, ts__default["default"].factory.createNoSubstitutionTemplateLiteral(head, head));
|
373
289
|
}
|
@@ -386,6 +302,8 @@ function toExpression(value) {
|
|
386
302
|
} else if (typeof value === "object") {
|
387
303
|
if (isValFileValue(value)) {
|
388
304
|
return createValFileReference(value);
|
305
|
+
} else if (isValLinkValue(value)) {
|
306
|
+
return createValLink(value);
|
389
307
|
} else if (isValRichTextValue(value)) {
|
390
308
|
return createValRichTextTaggedStringTemplate(value);
|
391
309
|
}
|
@@ -620,8 +538,11 @@ function isValFileValue(value) {
|
|
620
538
|
// value[VAL_EXTENSION] === "file" &&
|
621
539
|
core.FILE_REF_PROP in value && typeof value[core.FILE_REF_PROP] === "string");
|
622
540
|
}
|
541
|
+
function isValLinkValue(value) {
|
542
|
+
return !!(typeof value === "object" && value && core.VAL_EXTENSION in value && value[core.VAL_EXTENSION] === "link");
|
543
|
+
}
|
623
544
|
function isValRichTextValue(value) {
|
624
|
-
return !!(typeof value === "object" && value && core.VAL_EXTENSION in value && value[core.VAL_EXTENSION] === "richtext" && "
|
545
|
+
return !!(typeof value === "object" && value && core.VAL_EXTENSION in value && value[core.VAL_EXTENSION] === "richtext" && "templateStrings" in value && typeof value.templateStrings === "object" && Array.isArray(value.templateStrings));
|
625
546
|
}
|
626
547
|
function addToNode(document, node, key, value) {
|
627
548
|
if (ts__default["default"].isArrayLiteralExpression(node)) {
|
@@ -246,99 +246,6 @@ function analyzeValModule(sourceFile) {
|
|
246
246
|
return analysis;
|
247
247
|
}
|
248
248
|
|
249
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
250
|
-
|
251
|
-
const HeaderRegEx = /^h([\d+])$/;
|
252
|
-
function richTextToTaggedStringTemplate(source) {
|
253
|
-
const texts = [""];
|
254
|
-
const nodes = [];
|
255
|
-
let didAppendNewLines = false;
|
256
|
-
let listContext = null;
|
257
|
-
function rec(node) {
|
258
|
-
if (typeof node === "string") {
|
259
|
-
texts[texts.length - 1] += node;
|
260
|
-
} else if ("tag" in node && node.tag) {
|
261
|
-
var _node$children, _node$tag;
|
262
|
-
if (node.tag === "h1" || node.tag === "h2" || node.tag === "h3" || node.tag === "h4" || node.tag === "h5" || node.tag === "h6") {
|
263
|
-
var _node$tag$match;
|
264
|
-
const depth = Number((_node$tag$match = node.tag.match(HeaderRegEx)) === null || _node$tag$match === void 0 ? void 0 : _node$tag$match[1]);
|
265
|
-
if (Number.isNaN(depth)) {
|
266
|
-
throw new Error("Invalid header depth");
|
267
|
-
}
|
268
|
-
for (let i = 0; i < Number(depth); i++) {
|
269
|
-
texts[texts.length - 1] += "#";
|
270
|
-
}
|
271
|
-
texts[texts.length - 1] += " ";
|
272
|
-
} else if (node.tag === "p") ; else if (node.tag === "ul") {
|
273
|
-
listContext = "ul";
|
274
|
-
texts[texts.length - 1] += "\n";
|
275
|
-
} else if (node.tag === "ol") {
|
276
|
-
listContext = "ol";
|
277
|
-
texts[texts.length - 1] += "\n";
|
278
|
-
} else if (node.tag === "li") {
|
279
|
-
if (listContext === "ul") {
|
280
|
-
texts[texts.length - 1] += "\n- ";
|
281
|
-
} else if (listContext === "ol") {
|
282
|
-
texts[texts.length - 1] += "\n1. ";
|
283
|
-
} else {
|
284
|
-
throw new Error("Unexpected list context");
|
285
|
-
}
|
286
|
-
} else if (node.tag === "span") {
|
287
|
-
if (node.classes.includes("bold") && !node.classes.includes("italic")) {
|
288
|
-
texts[texts.length - 1] += "**";
|
289
|
-
}
|
290
|
-
if (node.classes.includes("italic") && !node.classes.includes("bold")) {
|
291
|
-
texts[texts.length - 1] += "*";
|
292
|
-
}
|
293
|
-
if (node.classes.includes("italic") && node.classes.includes("bold")) {
|
294
|
-
texts[texts.length - 1] += "***";
|
295
|
-
}
|
296
|
-
if (node.classes.includes("line-through")) {
|
297
|
-
texts[texts.length - 1] += "~~";
|
298
|
-
}
|
299
|
-
} else {
|
300
|
-
//exhaustive match
|
301
|
-
const exhaustiveCheck = node.tag;
|
302
|
-
throw new Error("Unexpected node tag: " + JSON.stringify(node, exhaustiveCheck, 2));
|
303
|
-
}
|
304
|
-
(_node$children = node.children) === null || _node$children === void 0 ? void 0 : _node$children.forEach(rec);
|
305
|
-
didAppendNewLines = false;
|
306
|
-
if (node.tag === "span") {
|
307
|
-
if (node.classes.includes("line-through")) {
|
308
|
-
texts[texts.length - 1] += "~~";
|
309
|
-
}
|
310
|
-
if (node.classes.includes("italic") && node.classes.includes("bold")) {
|
311
|
-
texts[texts.length - 1] += "***";
|
312
|
-
}
|
313
|
-
if (node.classes.includes("italic") && !node.classes.includes("bold")) {
|
314
|
-
texts[texts.length - 1] += "*";
|
315
|
-
}
|
316
|
-
if (node.classes.includes("bold") && !node.classes.includes("italic")) {
|
317
|
-
texts[texts.length - 1] += "**";
|
318
|
-
}
|
319
|
-
} else if (node.tag === "p") {
|
320
|
-
didAppendNewLines = true;
|
321
|
-
texts[texts.length - 1] += "\n\n";
|
322
|
-
} else if (node.tag === "ul" || node.tag === "ol") {
|
323
|
-
listContext = null;
|
324
|
-
texts[texts.length - 1] += "\n";
|
325
|
-
} else if ((_node$tag = node.tag) !== null && _node$tag !== void 0 && _node$tag.startsWith("h")) {
|
326
|
-
didAppendNewLines = true;
|
327
|
-
texts[texts.length - 1] += "\n\n";
|
328
|
-
}
|
329
|
-
} else {
|
330
|
-
nodes.push(node); // ImageSource
|
331
|
-
texts.push("\n");
|
332
|
-
}
|
333
|
-
}
|
334
|
-
source.children.forEach(rec);
|
335
|
-
if (texts[texts.length - 1] && didAppendNewLines) {
|
336
|
-
// remove last \n\n
|
337
|
-
texts[texts.length - 1] = texts[texts.length - 1].slice(0, -2);
|
338
|
-
}
|
339
|
-
return [texts, nodes];
|
340
|
-
}
|
341
|
-
|
342
249
|
function isValidIdentifier(text) {
|
343
250
|
if (text.length === 0) {
|
344
251
|
return false;
|
@@ -363,11 +270,20 @@ function createValFileReference(value) {
|
|
363
270
|
}
|
364
271
|
return ts__default["default"].factory.createCallExpression(ts__default["default"].factory.createPropertyAccessExpression(ts__default["default"].factory.createIdentifier("val"), ts__default["default"].factory.createIdentifier("file")), undefined, args);
|
365
272
|
}
|
273
|
+
function createValLink(value) {
|
274
|
+
const args = [ts__default["default"].factory.createStringLiteral(value.children[0]), toExpression({
|
275
|
+
href: value.href
|
276
|
+
})];
|
277
|
+
return ts__default["default"].factory.createCallExpression(ts__default["default"].factory.createPropertyAccessExpression(ts__default["default"].factory.createIdentifier("val"), ts__default["default"].factory.createIdentifier("link")), undefined, args);
|
278
|
+
}
|
366
279
|
function createValRichTextTaggedStringTemplate(value) {
|
367
|
-
const
|
280
|
+
const {
|
281
|
+
templateStrings: [head, ...others],
|
282
|
+
exprs
|
283
|
+
} = value;
|
368
284
|
const tag = ts__default["default"].factory.createPropertyAccessExpression(ts__default["default"].factory.createIdentifier("val"), ts__default["default"].factory.createIdentifier("richtext"));
|
369
|
-
if (
|
370
|
-
return ts__default["default"].factory.createTaggedTemplateExpression(tag, undefined, ts__default["default"].factory.createTemplateExpression(ts__default["default"].factory.createTemplateHead(head, head), others.map((s, i) => ts__default["default"].factory.createTemplateSpan(toExpression(
|
285
|
+
if (exprs.length > 0) {
|
286
|
+
return ts__default["default"].factory.createTaggedTemplateExpression(tag, undefined, ts__default["default"].factory.createTemplateExpression(ts__default["default"].factory.createTemplateHead(head, head), others.map((s, i) => ts__default["default"].factory.createTemplateSpan(toExpression(exprs[i]), i < others.length - 1 ? ts__default["default"].factory.createTemplateMiddle(s, s) : ts__default["default"].factory.createTemplateTail(s, s)))));
|
371
287
|
}
|
372
288
|
return ts__default["default"].factory.createTaggedTemplateExpression(tag, undefined, ts__default["default"].factory.createNoSubstitutionTemplateLiteral(head, head));
|
373
289
|
}
|
@@ -386,6 +302,8 @@ function toExpression(value) {
|
|
386
302
|
} else if (typeof value === "object") {
|
387
303
|
if (isValFileValue(value)) {
|
388
304
|
return createValFileReference(value);
|
305
|
+
} else if (isValLinkValue(value)) {
|
306
|
+
return createValLink(value);
|
389
307
|
} else if (isValRichTextValue(value)) {
|
390
308
|
return createValRichTextTaggedStringTemplate(value);
|
391
309
|
}
|
@@ -620,8 +538,11 @@ function isValFileValue(value) {
|
|
620
538
|
// value[VAL_EXTENSION] === "file" &&
|
621
539
|
core.FILE_REF_PROP in value && typeof value[core.FILE_REF_PROP] === "string");
|
622
540
|
}
|
541
|
+
function isValLinkValue(value) {
|
542
|
+
return !!(typeof value === "object" && value && core.VAL_EXTENSION in value && value[core.VAL_EXTENSION] === "link");
|
543
|
+
}
|
623
544
|
function isValRichTextValue(value) {
|
624
|
-
return !!(typeof value === "object" && value && core.VAL_EXTENSION in value && value[core.VAL_EXTENSION] === "richtext" && "
|
545
|
+
return !!(typeof value === "object" && value && core.VAL_EXTENSION in value && value[core.VAL_EXTENSION] === "richtext" && "templateStrings" in value && typeof value.templateStrings === "object" && Array.isArray(value.templateStrings));
|
625
546
|
}
|
626
547
|
function addToNode(document, node, key, value) {
|
627
548
|
if (ts__default["default"].isArrayLiteralExpression(node)) {
|
@@ -215,99 +215,6 @@ function analyzeValModule(sourceFile) {
|
|
215
215
|
return analysis;
|
216
216
|
}
|
217
217
|
|
218
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
219
|
-
|
220
|
-
const HeaderRegEx = /^h([\d+])$/;
|
221
|
-
function richTextToTaggedStringTemplate(source) {
|
222
|
-
const texts = [""];
|
223
|
-
const nodes = [];
|
224
|
-
let didAppendNewLines = false;
|
225
|
-
let listContext = null;
|
226
|
-
function rec(node) {
|
227
|
-
if (typeof node === "string") {
|
228
|
-
texts[texts.length - 1] += node;
|
229
|
-
} else if ("tag" in node && node.tag) {
|
230
|
-
var _node$children, _node$tag;
|
231
|
-
if (node.tag === "h1" || node.tag === "h2" || node.tag === "h3" || node.tag === "h4" || node.tag === "h5" || node.tag === "h6") {
|
232
|
-
var _node$tag$match;
|
233
|
-
const depth = Number((_node$tag$match = node.tag.match(HeaderRegEx)) === null || _node$tag$match === void 0 ? void 0 : _node$tag$match[1]);
|
234
|
-
if (Number.isNaN(depth)) {
|
235
|
-
throw new Error("Invalid header depth");
|
236
|
-
}
|
237
|
-
for (let i = 0; i < Number(depth); i++) {
|
238
|
-
texts[texts.length - 1] += "#";
|
239
|
-
}
|
240
|
-
texts[texts.length - 1] += " ";
|
241
|
-
} else if (node.tag === "p") ; else if (node.tag === "ul") {
|
242
|
-
listContext = "ul";
|
243
|
-
texts[texts.length - 1] += "\n";
|
244
|
-
} else if (node.tag === "ol") {
|
245
|
-
listContext = "ol";
|
246
|
-
texts[texts.length - 1] += "\n";
|
247
|
-
} else if (node.tag === "li") {
|
248
|
-
if (listContext === "ul") {
|
249
|
-
texts[texts.length - 1] += "\n- ";
|
250
|
-
} else if (listContext === "ol") {
|
251
|
-
texts[texts.length - 1] += "\n1. ";
|
252
|
-
} else {
|
253
|
-
throw new Error("Unexpected list context");
|
254
|
-
}
|
255
|
-
} else if (node.tag === "span") {
|
256
|
-
if (node.classes.includes("bold") && !node.classes.includes("italic")) {
|
257
|
-
texts[texts.length - 1] += "**";
|
258
|
-
}
|
259
|
-
if (node.classes.includes("italic") && !node.classes.includes("bold")) {
|
260
|
-
texts[texts.length - 1] += "*";
|
261
|
-
}
|
262
|
-
if (node.classes.includes("italic") && node.classes.includes("bold")) {
|
263
|
-
texts[texts.length - 1] += "***";
|
264
|
-
}
|
265
|
-
if (node.classes.includes("line-through")) {
|
266
|
-
texts[texts.length - 1] += "~~";
|
267
|
-
}
|
268
|
-
} else {
|
269
|
-
//exhaustive match
|
270
|
-
const exhaustiveCheck = node.tag;
|
271
|
-
throw new Error("Unexpected node tag: " + JSON.stringify(node, exhaustiveCheck, 2));
|
272
|
-
}
|
273
|
-
(_node$children = node.children) === null || _node$children === void 0 ? void 0 : _node$children.forEach(rec);
|
274
|
-
didAppendNewLines = false;
|
275
|
-
if (node.tag === "span") {
|
276
|
-
if (node.classes.includes("line-through")) {
|
277
|
-
texts[texts.length - 1] += "~~";
|
278
|
-
}
|
279
|
-
if (node.classes.includes("italic") && node.classes.includes("bold")) {
|
280
|
-
texts[texts.length - 1] += "***";
|
281
|
-
}
|
282
|
-
if (node.classes.includes("italic") && !node.classes.includes("bold")) {
|
283
|
-
texts[texts.length - 1] += "*";
|
284
|
-
}
|
285
|
-
if (node.classes.includes("bold") && !node.classes.includes("italic")) {
|
286
|
-
texts[texts.length - 1] += "**";
|
287
|
-
}
|
288
|
-
} else if (node.tag === "p") {
|
289
|
-
didAppendNewLines = true;
|
290
|
-
texts[texts.length - 1] += "\n\n";
|
291
|
-
} else if (node.tag === "ul" || node.tag === "ol") {
|
292
|
-
listContext = null;
|
293
|
-
texts[texts.length - 1] += "\n";
|
294
|
-
} else if ((_node$tag = node.tag) !== null && _node$tag !== void 0 && _node$tag.startsWith("h")) {
|
295
|
-
didAppendNewLines = true;
|
296
|
-
texts[texts.length - 1] += "\n\n";
|
297
|
-
}
|
298
|
-
} else {
|
299
|
-
nodes.push(node); // ImageSource
|
300
|
-
texts.push("\n");
|
301
|
-
}
|
302
|
-
}
|
303
|
-
source.children.forEach(rec);
|
304
|
-
if (texts[texts.length - 1] && didAppendNewLines) {
|
305
|
-
// remove last \n\n
|
306
|
-
texts[texts.length - 1] = texts[texts.length - 1].slice(0, -2);
|
307
|
-
}
|
308
|
-
return [texts, nodes];
|
309
|
-
}
|
310
|
-
|
311
218
|
function isValidIdentifier(text) {
|
312
219
|
if (text.length === 0) {
|
313
220
|
return false;
|
@@ -332,11 +239,20 @@ function createValFileReference(value) {
|
|
332
239
|
}
|
333
240
|
return ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("val"), ts.factory.createIdentifier("file")), undefined, args);
|
334
241
|
}
|
242
|
+
function createValLink(value) {
|
243
|
+
const args = [ts.factory.createStringLiteral(value.children[0]), toExpression({
|
244
|
+
href: value.href
|
245
|
+
})];
|
246
|
+
return ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("val"), ts.factory.createIdentifier("link")), undefined, args);
|
247
|
+
}
|
335
248
|
function createValRichTextTaggedStringTemplate(value) {
|
336
|
-
const
|
249
|
+
const {
|
250
|
+
templateStrings: [head, ...others],
|
251
|
+
exprs
|
252
|
+
} = value;
|
337
253
|
const tag = ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("val"), ts.factory.createIdentifier("richtext"));
|
338
|
-
if (
|
339
|
-
return ts.factory.createTaggedTemplateExpression(tag, undefined, ts.factory.createTemplateExpression(ts.factory.createTemplateHead(head, head), others.map((s, i) => ts.factory.createTemplateSpan(toExpression(
|
254
|
+
if (exprs.length > 0) {
|
255
|
+
return ts.factory.createTaggedTemplateExpression(tag, undefined, ts.factory.createTemplateExpression(ts.factory.createTemplateHead(head, head), others.map((s, i) => ts.factory.createTemplateSpan(toExpression(exprs[i]), i < others.length - 1 ? ts.factory.createTemplateMiddle(s, s) : ts.factory.createTemplateTail(s, s)))));
|
340
256
|
}
|
341
257
|
return ts.factory.createTaggedTemplateExpression(tag, undefined, ts.factory.createNoSubstitutionTemplateLiteral(head, head));
|
342
258
|
}
|
@@ -355,6 +271,8 @@ function toExpression(value) {
|
|
355
271
|
} else if (typeof value === "object") {
|
356
272
|
if (isValFileValue(value)) {
|
357
273
|
return createValFileReference(value);
|
274
|
+
} else if (isValLinkValue(value)) {
|
275
|
+
return createValLink(value);
|
358
276
|
} else if (isValRichTextValue(value)) {
|
359
277
|
return createValRichTextTaggedStringTemplate(value);
|
360
278
|
}
|
@@ -589,8 +507,11 @@ function isValFileValue(value) {
|
|
589
507
|
// value[VAL_EXTENSION] === "file" &&
|
590
508
|
FILE_REF_PROP in value && typeof value[FILE_REF_PROP] === "string");
|
591
509
|
}
|
510
|
+
function isValLinkValue(value) {
|
511
|
+
return !!(typeof value === "object" && value && VAL_EXTENSION in value && value[VAL_EXTENSION] === "link");
|
512
|
+
}
|
592
513
|
function isValRichTextValue(value) {
|
593
|
-
return !!(typeof value === "object" && value && VAL_EXTENSION in value && value[VAL_EXTENSION] === "richtext" && "
|
514
|
+
return !!(typeof value === "object" && value && VAL_EXTENSION in value && value[VAL_EXTENSION] === "richtext" && "templateStrings" in value && typeof value.templateStrings === "object" && Array.isArray(value.templateStrings));
|
594
515
|
}
|
595
516
|
function addToNode(document, node, key, value) {
|
596
517
|
if (ts.isArrayLiteralExpression(node)) {
|
package/package.json
CHANGED
@@ -12,7 +12,7 @@
|
|
12
12
|
"./package.json": "./package.json"
|
13
13
|
},
|
14
14
|
"types": "dist/valbuild-server.cjs.d.ts",
|
15
|
-
"version": "0.
|
15
|
+
"version": "0.21.0",
|
16
16
|
"scripts": {
|
17
17
|
"typecheck": "tsc --noEmit",
|
18
18
|
"test": "jest",
|
@@ -25,8 +25,8 @@
|
|
25
25
|
"concurrently": "^7.6.0"
|
26
26
|
},
|
27
27
|
"dependencies": {
|
28
|
-
"@valbuild/core": "~0.
|
29
|
-
"@valbuild/ui": "~0.
|
28
|
+
"@valbuild/core": "~0.21.0",
|
29
|
+
"@valbuild/ui": "~0.21.0",
|
30
30
|
"express": "^4.18.2",
|
31
31
|
"image-size": "^1.0.2",
|
32
32
|
"quickjs-emscripten": "^0.21.1",
|
package/src/ProxyValServer.ts
CHANGED
package/src/patch/ts/ops.test.ts
CHANGED
@@ -456,7 +456,8 @@ describe("TSOps", () => {
|
|
456
456
|
path: [],
|
457
457
|
value: {
|
458
458
|
[VAL_EXTENSION]: "richtext",
|
459
|
-
|
459
|
+
templateStrings: ["Test 2"],
|
460
|
+
exprs: [],
|
460
461
|
},
|
461
462
|
expected: result.ok("val.richtext `Test 2`"),
|
462
463
|
},
|
@@ -466,13 +467,10 @@ describe("TSOps", () => {
|
|
466
467
|
path: [],
|
467
468
|
value: {
|
468
469
|
[VAL_EXTENSION]: "richtext",
|
469
|
-
|
470
|
-
|
471
|
-
{ tag: "p", children: ["Test 2"] },
|
472
|
-
],
|
470
|
+
templateStrings: ["# Title 1\nTest 2"],
|
471
|
+
exprs: [],
|
473
472
|
},
|
474
473
|
expected: result.ok(`val.richtext \`# Title 1
|
475
|
-
|
476
474
|
Test 2\``),
|
477
475
|
},
|
478
476
|
{
|
@@ -481,9 +479,8 @@ Test 2\``),
|
|
481
479
|
path: [],
|
482
480
|
value: {
|
483
481
|
[VAL_EXTENSION]: "richtext",
|
484
|
-
|
485
|
-
|
486
|
-
{ tag: "p", children: ["Test 2"] },
|
482
|
+
templateStrings: ["# Title 1\nTest 2\n", ""],
|
483
|
+
exprs: [
|
487
484
|
{
|
488
485
|
[VAL_EXTENSION]: "file",
|
489
486
|
[FILE_REF_PROP]: "/public/test",
|
@@ -492,9 +489,7 @@ Test 2\``),
|
|
492
489
|
],
|
493
490
|
},
|
494
491
|
expected: result.ok(`val.richtext \`# Title 1
|
495
|
-
|
496
492
|
Test 2
|
497
|
-
|
498
493
|
\${val.file("/public/test", { width: 100, height: 100, sha256: "123" })}\``),
|
499
494
|
},
|
500
495
|
{
|
@@ -503,8 +498,8 @@ Test 2
|
|
503
498
|
path: [],
|
504
499
|
value: {
|
505
500
|
[VAL_EXTENSION]: "richtext",
|
506
|
-
|
507
|
-
|
501
|
+
templateStrings: ["# Title 1\n", "\n", "\nTest 2"],
|
502
|
+
exprs: [
|
508
503
|
{
|
509
504
|
[VAL_EXTENSION]: "file",
|
510
505
|
[FILE_REF_PROP]: "/public/test1",
|
@@ -515,14 +510,36 @@ Test 2
|
|
515
510
|
[FILE_REF_PROP]: "/public/test2",
|
516
511
|
metadata: { width: 100, height: 100, sha256: "123" },
|
517
512
|
},
|
518
|
-
{ tag: "p", children: ["Test 2"] },
|
519
513
|
],
|
520
514
|
},
|
521
515
|
expected: result.ok(`val.richtext \`# Title 1
|
522
|
-
|
523
516
|
\${val.file("/public/test1", { width: 100, height: 100, sha256: "123" })}
|
524
517
|
\${val.file("/public/test2", { width: 100, height: 100, sha256: "123" })}
|
525
518
|
Test 2\``),
|
519
|
+
},
|
520
|
+
{
|
521
|
+
name: "val.richtext link",
|
522
|
+
input: "val.richtext`Test`",
|
523
|
+
path: [],
|
524
|
+
value: {
|
525
|
+
[VAL_EXTENSION]: "richtext",
|
526
|
+
templateStrings: ["# Title 1\n", "\n", ""],
|
527
|
+
exprs: [
|
528
|
+
{
|
529
|
+
[VAL_EXTENSION]: "link",
|
530
|
+
href: "https://example.com",
|
531
|
+
children: ["https://example.com"],
|
532
|
+
},
|
533
|
+
{
|
534
|
+
[VAL_EXTENSION]: "file",
|
535
|
+
[FILE_REF_PROP]: "/public/test2",
|
536
|
+
metadata: { width: 100, height: 100, sha256: "123" },
|
537
|
+
},
|
538
|
+
],
|
539
|
+
},
|
540
|
+
expected: result.ok(`val.richtext \`# Title 1
|
541
|
+
\${val.link("https://example.com", { href: "https://example.com" })}
|
542
|
+
\${val.file("/public/test2", { width: 100, height: 100, sha256: "123" })}\``),
|
526
543
|
},
|
527
544
|
{
|
528
545
|
name: "val.richtext empty head",
|
@@ -531,7 +548,8 @@ Test 2\``),
|
|
531
548
|
path: ["text"],
|
532
549
|
value: {
|
533
550
|
[VAL_EXTENSION]: "richtext",
|
534
|
-
|
551
|
+
templateStrings: ["", "\n", "\nTest 2"],
|
552
|
+
exprs: [
|
535
553
|
{
|
536
554
|
[VAL_EXTENSION]: "file",
|
537
555
|
[FILE_REF_PROP]: "/public/test1",
|
@@ -542,7 +560,6 @@ Test 2\``),
|
|
542
560
|
[FILE_REF_PROP]: "/public/test2",
|
543
561
|
metadata: { width: 100, height: 100, sha256: "123" },
|
544
562
|
},
|
545
|
-
{ tag: "p", children: ["Test 2"] },
|
546
563
|
],
|
547
564
|
},
|
548
565
|
expected:
|
package/src/patch/ts/ops.ts
CHANGED
@@ -26,7 +26,7 @@ import {
|
|
26
26
|
VAL_EXTENSION,
|
27
27
|
} from "@valbuild/core";
|
28
28
|
import { JsonPrimitive } from "@valbuild/core/src/Json";
|
29
|
-
import {
|
29
|
+
import { LinkSource } from "@valbuild/core/src/source/link";
|
30
30
|
|
31
31
|
type TSOpsResult<T> = result.Result<T, PatchError | ValSyntaxErrorTree>;
|
32
32
|
|
@@ -85,15 +85,34 @@ function createValFileReference(value: FileSource) {
|
|
85
85
|
);
|
86
86
|
}
|
87
87
|
|
88
|
+
function createValLink(value: LinkSource) {
|
89
|
+
const args: ts.Expression[] = [
|
90
|
+
ts.factory.createStringLiteral(value.children[0]),
|
91
|
+
toExpression({ href: value.href }),
|
92
|
+
];
|
93
|
+
|
94
|
+
return ts.factory.createCallExpression(
|
95
|
+
ts.factory.createPropertyAccessExpression(
|
96
|
+
ts.factory.createIdentifier("val"),
|
97
|
+
ts.factory.createIdentifier("link")
|
98
|
+
),
|
99
|
+
undefined,
|
100
|
+
args
|
101
|
+
);
|
102
|
+
}
|
103
|
+
|
88
104
|
function createValRichTextTaggedStringTemplate(
|
89
105
|
value: RichTextSource<AnyRichTextOptions>
|
90
106
|
): ts.Expression {
|
91
|
-
const
|
107
|
+
const {
|
108
|
+
templateStrings: [head, ...others],
|
109
|
+
exprs,
|
110
|
+
} = value;
|
92
111
|
const tag = ts.factory.createPropertyAccessExpression(
|
93
112
|
ts.factory.createIdentifier("val"),
|
94
113
|
ts.factory.createIdentifier("richtext")
|
95
114
|
);
|
96
|
-
if (
|
115
|
+
if (exprs.length > 0) {
|
97
116
|
return ts.factory.createTaggedTemplateExpression(
|
98
117
|
tag,
|
99
118
|
undefined,
|
@@ -101,7 +120,7 @@ function createValRichTextTaggedStringTemplate(
|
|
101
120
|
ts.factory.createTemplateHead(head, head),
|
102
121
|
others.map((s, i) =>
|
103
122
|
ts.factory.createTemplateSpan(
|
104
|
-
toExpression(
|
123
|
+
toExpression(exprs[i]),
|
105
124
|
i < others.length - 1
|
106
125
|
? ts.factory.createTemplateMiddle(s, s)
|
107
126
|
: ts.factory.createTemplateTail(s, s)
|
@@ -132,6 +151,8 @@ function toExpression(value: JSONValue): ts.Expression {
|
|
132
151
|
} else if (typeof value === "object") {
|
133
152
|
if (isValFileValue(value)) {
|
134
153
|
return createValFileReference(value);
|
154
|
+
} else if (isValLinkValue(value)) {
|
155
|
+
return createValLink(value);
|
135
156
|
} else if (isValRichTextValue(value)) {
|
136
157
|
return createValRichTextTaggedStringTemplate(value);
|
137
158
|
}
|
@@ -591,7 +612,7 @@ function removeAtPath(
|
|
591
612
|
);
|
592
613
|
}
|
593
614
|
|
594
|
-
function isValFileValue(value: JSONValue): value is FileSource<{
|
615
|
+
export function isValFileValue(value: JSONValue): value is FileSource<{
|
595
616
|
[key: string]: JsonPrimitive;
|
596
617
|
}> {
|
597
618
|
return !!(
|
@@ -604,6 +625,14 @@ function isValFileValue(value: JSONValue): value is FileSource<{
|
|
604
625
|
typeof value[FILE_REF_PROP] === "string"
|
605
626
|
);
|
606
627
|
}
|
628
|
+
function isValLinkValue(value: JSONValue): value is LinkSource {
|
629
|
+
return !!(
|
630
|
+
typeof value === "object" &&
|
631
|
+
value &&
|
632
|
+
VAL_EXTENSION in value &&
|
633
|
+
value[VAL_EXTENSION] === "link"
|
634
|
+
);
|
635
|
+
}
|
607
636
|
|
608
637
|
function isValRichTextValue(
|
609
638
|
value: JSONValue
|
@@ -613,9 +642,9 @@ function isValRichTextValue(
|
|
613
642
|
value &&
|
614
643
|
VAL_EXTENSION in value &&
|
615
644
|
value[VAL_EXTENSION] === "richtext" &&
|
616
|
-
"
|
617
|
-
typeof value.
|
618
|
-
Array.isArray(value.
|
645
|
+
"templateStrings" in value &&
|
646
|
+
typeof value.templateStrings === "object" &&
|
647
|
+
Array.isArray(value.templateStrings)
|
619
648
|
);
|
620
649
|
}
|
621
650
|
|
@@ -1,100 +0,0 @@
|
|
1
|
-
import { initVal } from "@valbuild/core";
|
2
|
-
import { richTextToTaggedStringTemplate } from "./richtext";
|
3
|
-
|
4
|
-
describe("patch richtext", () => {
|
5
|
-
test("basic richtext <-> markdown", () => {
|
6
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
7
|
-
const input: any = {
|
8
|
-
_type: "richtext",
|
9
|
-
children: [
|
10
|
-
{ tag: "h1", children: ["Title 1"] },
|
11
|
-
{
|
12
|
-
tag: "p",
|
13
|
-
children: [
|
14
|
-
{
|
15
|
-
tag: "span",
|
16
|
-
classes: ["bold"],
|
17
|
-
children: ["Bold text"],
|
18
|
-
},
|
19
|
-
],
|
20
|
-
},
|
21
|
-
{ _type: "file", _ref: "/public/image.png" },
|
22
|
-
{ tag: "p", children: ["Paragraph 2"] },
|
23
|
-
],
|
24
|
-
};
|
25
|
-
const r = richTextToTaggedStringTemplate(input);
|
26
|
-
expect(r).toStrictEqual([
|
27
|
-
["# Title 1\n\n**Bold text**\n\n", "\nParagraph 2"],
|
28
|
-
[{ _type: "file", _ref: "/public/image.png" }],
|
29
|
-
]);
|
30
|
-
|
31
|
-
const { val } = initVal();
|
32
|
-
const r2 = val.richtext(
|
33
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
34
|
-
// @ts-expect-error
|
35
|
-
r[0],
|
36
|
-
...r[1]
|
37
|
-
);
|
38
|
-
expect(r2).toStrictEqual(input);
|
39
|
-
});
|
40
|
-
|
41
|
-
test("richtext <-> markdown", () => {
|
42
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
43
|
-
const input: any = {
|
44
|
-
_type: "richtext",
|
45
|
-
children: [
|
46
|
-
{ tag: "h1", children: ["Title 1"] },
|
47
|
-
{ tag: "h2", children: ["Title 2"] },
|
48
|
-
{
|
49
|
-
tag: "p",
|
50
|
-
children: [
|
51
|
-
"Test 1 2 3. ",
|
52
|
-
{
|
53
|
-
tag: "span",
|
54
|
-
classes: ["bold"],
|
55
|
-
children: ["Bold text"],
|
56
|
-
},
|
57
|
-
". More text. See image below",
|
58
|
-
],
|
59
|
-
},
|
60
|
-
{ _type: "file", _ref: "/public/image.png" },
|
61
|
-
{ tag: "p", children: ["Paragraph 2"] },
|
62
|
-
{
|
63
|
-
tag: "ol",
|
64
|
-
children: [
|
65
|
-
{ tag: "li", children: ["OL:Item 1"] },
|
66
|
-
{ tag: "li", children: ["OL:Item 2"] },
|
67
|
-
],
|
68
|
-
},
|
69
|
-
{
|
70
|
-
tag: "ul",
|
71
|
-
children: [
|
72
|
-
{ tag: "li", children: ["UL:Item 2"] },
|
73
|
-
{ tag: "li", children: ["UL:Item 3"] },
|
74
|
-
],
|
75
|
-
},
|
76
|
-
{ tag: "h3", children: ["Title 3"] },
|
77
|
-
{
|
78
|
-
tag: "ul",
|
79
|
-
children: [
|
80
|
-
{
|
81
|
-
tag: "li",
|
82
|
-
children: [
|
83
|
-
{ tag: "span", classes: ["bold"], children: ["UL:Item 4"] },
|
84
|
-
],
|
85
|
-
},
|
86
|
-
],
|
87
|
-
},
|
88
|
-
],
|
89
|
-
};
|
90
|
-
const r = richTextToTaggedStringTemplate(input);
|
91
|
-
const { val } = initVal();
|
92
|
-
const r2 = val.richtext(
|
93
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
94
|
-
// @ts-expect-error
|
95
|
-
r[0],
|
96
|
-
...r[1]
|
97
|
-
);
|
98
|
-
expect(r2).toStrictEqual(input);
|
99
|
-
});
|
100
|
-
});
|
package/src/patch/ts/richtext.ts
DELETED
@@ -1,113 +0,0 @@
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
2
|
-
import {
|
3
|
-
AnyRichTextOptions,
|
4
|
-
RichTextSource,
|
5
|
-
RichTextSourceNode,
|
6
|
-
} from "@valbuild/core";
|
7
|
-
|
8
|
-
const HeaderRegEx = /^h([\d+])$/;
|
9
|
-
|
10
|
-
export function richTextToTaggedStringTemplate(
|
11
|
-
source: RichTextSource<AnyRichTextOptions>
|
12
|
-
) {
|
13
|
-
const texts: string[] = [""];
|
14
|
-
const nodes: any[] = [];
|
15
|
-
let didAppendNewLines = false;
|
16
|
-
let listContext: "ul" | "ol" | null = null;
|
17
|
-
|
18
|
-
function rec(node: RichTextSourceNode<AnyRichTextOptions>) {
|
19
|
-
if (typeof node === "string") {
|
20
|
-
texts[texts.length - 1] += node;
|
21
|
-
} else if ("tag" in node && node.tag) {
|
22
|
-
if (
|
23
|
-
node.tag === "h1" ||
|
24
|
-
node.tag === "h2" ||
|
25
|
-
node.tag === "h3" ||
|
26
|
-
node.tag === "h4" ||
|
27
|
-
node.tag === "h5" ||
|
28
|
-
node.tag === "h6"
|
29
|
-
) {
|
30
|
-
const depth = Number(node.tag.match(HeaderRegEx)?.[1]);
|
31
|
-
if (Number.isNaN(depth)) {
|
32
|
-
throw new Error("Invalid header depth");
|
33
|
-
}
|
34
|
-
for (let i = 0; i < Number(depth); i++) {
|
35
|
-
texts[texts.length - 1] += "#";
|
36
|
-
}
|
37
|
-
texts[texts.length - 1] += " ";
|
38
|
-
} else if (node.tag === "p") {
|
39
|
-
// Ignore
|
40
|
-
} else if (node.tag === "ul") {
|
41
|
-
listContext = "ul";
|
42
|
-
texts[texts.length - 1] += "\n";
|
43
|
-
} else if (node.tag === "ol") {
|
44
|
-
listContext = "ol";
|
45
|
-
texts[texts.length - 1] += "\n";
|
46
|
-
} else if (node.tag === "li") {
|
47
|
-
if (listContext === "ul") {
|
48
|
-
texts[texts.length - 1] += "\n- ";
|
49
|
-
} else if (listContext === "ol") {
|
50
|
-
texts[texts.length - 1] += "\n1. ";
|
51
|
-
} else {
|
52
|
-
throw new Error("Unexpected list context");
|
53
|
-
}
|
54
|
-
} else if (node.tag === "span") {
|
55
|
-
if (node.classes.includes("bold") && !node.classes.includes("italic")) {
|
56
|
-
texts[texts.length - 1] += "**";
|
57
|
-
}
|
58
|
-
if (node.classes.includes("italic") && !node.classes.includes("bold")) {
|
59
|
-
texts[texts.length - 1] += "*";
|
60
|
-
}
|
61
|
-
if (node.classes.includes("italic") && node.classes.includes("bold")) {
|
62
|
-
texts[texts.length - 1] += "***";
|
63
|
-
}
|
64
|
-
if (node.classes.includes("line-through")) {
|
65
|
-
texts[texts.length - 1] += "~~";
|
66
|
-
}
|
67
|
-
} else {
|
68
|
-
//exhaustive match
|
69
|
-
const exhaustiveCheck: never = node.tag;
|
70
|
-
throw new Error(
|
71
|
-
"Unexpected node tag: " + JSON.stringify(node, exhaustiveCheck, 2)
|
72
|
-
);
|
73
|
-
}
|
74
|
-
|
75
|
-
node.children?.forEach(rec);
|
76
|
-
|
77
|
-
didAppendNewLines = false;
|
78
|
-
if (node.tag === "span") {
|
79
|
-
if (node.classes.includes("line-through")) {
|
80
|
-
texts[texts.length - 1] += "~~";
|
81
|
-
}
|
82
|
-
if (node.classes.includes("italic") && node.classes.includes("bold")) {
|
83
|
-
texts[texts.length - 1] += "***";
|
84
|
-
}
|
85
|
-
if (node.classes.includes("italic") && !node.classes.includes("bold")) {
|
86
|
-
texts[texts.length - 1] += "*";
|
87
|
-
}
|
88
|
-
if (node.classes.includes("bold") && !node.classes.includes("italic")) {
|
89
|
-
texts[texts.length - 1] += "**";
|
90
|
-
}
|
91
|
-
} else if (node.tag === "p") {
|
92
|
-
didAppendNewLines = true;
|
93
|
-
texts[texts.length - 1] += "\n\n";
|
94
|
-
} else if (node.tag === "ul" || node.tag === "ol") {
|
95
|
-
listContext = null;
|
96
|
-
texts[texts.length - 1] += "\n";
|
97
|
-
} else if (node.tag?.startsWith("h")) {
|
98
|
-
didAppendNewLines = true;
|
99
|
-
texts[texts.length - 1] += "\n\n";
|
100
|
-
}
|
101
|
-
} else {
|
102
|
-
nodes.push(node); // ImageSource
|
103
|
-
texts.push("\n");
|
104
|
-
}
|
105
|
-
}
|
106
|
-
source.children.forEach(rec);
|
107
|
-
|
108
|
-
if (texts[texts.length - 1] && didAppendNewLines) {
|
109
|
-
// remove last \n\n
|
110
|
-
texts[texts.length - 1] = texts[texts.length - 1].slice(0, -2);
|
111
|
-
}
|
112
|
-
return [texts, nodes];
|
113
|
-
}
|