import { d as parseJsArg, g as __toESM, h as __exportAll, i as htmlSafe, l as isSubsetOf, p as unallowedExpression, r as escape, t as require_js_stringify } from "../../js-stringify-CbllxJUy.js";
import string from "@poppinss/utils/string";
import { expressions } from "edge-parser";
import { EdgeError } from "edge-error";
import lodash from "@poppinss/utils/lodash";
import inspect from "@poppinss/inspect";
//#region src/migrate/tags/set.ts
/**
* The set tag is used to set runtime values within the template. The value
* is set inside the current scope of the template.
*
* ```edge
* @set('user.username', 'virk')
* <p> {{ user.username }} </p>
* ```
*
* Set it inside the each loop.
*
* ```edge
* @each(user in users)
*   @set('age', user.age + 1)
*   {{ age }}
* @endeach
* ```
*/
const setTag = {
	block: false,
	seekable: true,
	tagName: "set",
	noNewLine: true,
	/**
	* Compiles else block node to Javascript else statement
	*/
	compile(parser, buffer, token) {
		const parsed = parseJsArg(parser, token);
		/**
		* The set tag only accepts a sequence expression.
		*/
		isSubsetOf(parsed, [expressions.SequenceExpression], () => {
			throw unallowedExpression(`"${token.properties.jsArg}" is not a valid key-value pair for the @slot tag`, token.filename, parser.utils.getExpressionLoc(parsed));
		});
		/**
		* Disallow less than 2 and more than 3 values for the sequence
		* expression
		*/
		if (parsed.expressions.length < 2 || parsed.expressions.length > 3) throw new EdgeError("@set tag accepts a minimum of 2 or maximum or 3 arguments", "E_INVALID_ARGUMENTS_COUNT", {
			line: parsed.loc.start.line,
			col: parsed.loc.start.column,
			filename: token.filename
		});
		/**
		* Extract key-value and the collection (if any)
		*/
		let collection;
		let key;
		let value;
		if (parsed.expressions.length === 3) {
			collection = parsed.expressions[0];
			key = parsed.expressions[1];
			value = parsed.expressions[2];
		} else {
			key = parsed.expressions[0];
			value = parsed.expressions[1];
		}
		/**
		* Mutate the collection when defined
		*/
		if (collection) {
			buffer.writeExpression(`template.setValue(${parser.utils.stringify(collection)}, '${key.value}', ${parser.utils.stringify(value)})`, token.filename, token.loc.start.line);
			return;
		}
		/**
		* Write statement to mutate the key. If the variable has already been
		* defined, then just update it's value.
		*
		* We do not allow re-declaring a variable as of now
		*/
		const expression = parser.stack.has(key.value) ? `${key.value} = ${parser.utils.stringify(value)}` : `let ${key.value} = ${parser.utils.stringify(value)}`;
		buffer.writeExpression(expression, token.filename, token.loc.start.line);
		parser.stack.defineVariable(key.value);
	},
	/**
	* Add methods to the template for running the loop
	*/
	boot(template) {
		template.macro("setValue", lodash.set);
	}
};
//#endregion
//#region src/migrate/tags/super.ts
/**
* Super tag is used inside sections to inherit the parent section
* content.
*
* The implementation of super tag is handled by the compiler itself, but we need
* the tag to exists, so that the lexer can parse it as a tag.
*/
const superTag = {
	block: false,
	seekable: false,
	tagName: "super",
	compile(_, __, token) {
		throw new EdgeError("@super tag must appear as top level tag inside the @section tag", "E_ORPHAN_SUPER_TAG", {
			line: token.loc.start.line,
			col: token.loc.start.col,
			filename: token.filename
		});
	}
};
//#endregion
//#region src/migrate/tags/layout.ts
/**
* Layout tag is used to define parent layout for a given template. The layout
* must appear in the first line of the template itself.
*/
const layoutTag = {
	block: false,
	seekable: true,
	tagName: "layout",
	noNewLine: true,
	compile() {}
};
//#endregion
//#region src/migrate/tags/section.ts
/**
* Section tag is used to define the sections on a given template. Sections cannot be
* nested and must appear as top level children inside a component.
*/
const sectionTag = {
	block: true,
	seekable: true,
	tagName: "section",
	compile(parser, buffer, token) {
		token.children.forEach((child) => parser.processToken(child, buffer));
	}
};
//#endregion
//#region src/migrate/tags/main.ts
var main_exports = /* @__PURE__ */ __exportAll({
	layout: () => layoutTag,
	section: () => sectionTag,
	set: () => setTag,
	super: () => superTag
});
//#endregion
//#region src/migrate/globals.ts
var import_js_stringify = /* @__PURE__ */ __toESM(require_js_stringify(), 1);
const { string: prettyPrintHtml } = inspect;
const GLOBALS = {
	/**
	* Converts new lines to break
	*/
	nl2br: (value) => {
		if (!value) return;
		return String(value).replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, "$1<br>");
	},
	/**
	* Inspect state
	*/
	inspect: (value) => {
		return htmlSafe(prettyPrintHtml.html(value));
	},
	/**
	* Truncate a sentence
	*/
	truncate: (value, length = 20, options) => {
		options = options || {};
		return string.truncate(value, length, {
			completeWords: options.completeWords !== void 0 ? options.completeWords : !options.strict,
			suffix: options.suffix
		});
	},
	/**
	* Raise an exception
	*/
	raise: (message, options) => {
		if (!options) throw new Error(message);
		else throw new EdgeError(message, "E_RUNTIME_EXCEPTION", options);
	},
	/**
	* Generate an excerpt
	*/
	excerpt: (value, length = 20, options) => {
		options = options || {};
		return string.excerpt(value, length, {
			completeWords: options.completeWords !== void 0 ? options.completeWords : !options.strict,
			suffix: options.suffix
		});
	},
	/**
	* Using `"e"` because, `escape` is a global function in the
	* Node.js global namespace and edge parser gives priority
	* to it
	*/
	e: escape,
	/**
	* Convert javascript data structures to a string. The method is a little
	* better over JSON.stringify in handling certain data structures. For
	* example: In JSON.stringify, the date is converted to an ISO string
	* whereas this method converts it to an actual instance of date
	*/
	stringify: import_js_stringify.default,
	safe: htmlSafe,
	camelCase: string.camelCase,
	snakeCase: string.snakeCase,
	dashCase: string.dashCase,
	pascalCase: string.pascalCase,
	capitalCase: string.capitalCase,
	sentenceCase: string.sentenceCase,
	dotCase: string.dotCase,
	noCase: string.noCase,
	titleCase: string.titleCase,
	pluralize: string.pluralize,
	sentence: string.sentence,
	prettyMs: string.milliseconds.format,
	toMs: string.milliseconds.parse,
	prettyBytes: string.bytes.format,
	toBytes: string.bytes.parse,
	ordinal: string.ordinal
};
//#endregion
//#region src/migrate/plugin.ts
const migrate = (edge) => {
	edge.compat = true;
	edge.compiler.compat = true;
	edge.asyncCompiler.compat = true;
	Object.keys(GLOBALS).forEach((name) => {
		edge.global(name, GLOBALS[name]);
	});
	Object.keys(main_exports).forEach((name) => {
		edge.registerTag(main_exports[name]);
	});
};
//#endregion
export { migrate };
