Phase 1 MVP - Complete implementation

- Login with JWT and refresh token rotation
- Dashboard with projects cards
- ProjectView with TreeView navigation
- DocumentView with markdown editor and auto-save
- Tag management (create, assign, remove)
- Dark mode CSS variables
- Security fixes applied (logout to backend, createDocument endpoint)
This commit is contained in:
Motoko
2026-03-30 15:17:29 +00:00
commit c9cb07dbfc
1341 changed files with 1084068 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
import type { Mapping } from '@volar/language-core';
import type { Segment } from 'muggle-string';
export declare function buildMappings<T>(chunks: Segment<T>[]): Mapping<T>[];

View File

@@ -0,0 +1,23 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildMappings = buildMappings;
function buildMappings(chunks) {
let length = 0;
const mappings = [];
for (const segment of chunks) {
if (typeof segment === 'string') {
length += segment.length;
}
else {
mappings.push({
sourceOffsets: [segment[2]],
generatedOffsets: [length],
lengths: [segment[0].length],
data: segment[3],
});
length += segment[0].length;
}
}
return mappings;
}
//# sourceMappingURL=buildMappings.js.map

View File

@@ -0,0 +1,4 @@
export declare function parseCssClassNames(css: string): Generator<{
offset: number;
text: string;
}, void, unknown>;

View File

@@ -0,0 +1,17 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseCssClassNames = parseCssClassNames;
const parseCssVars_1 = require("./parseCssVars");
const cssClassNameReg = /(?=(\.[a-z_][-\w]*)[\s.,+~>:#)[{])/gi;
const fragmentReg = /(?<={)[^{]*(?=(?<!\\);)/g;
function* parseCssClassNames(css) {
css = (0, parseCssVars_1.fillBlank)(css, parseCssVars_1.commentReg, fragmentReg);
const matches = css.matchAll(cssClassNameReg);
for (const match of matches) {
const matchText = match[1];
if (matchText) {
yield { offset: match.index, text: matchText };
}
}
}
//# sourceMappingURL=parseCssClassNames.js.map

View File

@@ -0,0 +1,6 @@
export declare const commentReg: RegExp;
export declare function parseCssVars(css: string): Generator<{
offset: number;
text: string;
}, void, unknown>;
export declare function fillBlank(css: string, ...regs: RegExp[]): string;

View File

@@ -0,0 +1,26 @@
"use strict";
// https://github.com/vuejs/core/blob/main/packages/compiler-sfc/src/cssVars.ts#L47-L61
Object.defineProperty(exports, "__esModule", { value: true });
exports.commentReg = void 0;
exports.parseCssVars = parseCssVars;
exports.fillBlank = fillBlank;
const vBindCssVarReg = /\bv-bind\(\s*(?:'([^']+)'|"([^"]+)"|([a-z_]\w*))\s*\)/gi;
exports.commentReg = /(?<=\/\*)[\s\S]*?(?=\*\/)|(?<=\/\/)[\s\S]*?(?=\n)/g;
function* parseCssVars(css) {
css = fillBlank(css, exports.commentReg);
const matchs = css.matchAll(vBindCssVarReg);
for (const match of matchs) {
const matchText = match.slice(1).find(t => t);
if (matchText) {
const offset = match.index + css.slice(match.index).indexOf(matchText);
yield { offset, text: matchText };
}
}
}
function fillBlank(css, ...regs) {
for (const reg of regs) {
css = css.replace(reg, match => ' '.repeat(match.length));
}
return css;
}
//# sourceMappingURL=parseCssVars.js.map

View File

@@ -0,0 +1,7 @@
import type { SFCParseResult } from '@vue/compiler-sfc';
declare module '@vue/compiler-sfc' {
interface SFCDescriptor {
comments: string[];
}
}
export declare function parse(source: string): SFCParseResult;

153
node_modules/@vue/language-core/lib/utils/parseSfc.js generated vendored Normal file
View File

@@ -0,0 +1,153 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parse = parse;
const CompilerDOM = require("@vue/compiler-dom");
function parse(source) {
const errors = [];
const ast = CompilerDOM.parse(source, {
// there are no components at SFC parsing level
isNativeTag: () => true,
// preserve all whitespaces
isPreTag: () => true,
parseMode: 'sfc',
onError: e => {
errors.push(e);
},
comments: true,
});
const descriptor = {
filename: 'anonymous.vue',
source,
comments: [],
template: null,
script: null,
scriptSetup: null,
styles: [],
customBlocks: [],
cssVars: [],
slotted: false,
shouldForceReload: () => false,
};
ast.children.forEach(node => {
if (node.type === CompilerDOM.NodeTypes.COMMENT) {
descriptor.comments.push(node.content);
return;
}
else if (node.type !== CompilerDOM.NodeTypes.ELEMENT) {
return;
}
switch (node.tag) {
case 'template':
descriptor.template = createBlock(node, source);
break;
case 'script':
const scriptBlock = createBlock(node, source);
const isSetup = !!scriptBlock.setup;
if (isSetup && !descriptor.scriptSetup) {
descriptor.scriptSetup = scriptBlock;
break;
}
if (!isSetup && !descriptor.script) {
descriptor.script = scriptBlock;
break;
}
break;
case 'style':
const styleBlock = createBlock(node, source);
descriptor.styles.push(styleBlock);
break;
default:
descriptor.customBlocks.push(createBlock(node, source));
break;
}
});
return {
descriptor,
errors,
};
}
function createBlock(node, source) {
const type = node.tag;
let { start, end } = node.loc;
let content = '';
if (node.children.length) {
start = node.children[0].loc.start;
end = node.children[node.children.length - 1].loc.end;
content = source.slice(start.offset, end.offset);
}
else {
const offset = node.loc.source.indexOf(`</`);
if (offset > -1) {
start = {
line: start.line,
column: start.column + offset,
offset: start.offset + offset
};
}
end = Object.assign({}, start);
}
const loc = {
source: content,
start,
end
};
const attrs = {};
const block = {
type,
content,
loc,
attrs
};
node.props.forEach(p => {
if (p.type === CompilerDOM.NodeTypes.ATTRIBUTE) {
attrs[p.name] = p.value ? p.value.content || true : true;
if (p.name === 'lang') {
block.lang = p.value?.content;
}
else if (p.name === 'src') {
block.__src = parseAttr(p, node);
}
else if (isScriptBlock(block)) {
if (p.name === 'setup' || p.name === 'vapor') {
block.setup = attrs[p.name];
}
else if (p.name === 'generic') {
block.__generic = parseAttr(p, node);
}
}
else if (isStyleBlock(block)) {
if (p.name === 'scoped') {
block.scoped = true;
}
else if (p.name === 'module') {
block.__module = parseAttr(p, node);
}
}
}
});
return block;
}
function isScriptBlock(block) {
return block.type === 'script';
}
function isStyleBlock(block) {
return block.type === 'style';
}
function parseAttr(p, node) {
if (!p.value) {
return true;
}
const text = p.value.content;
const source = p.value.loc.source;
let offset = p.value.loc.start.offset - node.loc.start.offset;
const quotes = source.startsWith('"') || source.startsWith("'");
if (quotes) {
offset++;
}
return {
text,
offset,
quotes,
};
}
//# sourceMappingURL=parseSfc.js.map

View File

@@ -0,0 +1,3 @@
export declare function getSlotsPropertyName(vueVersion: number): "$scopedSlots" | "$slots";
export { hyphenate as hyphenateTag } from '@vue/shared';
export declare function hyphenateAttr(str: string): string;

20
node_modules/@vue/language-core/lib/utils/shared.js generated vendored Normal file
View File

@@ -0,0 +1,20 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.hyphenateTag = void 0;
exports.getSlotsPropertyName = getSlotsPropertyName;
exports.hyphenateAttr = hyphenateAttr;
const shared_1 = require("@vue/shared");
function getSlotsPropertyName(vueVersion) {
return vueVersion < 3 ? '$scopedSlots' : '$slots';
}
var shared_2 = require("@vue/shared");
Object.defineProperty(exports, "hyphenateTag", { enumerable: true, get: function () { return shared_2.hyphenate; } });
function hyphenateAttr(str) {
let hyphencase = (0, shared_1.hyphenate)(str);
// fix https://github.com/vuejs/core/issues/8811
if (str.length && str[0] !== str[0].toLowerCase()) {
hyphencase = '-' + hyphencase;
}
return hyphencase;
}
//# sourceMappingURL=shared.js.map

View File

@@ -0,0 +1,2 @@
export declare function computedArray<I, O>(arr: () => I[], getGetter: (item: () => I, index: number) => () => O): readonly Readonly<O>[];
export declare function computedSet<T>(source: () => Set<T>): () => Set<T>;

54
node_modules/@vue/language-core/lib/utils/signals.js generated vendored Normal file
View File

@@ -0,0 +1,54 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.computedArray = computedArray;
exports.computedSet = computedSet;
const alien_signals_1 = require("alien-signals");
function computedArray(arr, getGetter) {
const length = (0, alien_signals_1.computed)(() => arr().length);
const keys = (0, alien_signals_1.computed)(() => {
const keys = [];
for (let i = 0; i < length(); i++) {
keys.push(String(i));
}
return keys;
});
const items = (0, alien_signals_1.computed)(array => {
array ??= [];
while (array.length < length()) {
const index = array.length;
const item = (0, alien_signals_1.computed)(() => arr()[index]);
array.push((0, alien_signals_1.computed)(getGetter(item, index)));
}
if (array.length > length()) {
array.length = length();
}
return array;
});
return new Proxy({}, {
get(_, p, receiver) {
if (p === 'length') {
return length();
}
if (typeof p === 'string' && !isNaN(Number(p))) {
return items()[Number(p)]?.();
}
return Reflect.get(items(), p, receiver);
},
has(_, p) {
return Reflect.has(items(), p);
},
ownKeys() {
return keys();
},
});
}
function computedSet(source) {
return (0, alien_signals_1.computed)(oldValue => {
const newValue = source();
if (oldValue?.size === newValue.size && [...oldValue].every(c => newValue.has(c))) {
return oldValue;
}
return newValue;
});
}
//# sourceMappingURL=signals.js.map

26
node_modules/@vue/language-core/lib/utils/ts.d.ts generated vendored Normal file
View File

@@ -0,0 +1,26 @@
import type * as ts from 'typescript';
import type { RawVueCompilerOptions, VueCompilerOptions, VueLanguagePlugin } from '../types';
export type ParsedCommandLine = ts.ParsedCommandLine & {
vueOptions: VueCompilerOptions;
};
export declare function createParsedCommandLineByJson(ts: typeof import('typescript'), parseConfigHost: ts.ParseConfigHost & {
writeFile?(path: string, data: string): void;
}, rootDir: string, json: any, configFileName?: string, skipGlobalTypesSetup?: boolean): ParsedCommandLine;
export declare function createParsedCommandLine(ts: typeof import('typescript'), parseConfigHost: ts.ParseConfigHost, tsConfigPath: string, skipGlobalTypesSetup?: boolean): ParsedCommandLine;
export declare class CompilerOptionsResolver {
options: Omit<RawVueCompilerOptions, 'target' | 'plugin'>;
fallbackTarget: number | undefined;
target: number | undefined;
plugins: VueLanguagePlugin[];
addConfig(options: RawVueCompilerOptions, rootDir: string): void;
build(defaults?: VueCompilerOptions): VueCompilerOptions;
}
export declare function getDefaultCompilerOptions(target?: number, lib?: string, strictTemplates?: boolean): VueCompilerOptions;
/**
* @deprecated use `getDefaultCompilerOptions` instead
*/
export declare function resolveVueCompilerOptions(options: Partial<VueCompilerOptions>): VueCompilerOptions;
export declare function setupGlobalTypes(rootDir: string, vueOptions: VueCompilerOptions, host: {
fileExists(path: string): boolean;
writeFile?(path: string, data: string): void;
}): VueCompilerOptions['__setupedGlobalTypes'];

303
node_modules/@vue/language-core/lib/utils/ts.js generated vendored Normal file
View File

@@ -0,0 +1,303 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CompilerOptionsResolver = void 0;
exports.createParsedCommandLineByJson = createParsedCommandLineByJson;
exports.createParsedCommandLine = createParsedCommandLine;
exports.getDefaultCompilerOptions = getDefaultCompilerOptions;
exports.resolveVueCompilerOptions = resolveVueCompilerOptions;
exports.setupGlobalTypes = setupGlobalTypes;
const shared_1 = require("@vue/shared");
const path_browserify_1 = require("path-browserify");
const globalTypes_1 = require("../codegen/globalTypes");
const languagePlugin_1 = require("../languagePlugin");
const shared_2 = require("./shared");
function createParsedCommandLineByJson(ts, parseConfigHost, rootDir, json, configFileName = rootDir + '/jsconfig.json', skipGlobalTypesSetup = false) {
const proxyHost = proxyParseConfigHostForExtendConfigPaths(parseConfigHost);
ts.parseJsonConfigFileContent(json, proxyHost.host, rootDir, {}, configFileName);
const resolver = new CompilerOptionsResolver();
for (const extendPath of proxyHost.extendConfigPaths.reverse()) {
try {
const configFile = ts.readJsonConfigFile(extendPath, proxyHost.host.readFile);
const obj = ts.convertToObject(configFile, []);
const rawOptions = obj?.vueCompilerOptions ?? {};
resolver.addConfig(rawOptions, path_browserify_1.posix.dirname(configFile.fileName));
}
catch (err) { }
}
const resolvedVueOptions = resolver.build();
if (skipGlobalTypesSetup) {
resolvedVueOptions.__setupedGlobalTypes = true;
}
else {
resolvedVueOptions.__setupedGlobalTypes = setupGlobalTypes(rootDir, resolvedVueOptions, parseConfigHost);
}
const parsed = ts.parseJsonConfigFileContent(json, proxyHost.host, rootDir, {}, configFileName, undefined, (0, languagePlugin_1.getAllExtensions)(resolvedVueOptions)
.map(extension => ({
extension: extension.slice(1),
isMixedContent: true,
scriptKind: ts.ScriptKind.Deferred,
})));
// fix https://github.com/vuejs/language-tools/issues/1786
// https://github.com/microsoft/TypeScript/issues/30457
// patching ts server broke with outDir + rootDir + composite/incremental
parsed.options.outDir = undefined;
return {
...parsed,
vueOptions: resolvedVueOptions,
};
}
function createParsedCommandLine(ts, parseConfigHost, tsConfigPath, skipGlobalTypesSetup = false) {
try {
const proxyHost = proxyParseConfigHostForExtendConfigPaths(parseConfigHost);
const config = ts.readJsonConfigFile(tsConfigPath, proxyHost.host.readFile);
ts.parseJsonSourceFileConfigFileContent(config, proxyHost.host, path_browserify_1.posix.dirname(tsConfigPath), {}, tsConfigPath);
const resolver = new CompilerOptionsResolver();
for (const extendPath of proxyHost.extendConfigPaths.reverse()) {
try {
const configFile = ts.readJsonConfigFile(extendPath, proxyHost.host.readFile);
const obj = ts.convertToObject(configFile, []);
const rawOptions = obj?.vueCompilerOptions ?? {};
resolver.addConfig(rawOptions, path_browserify_1.posix.dirname(configFile.fileName));
}
catch (err) { }
}
const resolvedVueOptions = resolver.build();
if (skipGlobalTypesSetup) {
resolvedVueOptions.__setupedGlobalTypes = true;
}
else {
resolvedVueOptions.__setupedGlobalTypes = setupGlobalTypes(path_browserify_1.posix.dirname(tsConfigPath), resolvedVueOptions, parseConfigHost);
}
const parsed = ts.parseJsonSourceFileConfigFileContent(config, proxyHost.host, path_browserify_1.posix.dirname(tsConfigPath), {}, tsConfigPath, undefined, (0, languagePlugin_1.getAllExtensions)(resolvedVueOptions)
.map(extension => ({
extension: extension.slice(1),
isMixedContent: true,
scriptKind: ts.ScriptKind.Deferred,
})));
// fix https://github.com/vuejs/language-tools/issues/1786
// https://github.com/microsoft/TypeScript/issues/30457
// patching ts server broke with outDir + rootDir + composite/incremental
parsed.options.outDir = undefined;
return {
...parsed,
vueOptions: resolvedVueOptions,
};
}
catch (err) {
// console.warn('Failed to resolve tsconfig path:', tsConfigPath, err);
return {
fileNames: [],
options: {},
vueOptions: getDefaultCompilerOptions(),
errors: [],
};
}
}
function proxyParseConfigHostForExtendConfigPaths(parseConfigHost) {
const extendConfigPaths = [];
const host = new Proxy(parseConfigHost, {
get(target, key) {
if (key === 'readFile') {
return (fileName) => {
if (!fileName.endsWith('/package.json') && !extendConfigPaths.includes(fileName)) {
extendConfigPaths.push(fileName);
}
return target.readFile(fileName);
};
}
return target[key];
}
});
return {
host,
extendConfigPaths,
};
}
class CompilerOptionsResolver {
constructor() {
this.options = {};
this.plugins = [];
}
addConfig(options, rootDir) {
for (const key in options) {
switch (key) {
case 'target':
const target = options.target;
if (typeof target === 'string') {
this.target = findVueVersion(rootDir);
}
else {
this.target = target;
}
break;
case 'plugins':
this.plugins = (options.plugins ?? [])
.map((pluginPath) => {
try {
const resolvedPath = resolvePath(pluginPath, rootDir);
if (resolvedPath) {
const plugin = require(resolvedPath);
plugin.__moduleName = pluginPath;
return plugin;
}
else {
console.warn('[Vue] Load plugin failed:', pluginPath);
}
}
catch (error) {
console.warn('[Vue] Resolve plugin path failed:', pluginPath, error);
}
return [];
});
break;
default:
// @ts-expect-error
this.options[key] = options[key];
break;
}
}
if (this.target === undefined) {
this.fallbackTarget = findVueVersion(rootDir);
}
}
build(defaults) {
const target = this.target ?? this.fallbackTarget;
defaults ??= getDefaultCompilerOptions(target, this.options.lib, this.options.strictTemplates);
return {
...defaults,
...this.options,
plugins: this.plugins,
macros: {
...defaults.macros,
...this.options.macros,
},
composables: {
...defaults.composables,
...this.options.composables,
},
fallthroughComponentNames: [
...defaults.fallthroughComponentNames,
...this.options.fallthroughComponentNames ?? []
].map(shared_2.hyphenateTag),
// https://github.com/vuejs/vue-next/blob/master/packages/compiler-dom/src/transforms/vModel.ts#L49-L51
// https://vuejs.org/guide/essentials/forms.html#form-input-bindings
experimentalModelPropName: Object.fromEntries(Object.entries(this.options.experimentalModelPropName ?? defaults.experimentalModelPropName).map(([k, v]) => [(0, shared_1.camelize)(k), v])),
};
}
}
exports.CompilerOptionsResolver = CompilerOptionsResolver;
function findVueVersion(rootDir) {
const resolvedPath = resolvePath('vue/package.json', rootDir);
if (resolvedPath) {
const vuePackageJson = require(resolvedPath);
const versionNumbers = vuePackageJson.version.split('.');
return Number(versionNumbers[0] + '.' + versionNumbers[1]);
}
else {
// console.warn('Load vue/package.json failed from', folder);
}
}
function resolvePath(scriptPath, root) {
try {
if (require?.resolve) {
return require.resolve(scriptPath, { paths: [root] });
}
else {
// console.warn('failed to resolve path:', scriptPath, 'require.resolve is not supported in web');
}
}
catch (error) {
// console.warn(error);
}
}
function getDefaultCompilerOptions(target = 99, lib = 'vue', strictTemplates = false) {
return {
target,
lib,
extensions: ['.vue'],
vitePressExtensions: [],
petiteVueExtensions: [],
jsxSlots: false,
checkUnknownProps: strictTemplates,
checkUnknownEvents: strictTemplates,
checkUnknownDirectives: strictTemplates,
checkUnknownComponents: strictTemplates,
inferComponentDollarEl: false,
inferComponentDollarRefs: false,
inferTemplateDollarAttrs: false,
inferTemplateDollarEl: false,
inferTemplateDollarRefs: false,
inferTemplateDollarSlots: false,
skipTemplateCodegen: false,
fallthroughAttributes: false,
fallthroughComponentNames: [
'Transition',
'KeepAlive',
'Teleport',
'Suspense',
],
dataAttributes: [],
htmlAttributes: ['aria-*'],
optionsWrapper: target >= 2.7
? [`(await import('${lib}')).defineComponent(`, `)`]
: [`(await import('${lib}')).default.extend(`, `)`],
macros: {
defineProps: ['defineProps'],
defineSlots: ['defineSlots'],
defineEmits: ['defineEmits'],
defineExpose: ['defineExpose'],
defineModel: ['defineModel'],
defineOptions: ['defineOptions'],
withDefaults: ['withDefaults'],
},
composables: {
useAttrs: ['useAttrs'],
useCssModule: ['useCssModule'],
useSlots: ['useSlots'],
useTemplateRef: ['useTemplateRef', 'templateRef'],
},
plugins: [],
experimentalDefinePropProposal: false,
experimentalResolveStyleCssClasses: 'scoped',
experimentalModelPropName: {
'': {
input: true
},
value: {
input: { type: 'text' },
textarea: true,
select: true
}
},
};
}
/**
* @deprecated use `getDefaultCompilerOptions` instead
*/
function resolveVueCompilerOptions(options) {
return {
...getDefaultCompilerOptions(options.target, options.lib),
...options,
};
}
function setupGlobalTypes(rootDir, vueOptions, host) {
if (!host.writeFile) {
return;
}
try {
let dir = rootDir;
while (!host.fileExists(path_browserify_1.posix.join(dir, 'node_modules', vueOptions.lib, 'package.json'))) {
const parentDir = path_browserify_1.posix.dirname(dir);
if (dir === parentDir) {
throw 0;
}
dir = parentDir;
}
const globalTypesPath = path_browserify_1.posix.join(dir, 'node_modules', '.vue-global-types', (0, globalTypes_1.getGlobalTypesFileName)(vueOptions));
const globalTypesContents = `// @ts-nocheck\nexport {};\n` + (0, globalTypes_1.generateGlobalTypes)(vueOptions);
host.writeFile(globalTypesPath, globalTypesContents);
return { absolutePath: globalTypesPath };
}
catch { }
}
//# sourceMappingURL=ts.js.map

View File

@@ -0,0 +1,2 @@
import * as CompilerDOM from '@vue/compiler-dom';
export declare const compile: typeof CompilerDOM.compile;

View File

@@ -0,0 +1,89 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.compile = void 0;
const CompilerDOM = require("@vue/compiler-dom");
const Vue2TemplateCompiler = require('@vue/compiler-vue2/build');
const compile = (template, options = {}) => {
if (typeof template !== 'string') {
throw new Error(`[@vue/language-core] compile() first argument must be string.`);
}
const onError = options.onError;
const onWarn = options.onWarn;
options.onError = error => {
if (error.code === 33 // :key binding allowed in v-for template child in vue 2
|| error.code === 29 // fix https://github.com/vuejs/language-tools/issues/1638
) {
return;
}
if (onError) {
onError(error);
}
else {
throw error;
}
};
const vue2Result = Vue2TemplateCompiler.compile(template, { outputSourceRange: true });
for (const error of vue2Result.errors) {
onError?.({
code: 'vue-template-compiler',
name: '',
message: error.msg,
loc: {
source: '',
start: { column: -1, line: -1, offset: error.start },
end: { column: -1, line: -1, offset: error.end ?? error.start },
},
});
}
for (const error of vue2Result.tips) {
onWarn?.({
code: 'vue-template-compiler',
name: '',
message: error.msg,
loc: {
source: '',
start: { column: -1, line: -1, offset: error.start },
end: { column: -1, line: -1, offset: error.end ?? error.start },
},
});
}
return baseCompile(template, Object.assign({}, CompilerDOM.parserOptions, options, {
nodeTransforms: [
...CompilerDOM.DOMNodeTransforms,
...(options.nodeTransforms || [])
],
directiveTransforms: Object.assign({}, CompilerDOM.DOMDirectiveTransforms, options.directiveTransforms || {}),
}));
};
exports.compile = compile;
function baseCompile(template, options = {}) {
const onError = options.onError || (error => { throw error; });
const isModuleMode = options.mode === 'module';
const prefixIdentifiers = options.prefixIdentifiers === true || isModuleMode;
if (!prefixIdentifiers && options.cacheHandlers) {
onError(CompilerDOM.createCompilerError(49));
}
if (options.scopeId && !isModuleMode) {
onError(CompilerDOM.createCompilerError(50));
}
const ast = CompilerDOM.baseParse(template, options);
const [nodeTransforms, directiveTransforms] = CompilerDOM.getBaseTransformPreset(prefixIdentifiers);
// v-for > v-if in vue 2
const transformIf = nodeTransforms[1];
const transformFor = nodeTransforms[3];
nodeTransforms[1] = transformFor;
nodeTransforms[3] = transformIf;
CompilerDOM.transform(ast, Object.assign({}, options, {
prefixIdentifiers,
nodeTransforms: [
...nodeTransforms,
...(options.nodeTransforms || []) // user transforms
],
directiveTransforms: Object.assign({}, directiveTransforms, options.directiveTransforms || {} // user transforms
)
}));
return CompilerDOM.generate(ast, Object.assign({}, options, {
prefixIdentifiers
}));
}
//# sourceMappingURL=vue2TemplateCompiler.js.map