@meldscience/meld
Version:
pipeable one-shot prompt scripting toolkit
148 lines • 5.66 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseMeldDirective = parseMeldDirective;
exports.buildMeldDirectiveNode = buildMeldDirectiveNode;
/**
* Splits a line of text into an array of either:
* - raw text nodes
* - meldDirective nodes
*/
function parseMeldDirective(value, file) {
const result = [];
let remaining = value;
// Match any @cmd[...] or @import[...] pattern, even if malformed
const directiveRegex = /(@(?:cmd|import)\[(?:[^\[\]]|\[(?:[^\[\]]|\[[^\[\]]*\])*\])*\])/g;
let match;
let lastIndex = 0;
while ((match = directiveRegex.exec(remaining)) !== null) {
const start = match.index;
const end = start + match[0].length;
// Add any preceding text as a Text node
if (start > lastIndex) {
const textChunk = remaining.slice(lastIndex, start);
result.push({ type: 'text', value: textChunk });
}
// Build the directive node
const rawDirective = match[0];
try {
// Check for malformed directives
if (!rawDirective.endsWith(']')) {
throw new Error(`Invalid ${rawDirective.startsWith('@cmd') ? 'command' : 'import'} format`);
}
const directiveNode = buildMeldDirectiveNode(rawDirective);
result.push(directiveNode);
}
catch (err) {
// For malformed directives, preserve the original text and add the error
result.push({ type: 'text', value: rawDirective });
result.push({ type: 'text', value: ` Error: ${err.message}` });
}
lastIndex = end;
}
// Add any trailing text
if (lastIndex < remaining.length) {
const textChunk = remaining.slice(lastIndex);
result.push({ type: 'text', value: textChunk });
}
return result;
}
/**
* Helper that parses the `@cmd[...]` or `@import[...]` line and returns a typed node.
*/
function buildMeldDirectiveNode(raw) {
// Check for basic format
if (!raw.startsWith('@cmd[') && !raw.startsWith('@import[')) {
throw new Error('Invalid directive format');
}
// Check for proper closing bracket
if (!raw.includes(']')) {
throw new Error('Invalid directive format - missing closing bracket');
}
if (raw.startsWith('@cmd')) {
if (!raw.includes('[') || !raw.includes(']')) {
throw new Error('Invalid command format');
}
const command = raw.slice('@cmd['.length, raw.indexOf(']')).trim();
if (!command) {
throw new Error('Invalid command format');
}
return {
type: 'meldDirective',
meldType: 'cmd',
raw,
data: {
command
}
};
}
else {
// It's an @import directive
if (!raw.includes('[') || !raw.includes(']')) {
throw new Error('Invalid import format');
}
const importMatch = raw.match(/^@import\[([^\[\]]*(?:\[[^\[\]]*\][^\[\]]*)*)\](?:\s+as\s+(#{1,6})\s*(?:"([^"]*)")?)?$/);
console.log('Raw input:', raw);
console.log('Import match:', importMatch);
if (!importMatch || !importMatch[1].trim()) {
throw new Error('Invalid import format');
}
const [, inside, headingLevelOverride, headingTextOverride] = importMatch;
console.log('Inside:', inside);
console.log('Heading level override:', headingLevelOverride);
console.log('Heading text override:', headingTextOverride);
// Parse import path and any modifiers
let importPath = inside;
let heading;
let importSymbolList;
let importWholeFile = false;
// Handle whole file import if no # is present
if (!inside.includes('#')) {
importWholeFile = true;
}
// Handle symbol imports with braces/brackets
else {
const [pathPart, rest] = inside.split('#').map(s => s.trim());
if (!pathPart || !rest) {
throw new Error('Invalid import format');
}
importPath = pathPart;
// Handle array of symbols: [symbol1, symbol2]
if (rest.startsWith('[') && rest.endsWith(']')) {
const symbolsStr = rest.slice(1, -1);
importSymbolList = symbolsStr.split(',').map(s => s.trim());
}
// Handle single symbol or brace pattern: {type} or {interface}
else if (rest.startsWith('{') && rest.endsWith('}')) {
const symbol = rest.slice(1, -1).trim();
importSymbolList = [symbol];
}
// Handle plain specifier based on file type
else {
if (importPath.endsWith('.ts') || importPath.endsWith('.js')) {
// If the rest starts with [ but doesn't end with ], it's malformed
if (rest.startsWith('[')) {
throw new Error('Malformed symbol list - missing closing bracket');
}
importSymbolList = [rest];
}
else {
heading = rest;
}
}
}
return {
type: 'meldDirective',
meldType: 'import',
raw,
data: {
importPath,
heading,
headingLevelOverride,
headingTextOverride,
importSymbolList,
importWholeFile
}
};
}
}
//# sourceMappingURL=parseMeldDirective.js.map