summaryrefslogtreecommitdiff
path: root/dist
diff options
context:
space:
mode:
Diffstat (limited to 'dist')
-rw-r--r--dist/index.cjs336
-rw-r--r--dist/index.d.cts146
-rw-r--r--dist/index.d.ts146
-rw-r--r--dist/index.js307
4 files changed, 935 insertions, 0 deletions
diff --git a/dist/index.cjs b/dist/index.cjs
new file mode 100644
index 0000000..430cc82
--- /dev/null
+++ b/dist/index.cjs
@@ -0,0 +1,336 @@
+"use strict";
+var __defProp = Object.defineProperty;
+var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
+var __getOwnPropNames = Object.getOwnPropertyNames;
+var __hasOwnProp = Object.prototype.hasOwnProperty;
+var __export = (target, all) => {
+ for (var name in all)
+ __defProp(target, name, { get: all[name], enumerable: true });
+};
+var __copyProps = (to, from, except, desc) => {
+ if (from && typeof from === "object" || typeof from === "function") {
+ for (let key of __getOwnPropNames(from))
+ if (!__hasOwnProp.call(to, key) && key !== except)
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
+ }
+ return to;
+};
+var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
+
+// src/index.ts
+var index_exports = {};
+__export(index_exports, {
+ FlatMatter: () => FlatMatter,
+ ToJson: () => ToJson,
+ ToObject: () => ToObject
+});
+module.exports = __toCommonJS(index_exports);
+
+// src/utils.ts
+function trimChar(input, char) {
+ if (typeof char === "string") {
+ char = [char];
+ }
+ for (const c of char) {
+ if (input.charAt(0) === c) {
+ input = input.substring(1);
+ }
+ if (input.charAt(input.length - 1) === c) {
+ input = input.substring(0, input.length - 1);
+ }
+ }
+ return input;
+}
+
+// src/flatmatter.ts
+var FlatMatter = class {
+ content;
+ parsedConfig = {};
+ functions;
+ constructor(content, functions = []) {
+ this.content = content;
+ this.functions = functions;
+ this.parse();
+ }
+ parse() {
+ for (const line of this.content.split(/\r?\n/)) {
+ this.parseLine(line);
+ }
+ }
+ /**
+ * Parses a given line of FlatMatter.
+ *
+ * @param {string} line
+ * @returns {void}
+ */
+ parseLine(line) {
+ this.validateLineConformance(line);
+ const keys = line.split(":")[0].trim().split(".");
+ const value = line.split(":").slice(1).join(":").trim();
+ const parsedValue = this.parseValue(value);
+ if (!parsedValue) return;
+ const config = keys.reduceRight((acc, key) => {
+ return { [key]: acc };
+ }, this.computeValue(parsedValue));
+ this.parsedConfig = { ...this.parsedConfig, ...config };
+ }
+ validateLineConformance(line) {
+ }
+ validateLineHasKeyVal(line) {
+ return {
+ passed: true
+ };
+ }
+ validateLineHasOnlyOneColonChar(line) {
+ return {
+ passed: true
+ };
+ }
+ /**
+ * Detects if the value is a simple value. A simple value is any
+ * of the following: `"a string"`, boolean `true` or `false`, or
+ * anything numeric like `12345` or `123.45`.
+ *
+ * @param {string} value
+ * @returns {boolean}
+ */
+ isSimpleValue(value) {
+ const isString = value.startsWith('"') && value.endsWith('"');
+ const isBoolean = value === "true" || value === "false";
+ const isNumber = !isNaN(parseFloat(value));
+ return isString || isBoolean || isNumber;
+ }
+ /**
+ * Detects if the value is a function value. A function value is any
+ * of the following:
+ *
+ * - A function call with arguments: `(function-name *args)`
+ * - A function call by reference: `function-name`
+ *
+ * @param {string} value
+ * @returns {boolean}
+ */
+ isFunctionValue(value) {
+ const isFnCall = value.startsWith("(") && value.endsWith(")");
+ const isFnReference = !!value.match(/^([a-zA-Z0-9_-]+)$/);
+ return isFnCall || isFnReference;
+ }
+ /**
+ * Detects if the value is a piped value. A piped value is a mix of
+ * simple and function value parts, piped together with the forward
+ * slash `/` character. For example:
+ *
+ * ```yaml
+ * posts: (get-content "posts") / (limit 10) / only-published
+ * ```
+ *
+ * or:
+ *
+ * ```yaml
+ * posts: "posts" / get-content / (limit 10) / only-published
+ * ```
+ *
+ * The result of the previous pipe gets passed to the next as a first
+ * argument.
+ *
+ * @param {string} value
+ * @returns {boolean}
+ */
+ isPipedValue(value) {
+ for (const part of this.composePipedValueParts(value)) {
+ if (!this.isSimpleValue(part) && !this.isFunctionValue(part)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ /**
+ * Parses a value to a `ParsedValue` object, or `null`
+ * in case it could not for whatever reason.
+ *
+ * @param {string} value
+ * @returns {ParsedValue | null}
+ */
+ parseValue(value) {
+ if (this.isSimpleValue(value)) {
+ return {
+ value: this.parseSimpleValue(value),
+ computeActions: []
+ };
+ }
+ if (this.isFunctionValue(value)) {
+ return {
+ value: null,
+ computeActions: [this.parseFunctionValue(value)]
+ };
+ }
+ if (this.isPipedValue(value)) {
+ return this.parsePipedValue(value);
+ }
+ return null;
+ }
+ /**
+ * Parses the value part of a line into a simple value, like for example
+ * a `string`, `number` or `boolean`.
+ *
+ * @param {string} value
+ * @returns {string | number | boolean}
+ */
+ parseSimpleValue(value) {
+ if (value === "true" || value === "false") {
+ return value === "true";
+ }
+ if (!Number.isNaN(parseFloat(value))) {
+ return parseFloat(value);
+ }
+ if (!Number.isNaN(parseInt(value))) {
+ return parseInt(value);
+ }
+ return trimChar(value, '"');
+ }
+ /**
+ * Parses the value part of a line into a Compute Action, which is
+ * later executed to run the function described in FlatMatter.
+ *
+ * @param {string} value
+ * @returns {ComputeAction}
+ */
+ parseFunctionValue(value) {
+ const isFn = value.startsWith("(") && value.endsWith(")");
+ if (!isFn) {
+ return {
+ identifier: value,
+ args: []
+ };
+ }
+ const fnName = trimChar(value, ["(", ")"]).split(" ")[0].trim();
+ const fnArgs = this.parseFunctionValueArgs(value);
+ return {
+ identifier: fnName,
+ args: fnArgs
+ };
+ }
+ /**
+ * Parses the value part of a line into a ParsedValue, which is
+ * composed out of piped parts separated by the forward slash `/` character.
+ *
+ * The ParsedValue will include the default value, if any, and a list of compute
+ * actions which will later be executed.
+ *
+ * @param {string} value
+ * @returns {ParsedValue}
+ */
+ parsePipedValue(value) {
+ const parts = this.composePipedValueParts(value);
+ if (this.isSimpleValue(parts[0])) {
+ return {
+ value: this.parseSimpleValue(parts[0]),
+ computeActions: parts.slice(1).map((p) => this.parseFunctionValue(p))
+ };
+ }
+ return {
+ value: null,
+ computeActions: parts.map((p) => this.parseFunctionValue(p))
+ };
+ }
+ /**
+ * Takes the entire value part of a line and, assuming it is a function value,
+ * parses it into a list of arguments to be passed down to the function.
+ *
+ * @param {string} value
+ * @returns {unknown[]}
+ */
+ parseFunctionValueArgs(value) {
+ const parts = value.substring(1, value.length - 1).split(" ").slice(1);
+ if (!parts.length) {
+ return [];
+ }
+ const normalizedParts = [parts[0]];
+ for (let i = 1; i < parts.length; i++) {
+ const untilCurrent = normalizedParts.join(" ");
+ const quoteCount = untilCurrent.split('"').length - 1;
+ if (quoteCount % 2 === 0) {
+ normalizedParts.push(parts[i]);
+ continue;
+ }
+ const lastIndex = normalizedParts.length - 1;
+ const lastPart = normalizedParts[lastIndex];
+ normalizedParts[lastIndex] = `${lastPart} ${parts[i]}`;
+ }
+ return normalizedParts.map((part) => this.parseSimpleValue(part));
+ }
+ /**
+ * Takes an entire value of a line and composes it into a list
+ * of piped parts.
+ *
+ * @param {string} value
+ * @returns {string[]}
+ */
+ composePipedValueParts(value) {
+ const parts = value.split(" / ");
+ const normalizedParts = [parts[0]];
+ for (let i = 1; i < parts.length; i++) {
+ const untilCurrent = normalizedParts.join(" / ");
+ const quoteCount = untilCurrent.split('"').length - 1;
+ if (quoteCount % 2 === 0) {
+ normalizedParts.push(parts[i]);
+ continue;
+ }
+ const lastIndex = normalizedParts.length - 1;
+ const lastPart = normalizedParts[lastIndex];
+ normalizedParts[lastIndex] = `${lastPart} / ${parts[i]}`;
+ }
+ return normalizedParts;
+ }
+ /**
+ * Takes ParsedValue and, optionally an initial value, and runs
+ * compute actions over it to return the final computed value.
+ *
+ * @param {ParsedValue} parsedValue
+ * @returns {unknown}
+ */
+ computeValue(parsedValue) {
+ let value = parsedValue.value;
+ for (const ca of parsedValue.computeActions) {
+ const fnInstance = this.functions.find((f) => f.name === ca.identifier);
+ if (!fnInstance) {
+ continue;
+ }
+ if (value !== null) {
+ ca.args = [value, ...ca.args];
+ }
+ value = fnInstance.compute(...ca.args);
+ }
+ return value;
+ }
+ /**
+ * Takes a Serializer and uses it to transform internal data
+ * object to a desired output.
+ *
+ * @param {Serializer} serializer
+ * @returns {unknown}
+ */
+ serialize(serializer) {
+ return serializer.serialize(this.parsedConfig);
+ }
+};
+
+// src/serializers/to_object.ts
+var ToObject = class {
+ serialize(parsedConfig) {
+ return parsedConfig;
+ }
+};
+
+// src/serializers/to_json.ts
+var ToJson = class {
+ serialize(parsedConfig) {
+ return JSON.stringify(parsedConfig);
+ }
+};
+// Annotate the CommonJS export names for ESM import in node:
+0 && (module.exports = {
+ FlatMatter,
+ ToJson,
+ ToObject
+});
diff --git a/dist/index.d.cts b/dist/index.d.cts
new file mode 100644
index 0000000..06dbba4
--- /dev/null
+++ b/dist/index.d.cts
@@ -0,0 +1,146 @@
+type Matter = {
+ [key: string]: Matter | unknown;
+};
+interface Serializer {
+ serialize(parsedConfig: Matter): unknown;
+}
+interface FlatMatterFn {
+ name: string;
+ compute(...args: unknown[]): unknown;
+}
+declare class FlatMatter {
+ private content;
+ private parsedConfig;
+ private functions;
+ constructor(content: string, functions?: FlatMatterFn[]);
+ private parse;
+ /**
+ * Parses a given line of FlatMatter.
+ *
+ * @param {string} line
+ * @returns {void}
+ */
+ private parseLine;
+ private validateLineConformance;
+ private validateLineHasKeyVal;
+ private validateLineHasOnlyOneColonChar;
+ /**
+ * Detects if the value is a simple value. A simple value is any
+ * of the following: `"a string"`, boolean `true` or `false`, or
+ * anything numeric like `12345` or `123.45`.
+ *
+ * @param {string} value
+ * @returns {boolean}
+ */
+ private isSimpleValue;
+ /**
+ * Detects if the value is a function value. A function value is any
+ * of the following:
+ *
+ * - A function call with arguments: `(function-name *args)`
+ * - A function call by reference: `function-name`
+ *
+ * @param {string} value
+ * @returns {boolean}
+ */
+ private isFunctionValue;
+ /**
+ * Detects if the value is a piped value. A piped value is a mix of
+ * simple and function value parts, piped together with the forward
+ * slash `/` character. For example:
+ *
+ * ```yaml
+ * posts: (get-content "posts") / (limit 10) / only-published
+ * ```
+ *
+ * or:
+ *
+ * ```yaml
+ * posts: "posts" / get-content / (limit 10) / only-published
+ * ```
+ *
+ * The result of the previous pipe gets passed to the next as a first
+ * argument.
+ *
+ * @param {string} value
+ * @returns {boolean}
+ */
+ private isPipedValue;
+ /**
+ * Parses a value to a `ParsedValue` object, or `null`
+ * in case it could not for whatever reason.
+ *
+ * @param {string} value
+ * @returns {ParsedValue | null}
+ */
+ private parseValue;
+ /**
+ * Parses the value part of a line into a simple value, like for example
+ * a `string`, `number` or `boolean`.
+ *
+ * @param {string} value
+ * @returns {string | number | boolean}
+ */
+ private parseSimpleValue;
+ /**
+ * Parses the value part of a line into a Compute Action, which is
+ * later executed to run the function described in FlatMatter.
+ *
+ * @param {string} value
+ * @returns {ComputeAction}
+ */
+ private parseFunctionValue;
+ /**
+ * Parses the value part of a line into a ParsedValue, which is
+ * composed out of piped parts separated by the forward slash `/` character.
+ *
+ * The ParsedValue will include the default value, if any, and a list of compute
+ * actions which will later be executed.
+ *
+ * @param {string} value
+ * @returns {ParsedValue}
+ */
+ private parsePipedValue;
+ /**
+ * Takes the entire value part of a line and, assuming it is a function value,
+ * parses it into a list of arguments to be passed down to the function.
+ *
+ * @param {string} value
+ * @returns {unknown[]}
+ */
+ private parseFunctionValueArgs;
+ /**
+ * Takes an entire value of a line and composes it into a list
+ * of piped parts.
+ *
+ * @param {string} value
+ * @returns {string[]}
+ */
+ private composePipedValueParts;
+ /**
+ * Takes ParsedValue and, optionally an initial value, and runs
+ * compute actions over it to return the final computed value.
+ *
+ * @param {ParsedValue} parsedValue
+ * @returns {unknown}
+ */
+ private computeValue;
+ /**
+ * Takes a Serializer and uses it to transform internal data
+ * object to a desired output.
+ *
+ * @param {Serializer} serializer
+ * @returns {unknown}
+ */
+ serialize(serializer: Serializer): unknown;
+}
+
+declare class ToObject implements Serializer {
+ serialize(parsedConfig: Matter): Matter;
+}
+
+declare class ToJson implements Serializer {
+ serialize(parsedConfig: Matter): string;
+}
+
+export { FlatMatter, type FlatMatterFn, type Serializer, ToJson, ToObject };
diff --git a/dist/index.d.ts b/dist/index.d.ts
new file mode 100644
index 0000000..06dbba4
--- /dev/null
+++ b/dist/index.d.ts
@@ -0,0 +1,146 @@
+type Matter = {
+ [key: string]: Matter | unknown;
+};
+interface Serializer {
+ serialize(parsedConfig: Matter): unknown;
+}
+interface FlatMatterFn {
+ name: string;
+ compute(...args: unknown[]): unknown;
+}
+declare class FlatMatter {
+ private content;
+ private parsedConfig;
+ private functions;
+ constructor(content: string, functions?: FlatMatterFn[]);
+ private parse;
+ /**
+ * Parses a given line of FlatMatter.
+ *
+ * @param {string} line
+ * @returns {void}
+ */
+ private parseLine;
+ private validateLineConformance;
+ private validateLineHasKeyVal;
+ private validateLineHasOnlyOneColonChar;
+ /**
+ * Detects if the value is a simple value. A simple value is any
+ * of the following: `"a string"`, boolean `true` or `false`, or
+ * anything numeric like `12345` or `123.45`.
+ *
+ * @param {string} value
+ * @returns {boolean}
+ */
+ private isSimpleValue;
+ /**
+ * Detects if the value is a function value. A function value is any
+ * of the following:
+ *
+ * - A function call with arguments: `(function-name *args)`
+ * - A function call by reference: `function-name`
+ *
+ * @param {string} value
+ * @returns {boolean}
+ */
+ private isFunctionValue;
+ /**
+ * Detects if the value is a piped value. A piped value is a mix of
+ * simple and function value parts, piped together with the forward
+ * slash `/` character. For example:
+ *
+ * ```yaml
+ * posts: (get-content "posts") / (limit 10) / only-published
+ * ```
+ *
+ * or:
+ *
+ * ```yaml
+ * posts: "posts" / get-content / (limit 10) / only-published
+ * ```
+ *
+ * The result of the previous pipe gets passed to the next as a first
+ * argument.
+ *
+ * @param {string} value
+ * @returns {boolean}
+ */
+ private isPipedValue;
+ /**
+ * Parses a value to a `ParsedValue` object, or `null`
+ * in case it could not for whatever reason.
+ *
+ * @param {string} value
+ * @returns {ParsedValue | null}
+ */
+ private parseValue;
+ /**
+ * Parses the value part of a line into a simple value, like for example
+ * a `string`, `number` or `boolean`.
+ *
+ * @param {string} value
+ * @returns {string | number | boolean}
+ */
+ private parseSimpleValue;
+ /**
+ * Parses the value part of a line into a Compute Action, which is
+ * later executed to run the function described in FlatMatter.
+ *
+ * @param {string} value
+ * @returns {ComputeAction}
+ */
+ private parseFunctionValue;
+ /**
+ * Parses the value part of a line into a ParsedValue, which is
+ * composed out of piped parts separated by the forward slash `/` character.
+ *
+ * The ParsedValue will include the default value, if any, and a list of compute
+ * actions which will later be executed.
+ *
+ * @param {string} value
+ * @returns {ParsedValue}
+ */
+ private parsePipedValue;
+ /**
+ * Takes the entire value part of a line and, assuming it is a function value,
+ * parses it into a list of arguments to be passed down to the function.
+ *
+ * @param {string} value
+ * @returns {unknown[]}
+ */
+ private parseFunctionValueArgs;
+ /**
+ * Takes an entire value of a line and composes it into a list
+ * of piped parts.
+ *
+ * @param {string} value
+ * @returns {string[]}
+ */
+ private composePipedValueParts;
+ /**
+ * Takes ParsedValue and, optionally an initial value, and runs
+ * compute actions over it to return the final computed value.
+ *
+ * @param {ParsedValue} parsedValue
+ * @returns {unknown}
+ */
+ private computeValue;
+ /**
+ * Takes a Serializer and uses it to transform internal data
+ * object to a desired output.
+ *
+ * @param {Serializer} serializer
+ * @returns {unknown}
+ */
+ serialize(serializer: Serializer): unknown;
+}
+
+declare class ToObject implements Serializer {
+ serialize(parsedConfig: Matter): Matter;
+}
+
+declare class ToJson implements Serializer {
+ serialize(parsedConfig: Matter): string;
+}
+
+export { FlatMatter, type FlatMatterFn, type Serializer, ToJson, ToObject };
diff --git a/dist/index.js b/dist/index.js
new file mode 100644
index 0000000..e9ee7c6
--- /dev/null
+++ b/dist/index.js
@@ -0,0 +1,307 @@
+// src/utils.ts
+function trimChar(input, char) {
+ if (typeof char === "string") {
+ char = [char];
+ }
+ for (const c of char) {
+ if (input.charAt(0) === c) {
+ input = input.substring(1);
+ }
+ if (input.charAt(input.length - 1) === c) {
+ input = input.substring(0, input.length - 1);
+ }
+ }
+ return input;
+}
+
+// src/flatmatter.ts
+var FlatMatter = class {
+ content;
+ parsedConfig = {};
+ functions;
+ constructor(content, functions = []) {
+ this.content = content;
+ this.functions = functions;
+ this.parse();
+ }
+ parse() {
+ for (const line of this.content.split(/\r?\n/)) {
+ this.parseLine(line);
+ }
+ }
+ /**
+ * Parses a given line of FlatMatter.
+ *
+ * @param {string} line
+ * @returns {void}
+ */
+ parseLine(line) {
+ this.validateLineConformance(line);
+ const keys = line.split(":")[0].trim().split(".");
+ const value = line.split(":").slice(1).join(":").trim();
+ const parsedValue = this.parseValue(value);
+ if (!parsedValue) return;
+ const config = keys.reduceRight((acc, key) => {
+ return { [key]: acc };
+ }, this.computeValue(parsedValue));
+ this.parsedConfig = { ...this.parsedConfig, ...config };
+ }
+ validateLineConformance(line) {
+ }
+ validateLineHasKeyVal(line) {
+ return {
+ passed: true
+ };
+ }
+ validateLineHasOnlyOneColonChar(line) {
+ return {
+ passed: true
+ };
+ }
+ /**
+ * Detects if the value is a simple value. A simple value is any
+ * of the following: `"a string"`, boolean `true` or `false`, or
+ * anything numeric like `12345` or `123.45`.
+ *
+ * @param {string} value
+ * @returns {boolean}
+ */
+ isSimpleValue(value) {
+ const isString = value.startsWith('"') && value.endsWith('"');
+ const isBoolean = value === "true" || value === "false";
+ const isNumber = !isNaN(parseFloat(value));
+ return isString || isBoolean || isNumber;
+ }
+ /**
+ * Detects if the value is a function value. A function value is any
+ * of the following:
+ *
+ * - A function call with arguments: `(function-name *args)`
+ * - A function call by reference: `function-name`
+ *
+ * @param {string} value
+ * @returns {boolean}
+ */
+ isFunctionValue(value) {
+ const isFnCall = value.startsWith("(") && value.endsWith(")");
+ const isFnReference = !!value.match(/^([a-zA-Z0-9_-]+)$/);
+ return isFnCall || isFnReference;
+ }
+ /**
+ * Detects if the value is a piped value. A piped value is a mix of
+ * simple and function value parts, piped together with the forward
+ * slash `/` character. For example:
+ *
+ * ```yaml
+ * posts: (get-content "posts") / (limit 10) / only-published
+ * ```
+ *
+ * or:
+ *
+ * ```yaml
+ * posts: "posts" / get-content / (limit 10) / only-published
+ * ```
+ *
+ * The result of the previous pipe gets passed to the next as a first
+ * argument.
+ *
+ * @param {string} value
+ * @returns {boolean}
+ */
+ isPipedValue(value) {
+ for (const part of this.composePipedValueParts(value)) {
+ if (!this.isSimpleValue(part) && !this.isFunctionValue(part)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ /**
+ * Parses a value to a `ParsedValue` object, or `null`
+ * in case it could not for whatever reason.
+ *
+ * @param {string} value
+ * @returns {ParsedValue | null}
+ */
+ parseValue(value) {
+ if (this.isSimpleValue(value)) {
+ return {
+ value: this.parseSimpleValue(value),
+ computeActions: []
+ };
+ }
+ if (this.isFunctionValue(value)) {
+ return {
+ value: null,
+ computeActions: [this.parseFunctionValue(value)]
+ };
+ }
+ if (this.isPipedValue(value)) {
+ return this.parsePipedValue(value);
+ }
+ return null;
+ }
+ /**
+ * Parses the value part of a line into a simple value, like for example
+ * a `string`, `number` or `boolean`.
+ *
+ * @param {string} value
+ * @returns {string | number | boolean}
+ */
+ parseSimpleValue(value) {
+ if (value === "true" || value === "false") {
+ return value === "true";
+ }
+ if (!Number.isNaN(parseFloat(value))) {
+ return parseFloat(value);
+ }
+ if (!Number.isNaN(parseInt(value))) {
+ return parseInt(value);
+ }
+ return trimChar(value, '"');
+ }
+ /**
+ * Parses the value part of a line into a Compute Action, which is
+ * later executed to run the function described in FlatMatter.
+ *
+ * @param {string} value
+ * @returns {ComputeAction}
+ */
+ parseFunctionValue(value) {
+ const isFn = value.startsWith("(") && value.endsWith(")");
+ if (!isFn) {
+ return {
+ identifier: value,
+ args: []
+ };
+ }
+ const fnName = trimChar(value, ["(", ")"]).split(" ")[0].trim();
+ const fnArgs = this.parseFunctionValueArgs(value);
+ return {
+ identifier: fnName,
+ args: fnArgs
+ };
+ }
+ /**
+ * Parses the value part of a line into a ParsedValue, which is
+ * composed out of piped parts separated by the forward slash `/` character.
+ *
+ * The ParsedValue will include the default value, if any, and a list of compute
+ * actions which will later be executed.
+ *
+ * @param {string} value
+ * @returns {ParsedValue}
+ */
+ parsePipedValue(value) {
+ const parts = this.composePipedValueParts(value);
+ if (this.isSimpleValue(parts[0])) {
+ return {
+ value: this.parseSimpleValue(parts[0]),
+ computeActions: parts.slice(1).map((p) => this.parseFunctionValue(p))
+ };
+ }
+ return {
+ value: null,
+ computeActions: parts.map((p) => this.parseFunctionValue(p))
+ };
+ }
+ /**
+ * Takes the entire value part of a line and, assuming it is a function value,
+ * parses it into a list of arguments to be passed down to the function.
+ *
+ * @param {string} value
+ * @returns {unknown[]}
+ */
+ parseFunctionValueArgs(value) {
+ const parts = value.substring(1, value.length - 1).split(" ").slice(1);
+ if (!parts.length) {
+ return [];
+ }
+ const normalizedParts = [parts[0]];
+ for (let i = 1; i < parts.length; i++) {
+ const untilCurrent = normalizedParts.join(" ");
+ const quoteCount = untilCurrent.split('"').length - 1;
+ if (quoteCount % 2 === 0) {
+ normalizedParts.push(parts[i]);
+ continue;
+ }
+ const lastIndex = normalizedParts.length - 1;
+ const lastPart = normalizedParts[lastIndex];
+ normalizedParts[lastIndex] = `${lastPart} ${parts[i]}`;
+ }
+ return normalizedParts.map((part) => this.parseSimpleValue(part));
+ }
+ /**
+ * Takes an entire value of a line and composes it into a list
+ * of piped parts.
+ *
+ * @param {string} value
+ * @returns {string[]}
+ */
+ composePipedValueParts(value) {
+ const parts = value.split(" / ");
+ const normalizedParts = [parts[0]];
+ for (let i = 1; i < parts.length; i++) {
+ const untilCurrent = normalizedParts.join(" / ");
+ const quoteCount = untilCurrent.split('"').length - 1;
+ if (quoteCount % 2 === 0) {
+ normalizedParts.push(parts[i]);
+ continue;
+ }
+ const lastIndex = normalizedParts.length - 1;
+ const lastPart = normalizedParts[lastIndex];
+ normalizedParts[lastIndex] = `${lastPart} / ${parts[i]}`;
+ }
+ return normalizedParts;
+ }
+ /**
+ * Takes ParsedValue and, optionally an initial value, and runs
+ * compute actions over it to return the final computed value.
+ *
+ * @param {ParsedValue} parsedValue
+ * @returns {unknown}
+ */
+ computeValue(parsedValue) {
+ let value = parsedValue.value;
+ for (const ca of parsedValue.computeActions) {
+ const fnInstance = this.functions.find((f) => f.name === ca.identifier);
+ if (!fnInstance) {
+ continue;
+ }
+ if (value !== null) {
+ ca.args = [value, ...ca.args];
+ }
+ value = fnInstance.compute(...ca.args);
+ }
+ return value;
+ }
+ /**
+ * Takes a Serializer and uses it to transform internal data
+ * object to a desired output.
+ *
+ * @param {Serializer} serializer
+ * @returns {unknown}
+ */
+ serialize(serializer) {
+ return serializer.serialize(this.parsedConfig);
+ }
+};
+
+// src/serializers/to_object.ts
+var ToObject = class {
+ serialize(parsedConfig) {
+ return parsedConfig;
+ }
+};
+
+// src/serializers/to_json.ts
+var ToJson = class {
+ serialize(parsedConfig) {
+ return JSON.stringify(parsedConfig);
+ }
+};
+export {
+ FlatMatter,
+ ToJson,
+ ToObject
+};