UNPKG

els-addon-typed-templates

Version:
142 lines (128 loc) 4.38 kB
import * as path from "path"; import * as fs from "fs"; import { LSRegistry, matchPathToType } from './ts-service'; import { Project } from '@lifeart/ember-language-server'; import { isHBS } from './utils'; export function virtualTemplateFileName(fsPath) { const extName = path.extname(fsPath); return path .resolve(fsPath) .replace(extName, "--virtual-typed-template.ts"); } export function virtualComponentTemplateFileName(fsPath) { const extName = path.extname(fsPath); return path .resolve(fsPath) .replace(extName, "--virtual-typed-component-template.ts"); } export function relativeImport(templateFile, scriptFile) { return path .relative(templateFile, scriptFile) .split(path.sep) .join("/") .replace("..", ".") .replace(".d.ts", "") .replace(".ts", "") .replace(".js", ""); } export function relativeAddonImport( templateFileName: string, addonItemFileName: string ): string | null { let extname = path.extname(addonItemFileName); let subRelative = relativeImport(templateFileName, addonItemFileName); // ./../../../node_modules/@ember/render-modifiers/app/modifiers/did-insert let searchPref = "/node_modules/"; // todo - read ember-addons property if (subRelative.includes("node_modules")) { let normalizedRelative: string = subRelative.split(searchPref)[1]; let [group, item]: [string, string] = normalizedRelative.split("/") as any; let addonFolderName = group; if (group.startsWith("@")) { addonFolderName = [group, item].join("/"); } let normalizedEntry = addonItemFileName .split(path.sep) .join("/") .split(searchPref)[0]; let addonName = addonFolderName; try { let entry = path.join( normalizedEntry, "node_modules", addonFolderName, "index.js" ); if (!fs.existsSync(entry)) { return null; } let item = require(entry); if (item.name) { addonName = item.name; } } catch (e) { console.log(e); } let imp = normalizedRelative.slice( normalizedRelative.indexOf(addonFolderName) + addonFolderName.length + 1, normalizedRelative.length ); let addonImp = imp.replace("app/", "addon/"); let maybeAddonPath = path.join( normalizedEntry, "node_modules", addonFolderName, addonImp + extname ); if (fs.existsSync(maybeAddonPath)) { return `${addonName}/${addonImp.replace("addon/", "")}`; } else { return subRelative; } } else return subRelative; } export function relativeComponentImport( templateFileName: string, scriptForComponent: string ): string | null { return relativeAddonImport(templateFileName, scriptForComponent); } export function findComponentForTemplate(fsPath, project: Project, registry: LSRegistry) { const extName = path.extname(fsPath); const componentMeta = matchPathToType(project, fsPath); if (!isHBS(extName) || !componentMeta) { // @to-do figure out this strategy return null; } let possibleScripts: string[] = []; if (componentMeta.kind === 'template' && componentMeta.type === 'template') { possibleScripts = (registry.routePath[componentMeta.name.split('/').join('.')]||[]).filter((el)=>{ let meta = matchPathToType(project, el); if (!meta) { return null; } return meta.type === 'controller' && meta.kind === 'script'; }); } else { possibleScripts = (registry.component[componentMeta.name] || []).filter((el)=>{ let meta = matchPathToType(project, el); return meta && meta.kind === 'script' }); } if (possibleScripts.length > 1) { possibleScripts = possibleScripts.filter((el)=> { let meta = matchPathToType(project, el); // to-do - add support for typed-templates in addons (we need to check is it addon or not and replace scope) return meta && meta.scope === 'application'; }) } if (possibleScripts.length > 1) { possibleScripts = possibleScripts.filter((el)=> { return el.endsWith('.ts'); }) } if (possibleScripts.length === 0) { return null; } return possibleScripts.filter(fileLocation => fs.existsSync(fileLocation))[0]; }