@marko/language-tools 1.0.3 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -14,6 +14,5 @@ export interface ExtractScriptOptions {
14
14
  lookup: TaglibLookup;
15
15
  scriptLang: ScriptLang;
16
16
  runtimeTypesCode?: string;
17
- componentFilename?: string | undefined;
18
17
  }
19
18
  export declare function extractScript(opts: ExtractScriptOptions): import("../../util/extractor").Extracted;
@@ -0,0 +1 @@
1
+ export declare function getComponentFilename(from: string): string | undefined;
@@ -1,4 +1,4 @@
1
- import type TS from "typescript";
1
+ import type TS from "typescript/lib/tsserverlibrary";
2
2
  import type { Repeatable } from "../../../parser";
3
3
  export default function getJSDocInputType(comment: string, ts: typeof TS): {
4
4
  typeParameters: Repeatable<{
package/dist/index.d.ts CHANGED
@@ -1,4 +1,8 @@
1
1
  export * from "./parser";
2
2
  export * from "./extractors/style";
3
3
  export * from "./extractors/script";
4
+ export * as Project from "./util/project";
5
+ export * as Processors from "./processors";
6
+ export { getExt } from "./util/get-ext";
7
+ export { isDefinitionFile } from "./util/is-definition-file";
4
8
  export { type Extracted } from "./util/extractor";
package/dist/index.js CHANGED
@@ -31,13 +31,17 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var src_exports = {};
32
32
  __export(src_exports, {
33
33
  NodeType: () => NodeType,
34
+ Processors: () => processors_exports,
35
+ Project: () => project_exports,
34
36
  ScriptLang: () => ScriptLang,
35
37
  UNFINISHED: () => UNFINISHED,
36
38
  extractScript: () => extractScript,
37
39
  extractStyle: () => extractStyle,
40
+ getExt: () => getExt,
38
41
  getLines: () => import_htmljs_parser2.getLines,
39
42
  getLocation: () => import_htmljs_parser2.getLocation,
40
43
  getPosition: () => import_htmljs_parser2.getPosition,
44
+ isDefinitionFile: () => isDefinitionFile,
41
45
  parse: () => parse
42
46
  });
43
47
  module.exports = __toCommonJS(src_exports);
@@ -701,13 +705,8 @@ var Extractor = class {
701
705
  }
702
706
  };
703
707
  var Extracted = class {
704
- #parsed;
705
- #generated;
706
- #sourceToGenerated;
707
- #generatedToSource;
708
- #cachedGeneratedLines;
709
708
  constructor(parsed, generated, tokens) {
710
- this.#parsed = parsed;
709
+ this.parsed = parsed;
711
710
  this.#generated = generated;
712
711
  if (tokens.length === 0) {
713
712
  this.#generatedToSource = this.#sourceToGenerated = emptyView;
@@ -718,6 +717,10 @@ var Extracted = class {
718
717
  );
719
718
  }
720
719
  }
720
+ #generated;
721
+ #sourceToGenerated;
722
+ #generatedToSource;
723
+ #cachedGeneratedLines;
721
724
  get #generatedLines() {
722
725
  return this.#cachedGeneratedLines || (this.#cachedGeneratedLines = (0, import_htmljs_parser2.getLines)(this.#generated));
723
726
  }
@@ -727,7 +730,7 @@ var Extracted = class {
727
730
  sourcePositionAt(generatedOffset) {
728
731
  const sourceOffset = this.sourceOffsetAt(generatedOffset);
729
732
  if (sourceOffset !== void 0)
730
- return this.#parsed.positionAt(sourceOffset);
733
+ return this.parsed.positionAt(sourceOffset);
731
734
  }
732
735
  sourceLocationAt(generatedStart, generatedEnd) {
733
736
  const sourceRange = this.#generatedToSource.rangeAt(
@@ -735,7 +738,7 @@ var Extracted = class {
735
738
  generatedEnd
736
739
  );
737
740
  if (sourceRange) {
738
- return this.#parsed.locationAt(sourceRange);
741
+ return this.parsed.locationAt(sourceRange);
739
742
  }
740
743
  }
741
744
  generatedOffsetAt(sourceOffset) {
@@ -1525,6 +1528,31 @@ function traverse(node, enter) {
1525
1528
  }
1526
1529
  }
1527
1530
 
1531
+ // src/extractors/script/util/get-component-filename.ts
1532
+ var import_fs = __toESM(require("fs"));
1533
+ var import_path = __toESM(require("path"));
1534
+ function getComponentFilename(from) {
1535
+ const dir = import_path.default.dirname(from);
1536
+ const nameNoExt = import_path.default.basename(from, ".marko");
1537
+ const isEntry = nameNoExt === "index";
1538
+ const componentFull = `${nameNoExt}.component.`;
1539
+ const componentBrowserFull = `${nameNoExt}.component-browser.`;
1540
+ const componentPartial = isEntry ? "component." : void 0;
1541
+ const componentBrowserPartial = isEntry ? "component-browser." : void 0;
1542
+ for (const entry of tryReaddirSync(dir)) {
1543
+ if (entry !== from && (isEntry && entry.startsWith(componentBrowserPartial) || entry.startsWith(componentPartial)) || entry.startsWith(componentBrowserFull) || entry.startsWith(componentFull)) {
1544
+ return import_path.default.join(dir, entry);
1545
+ }
1546
+ }
1547
+ }
1548
+ function tryReaddirSync(dir) {
1549
+ try {
1550
+ return import_fs.default.readdirSync(dir);
1551
+ } catch {
1552
+ return [];
1553
+ }
1554
+ }
1555
+
1528
1556
  // src/extractors/script/util/runtime-overrides.ts
1529
1557
  var RuntimeOverloads = /* @__PURE__ */ new Map();
1530
1558
  var commentsReg = /\/\*(?:[^*]+|\*[^/])*\*\//gm;
@@ -1684,13 +1712,14 @@ var ScriptExtractor = class {
1684
1712
  this.#scriptParser = new ScriptParser(parsed.filename, parsed.code);
1685
1713
  this.#read = parsed.read.bind(parsed);
1686
1714
  this.#mutationOffsets = crawlProgramScope(this.#parsed, this.#scriptParser);
1687
- this.#writeProgram(parsed.program, opts.componentFilename);
1715
+ this.#writeProgram(parsed.program);
1688
1716
  }
1689
1717
  end() {
1690
1718
  return this.#extractor.end();
1691
1719
  }
1692
- #writeProgram(program, componentFileName) {
1720
+ #writeProgram(program) {
1693
1721
  this.#writeCommentPragmas(program);
1722
+ const componentFileName = getComponentFilename(this.#filename);
1694
1723
  const inputType = this.#getInputType(program);
1695
1724
  let componentClassBody;
1696
1725
  for (const node of program.static) {
@@ -2848,15 +2877,422 @@ function removeNewLines(str) {
2848
2877
  function isEmptyRange(range) {
2849
2878
  return range.start === range.end;
2850
2879
  }
2880
+
2881
+ // src/util/project.ts
2882
+ var project_exports = {};
2883
+ __export(project_exports, {
2884
+ clearCaches: () => clearCaches,
2885
+ getCache: () => getCache,
2886
+ getCompiler: () => getCompiler,
2887
+ getConfig: () => getConfig,
2888
+ getScriptLang: () => getScriptLang,
2889
+ getTagLookup: () => getTagLookup,
2890
+ getTypeLibs: () => getTypeLibs,
2891
+ setDefaultTypePaths: () => setDefaultTypePaths
2892
+ });
2893
+ var import_path2 = __toESM(require("path"));
2894
+ var import_module = require("module");
2895
+ var defaultCompiler = __toESM(require("@marko/compiler"));
2896
+ var defaultConfig = __toESM(require("@marko/compiler/config"));
2897
+ var defaultTranslator = __toESM(require("@marko/translator-default"));
2898
+ var import_strip_json_comments = __toESM(require("strip-json-comments"));
2899
+ var defaultTypeLibs = {};
2900
+ var ignoreErrors = (_err) => {
2901
+ };
2902
+ var metaByDir = /* @__PURE__ */ new Map();
2903
+ var metaByCompiler = /* @__PURE__ */ new Map();
2904
+ var defaultMeta = {
2905
+ compiler: defaultCompiler,
2906
+ config: {
2907
+ ...defaultConfig,
2908
+ cache: /* @__PURE__ */ new Map(),
2909
+ translator: defaultTranslator
2910
+ }
2911
+ };
2912
+ defaultCompiler.configure(defaultMeta.config);
2913
+ function getCompiler(dir) {
2914
+ return getMeta(dir).compiler;
2915
+ }
2916
+ function getCache(dir) {
2917
+ return getMeta(dir).config.cache;
2918
+ }
2919
+ function getConfig(dir) {
2920
+ return getMeta(dir).config;
2921
+ }
2922
+ function getTagLookup(dir) {
2923
+ return getTagLookupForProject(getMeta(dir), dir);
2924
+ }
2925
+ function getTypeLibs(rootDir, ts, host) {
2926
+ const config = getConfig(rootDir);
2927
+ let typeLibs = config.cache.get(getTypeLibs);
2928
+ if (typeLibs)
2929
+ return typeLibs;
2930
+ const resolveTypeCompilerOptions = {
2931
+ moduleResolution: ts.ModuleResolutionKind.Bundler
2932
+ };
2933
+ const markoRunGeneratedTypesFile = import_path2.default.join(
2934
+ rootDir,
2935
+ ".marko-run/routes.d.ts"
2936
+ );
2937
+ const resolveFromFile = import_path2.default.join(rootDir, "_.d.ts");
2938
+ const { resolvedTypeReferenceDirective: resolvedInternalTypes } = ts.resolveTypeReferenceDirective(
2939
+ "@marko/language-tools/marko.internal.d.ts",
2940
+ resolveFromFile,
2941
+ resolveTypeCompilerOptions,
2942
+ host
2943
+ );
2944
+ const { resolvedTypeReferenceDirective: resolvedMarkoTypes } = ts.resolveTypeReferenceDirective(
2945
+ config.translator.runtimeTypes || "marko",
2946
+ resolveFromFile,
2947
+ resolveTypeCompilerOptions,
2948
+ host
2949
+ );
2950
+ const { resolvedTypeReferenceDirective: resolvedMarkoRunTypes } = ts.resolveTypeReferenceDirective(
2951
+ "@marko/run",
2952
+ resolveFromFile,
2953
+ resolveTypeCompilerOptions,
2954
+ host
2955
+ );
2956
+ const internalTypesFile = (resolvedInternalTypes == null ? void 0 : resolvedInternalTypes.resolvedFileName) || defaultTypeLibs.internalTypesFile;
2957
+ const markoTypesFile = (resolvedMarkoTypes == null ? void 0 : resolvedMarkoTypes.resolvedFileName) || defaultTypeLibs.markoTypesFile;
2958
+ const markoRunTypesFile = resolvedMarkoRunTypes == null ? void 0 : resolvedMarkoRunTypes.resolvedFileName;
2959
+ if (!internalTypesFile || !markoTypesFile) {
2960
+ throw new Error("Could not resolve marko type files.");
2961
+ }
2962
+ config.cache.set(
2963
+ getTypeLibs,
2964
+ typeLibs = {
2965
+ internalTypesFile,
2966
+ markoTypesFile,
2967
+ markoTypesCode: host.readFile(markoTypesFile) || "",
2968
+ markoRunTypesFile,
2969
+ markoRunGeneratedTypesFile: host.fileExists(markoRunGeneratedTypesFile) ? markoRunGeneratedTypesFile : void 0
2970
+ }
2971
+ );
2972
+ return typeLibs;
2973
+ }
2974
+ function getScriptLang(fileName, defaultScriptLang, ts, host) {
2975
+ if (fileName.endsWith(".d.marko"))
2976
+ return "ts" /* ts */;
2977
+ const dir = import_path2.default.dirname(fileName);
2978
+ const config = getConfig(dir);
2979
+ const cache = config.cache.get(getScriptLang);
2980
+ let scriptLang = cache == null ? void 0 : cache.get(dir);
2981
+ if (!scriptLang) {
2982
+ const configPath = ts.findConfigFile(
2983
+ dir,
2984
+ host.fileExists.bind(host),
2985
+ "marko.json"
2986
+ );
2987
+ if (configPath) {
2988
+ try {
2989
+ const configSource = host.readFile(configPath);
2990
+ if (configSource) {
2991
+ const config2 = tryParseJSONWithComments(configSource);
2992
+ if (config2) {
2993
+ const definedScriptLang = config2["script-lang"] || config2.scriptLang;
2994
+ if (definedScriptLang !== void 0) {
2995
+ scriptLang = definedScriptLang === "ts" /* ts */ ? "ts" /* ts */ : "js" /* js */;
2996
+ }
2997
+ }
2998
+ }
2999
+ } catch {
3000
+ }
3001
+ }
3002
+ if (scriptLang === void 0) {
3003
+ scriptLang = /[/\\]node_modules[/\\]/.test(dir) ? "js" /* js */ : defaultScriptLang;
3004
+ }
3005
+ if (cache) {
3006
+ cache.set(dir, scriptLang);
3007
+ } else {
3008
+ config.cache.set(getScriptLang, /* @__PURE__ */ new Map([[dir, scriptLang]]));
3009
+ }
3010
+ }
3011
+ return scriptLang;
3012
+ }
3013
+ function clearCaches() {
3014
+ clearCacheForMeta(defaultMeta);
3015
+ for (const project of metaByCompiler.values()) {
3016
+ clearCacheForMeta(project);
3017
+ }
3018
+ }
3019
+ function setDefaultTypePaths(defaults) {
3020
+ Object.assign(defaultTypeLibs, defaults);
3021
+ }
3022
+ function getMeta(dir) {
3023
+ if (!dir)
3024
+ return defaultMeta;
3025
+ let cached = metaByDir.get(dir);
3026
+ if (!cached) {
3027
+ try {
3028
+ const require2 = (0, import_module.createRequire)(dir);
3029
+ const compilerConfigPath = require2.resolve("@marko/compiler/config");
3030
+ cached = metaByCompiler.get(compilerConfigPath);
3031
+ if (!cached) {
3032
+ const compiler = require2(import_path2.default.join(
3033
+ compilerConfigPath,
3034
+ ".."
3035
+ ));
3036
+ const config = interopDefault(
3037
+ require2(compilerConfigPath)
3038
+ );
3039
+ cached = {
3040
+ compiler,
3041
+ config: {
3042
+ ...config,
3043
+ cache: /* @__PURE__ */ new Map(),
3044
+ translator: require2(config.translator)
3045
+ }
3046
+ };
3047
+ compiler.configure(cached.config);
3048
+ metaByCompiler.set(compilerConfigPath, cached);
3049
+ }
3050
+ } catch {
3051
+ cached = defaultMeta;
3052
+ }
3053
+ metaByDir.set(dir, cached);
3054
+ }
3055
+ return cached;
3056
+ }
3057
+ function getTagLookupForProject(meta, dir) {
3058
+ const cache = meta.config.cache.get(getTagLookupForProject);
3059
+ let lookup = cache == null ? void 0 : cache.get(dir);
3060
+ if (lookup === void 0) {
3061
+ try {
3062
+ lookup = meta.compiler.taglib.buildLookup(
3063
+ dir,
3064
+ meta.config.translator,
3065
+ ignoreErrors
3066
+ );
3067
+ } catch {
3068
+ if (meta !== defaultMeta) {
3069
+ lookup = getTagLookupForProject(defaultMeta, dir);
3070
+ }
3071
+ }
3072
+ if (cache) {
3073
+ cache.set(dir, lookup);
3074
+ } else {
3075
+ meta.config.cache.set(getTagLookupForProject, /* @__PURE__ */ new Map([[dir, lookup]]));
3076
+ }
3077
+ }
3078
+ return lookup;
3079
+ }
3080
+ function clearCacheForMeta(meta) {
3081
+ meta.config.cache.clear();
3082
+ meta.compiler.taglib.clearCaches();
3083
+ }
3084
+ function tryParseJSONWithComments(content) {
3085
+ try {
3086
+ return JSON.parse((0, import_strip_json_comments.default)(content));
3087
+ } catch {
3088
+ return void 0;
3089
+ }
3090
+ }
3091
+ function interopDefault(mod) {
3092
+ return mod.default || mod;
3093
+ }
3094
+
3095
+ // src/processors/index.ts
3096
+ var processors_exports = {};
3097
+ __export(processors_exports, {
3098
+ create: () => create,
3099
+ extensions: () => extensions,
3100
+ has: () => has
3101
+ });
3102
+
3103
+ // src/util/get-ext.ts
3104
+ function getExt(fileName) {
3105
+ const extIndex = fileName.lastIndexOf(".");
3106
+ if (extIndex !== -1)
3107
+ return fileName.slice(extIndex);
3108
+ }
3109
+
3110
+ // src/processors/marko.ts
3111
+ var import_path3 = __toESM(require("path"));
3112
+ var marko_default = {
3113
+ extension: ".marko",
3114
+ create({ ts, host, configFile }) {
3115
+ const currentDirectory = host.getCurrentDirectory ? host.getCurrentDirectory() : ts.sys.getCurrentDirectory();
3116
+ const defaultScriptLang = configFile && /tsconfig.json$/.test(configFile) ? "ts" /* ts */ : "js" /* js */;
3117
+ const runtimeTypes = getTypeLibs(currentDirectory, ts, host);
3118
+ const rootNames = [
3119
+ runtimeTypes.internalTypesFile,
3120
+ runtimeTypes.markoTypesFile
3121
+ ];
3122
+ if (runtimeTypes.markoRunTypesFile) {
3123
+ rootNames.push(runtimeTypes.markoRunTypesFile);
3124
+ }
3125
+ if (runtimeTypes.markoRunGeneratedTypesFile) {
3126
+ rootNames.push(runtimeTypes.markoRunGeneratedTypesFile);
3127
+ }
3128
+ return {
3129
+ getRootNames() {
3130
+ return rootNames;
3131
+ },
3132
+ getScriptExtension(fileName) {
3133
+ return getScriptLang(fileName, defaultScriptLang, ts, host) === "ts" /* ts */ ? ts.Extension.Ts : ts.Extension.Js;
3134
+ },
3135
+ getScriptKind(fileName) {
3136
+ return getScriptLang(fileName, defaultScriptLang, ts, host) === "ts" /* ts */ ? ts.ScriptKind.TS : ts.ScriptKind.JS;
3137
+ },
3138
+ extract(fileName, code) {
3139
+ const dir = import_path3.default.dirname(fileName);
3140
+ const parsed = parse(code, fileName);
3141
+ return extractScript({
3142
+ ts,
3143
+ parsed,
3144
+ lookup: getTagLookup(dir),
3145
+ scriptLang: getScriptLang(
3146
+ fileName,
3147
+ defaultScriptLang,
3148
+ ts,
3149
+ host
3150
+ ),
3151
+ runtimeTypesCode: runtimeTypes.markoTypesCode
3152
+ });
3153
+ },
3154
+ print({ extracted: { parsed } }) {
3155
+ const { code, map } = getCompiler(
3156
+ import_path3.default.dirname(parsed.filename)
3157
+ ).compileSync(parsed.code, parsed.filename, {
3158
+ output: "source",
3159
+ stripTypes: true,
3160
+ sourceMaps: true
3161
+ });
3162
+ return { code, map };
3163
+ },
3164
+ printTypes({ printer, typeChecker, sourceFile, formatSettings }) {
3165
+ var _a, _b, _c;
3166
+ let code = "";
3167
+ const nlChar = formatSettings.newLineCharacter;
3168
+ const tabChar = formatSettings.convertTabsToSpaces ? " ".repeat(formatSettings.indentSize) : " ";
3169
+ let defaultExport;
3170
+ let defaultExportId;
3171
+ let componentImpl;
3172
+ let internalRenderImpl;
3173
+ for (const statement of sourceFile.statements) {
3174
+ if (ts.isExportAssignment(statement)) {
3175
+ defaultExport = statement;
3176
+ defaultExportId = ts.isIdentifier(statement.expression) ? statement.expression.escapedText : void 0;
3177
+ } else if (ts.isClassDeclaration(statement) && ((_a = statement.name) == null ? void 0 : _a.escapedText) === "Component") {
3178
+ componentImpl = statement;
3179
+ } else if (ts.isFunctionDeclaration(statement) && ((_b = statement.name) == null ? void 0 : _b.escapedText) === "___marko_internal_template") {
3180
+ internalRenderImpl = statement;
3181
+ }
3182
+ }
3183
+ for (const statement of sourceFile.statements) {
3184
+ if (statement === defaultExport || // skips the generated `export default ...`.
3185
+ statement === componentImpl || // skips the generated `class {}` since it needs special processing.
3186
+ statement === internalRenderImpl || // skips the internal template render code.
3187
+ isExportComponentType(statement) || // skips the generated `export { type Component }`.
3188
+ isImportComponentType(statement) || // skips the generated `import type Component from "..."`.
3189
+ isExportEmptyInputType(statement) || // skips empty exported Input, eg `export type Input = {}` or `export interface Input {}`.
3190
+ isExportInputTypeAsComponentInput(statement) || // skips outputing `export type Input = Component["input"]` since it's inferred.
3191
+ defaultExportId && // If the `export default` was an identifier, we also remove the variable that declared the identifier.
3192
+ isVariableStatementForName(statement, defaultExportId)) {
3193
+ continue;
3194
+ }
3195
+ const printed = printer.printNode(
3196
+ ts.EmitHint.Unspecified,
3197
+ statement,
3198
+ sourceFile
3199
+ );
3200
+ if (!/^(?:import|export) /.test(printed))
3201
+ code += "static ";
3202
+ code += printed + nlChar;
3203
+ }
3204
+ if (componentImpl == null ? void 0 : componentImpl.members.length) {
3205
+ code += `class {${nlChar}`;
3206
+ for (const member of componentImpl.members) {
3207
+ if (ts.isPropertyDeclaration(member)) {
3208
+ code += `${tabChar}declare ${printer.printNode(ts.EmitHint.Unspecified, member, sourceFile) + nlChar}`;
3209
+ } else if (ts.isMethodDeclaration(member) || ts.isGetAccessorDeclaration(member) || ts.isSetAccessorDeclaration(member)) {
3210
+ code += `${tabChar + printer.printNode(ts.EmitHint.Unspecified, member, sourceFile).replace(/;\s*$/, "")} { return ${castType("any")}; }${nlChar}`;
3211
+ } else if (ts.isIndexSignatureDeclaration(member)) {
3212
+ code += tabChar + printer.printNode(ts.EmitHint.Unspecified, member, sourceFile) + nlChar;
3213
+ }
3214
+ }
3215
+ code += `}${nlChar}`;
3216
+ }
3217
+ if (internalRenderImpl) {
3218
+ const returnType = (_c = typeChecker.getSignatureFromDeclaration(internalRenderImpl)) == null ? void 0 : _c.getReturnType();
3219
+ if (returnType) {
3220
+ const props = returnType.getProperties();
3221
+ const valueType = props.length === 1 && props[0].name === "value" && typeChecker.getPropertyOfType(returnType, "value") || void 0;
3222
+ code += "<return ";
3223
+ if (valueType) {
3224
+ code += `= ${castType(
3225
+ typeChecker.typeToString(typeChecker.getTypeOfSymbol(valueType))
3226
+ )}`;
3227
+ } else {
3228
+ code += `...${castType(typeChecker.typeToString(returnType))}`;
3229
+ }
3230
+ code += `/>${nlChar}`;
3231
+ }
3232
+ }
3233
+ return { code };
3234
+ }
3235
+ };
3236
+ function isImportComponentType(statement) {
3237
+ var _a, _b;
3238
+ return ts.isImportDeclaration(statement) && ((_b = (_a = statement.importClause) == null ? void 0 : _a.name) == null ? void 0 : _b.escapedText) === "Component";
3239
+ }
3240
+ function isExportInputTypeAsComponentInput(statement) {
3241
+ return ts.isTypeAliasDeclaration(statement) && statement.name.escapedText === "Input" && ts.isIndexedAccessTypeNode(statement.type) && ts.isTypeReferenceNode(statement.type.objectType) && ts.isIdentifier(statement.type.objectType.typeName) && statement.type.objectType.typeName.escapedText === "Component" && ts.isLiteralTypeNode(statement.type.indexType) && ts.isStringLiteral(statement.type.indexType.literal) && statement.type.indexType.literal.text === "input";
3242
+ }
3243
+ function isExportEmptyInputType(statement) {
3244
+ return ts.isTypeAliasDeclaration(statement) && statement.name.escapedText === "Input" && ts.isTypeLiteralNode(statement.type) && !statement.typeParameters && statement.type.members.length === 0 || ts.isInterfaceDeclaration(statement) && statement.name.escapedText === "Input" && !statement.typeParameters && statement.members.length === 0;
3245
+ }
3246
+ function isExportComponentType(statement) {
3247
+ return ts.isExportDeclaration(statement) && statement.exportClause && ts.isNamedExports(statement.exportClause) && statement.exportClause.elements.length === 1 && statement.exportClause.elements[0].name.escapedText === "Component";
3248
+ }
3249
+ function isVariableStatementForName(statement, name) {
3250
+ if (ts.isVariableStatement(statement)) {
3251
+ for (const decl of statement.declarationList.declarations) {
3252
+ if (ts.isIdentifier(decl.name) && decl.name.escapedText === name) {
3253
+ return true;
3254
+ }
3255
+ }
3256
+ }
3257
+ }
3258
+ }
3259
+ };
3260
+ function castType(type) {
3261
+ if (type === "any") {
3262
+ return "1 as any";
3263
+ }
3264
+ return `(1 as any as ${type})`;
3265
+ }
3266
+
3267
+ // src/processors/index.ts
3268
+ var extensions = [marko_default.extension];
3269
+ function create(options) {
3270
+ return {
3271
+ [marko_default.extension]: marko_default.create(options)
3272
+ };
3273
+ }
3274
+ function has(fileName) {
3275
+ const ext = getExt(fileName);
3276
+ return !!(ext && extensions.includes(ext));
3277
+ }
3278
+
3279
+ // src/util/is-definition-file.ts
3280
+ function isDefinitionFile(fileName) {
3281
+ return /\.d\.[^.]+$/.test(fileName);
3282
+ }
2851
3283
  // Annotate the CommonJS export names for ESM import in node:
2852
3284
  0 && (module.exports = {
2853
3285
  NodeType,
3286
+ Processors,
3287
+ Project,
2854
3288
  ScriptLang,
2855
3289
  UNFINISHED,
2856
3290
  extractScript,
2857
3291
  extractStyle,
3292
+ getExt,
2858
3293
  getLines,
2859
3294
  getLocation,
2860
3295
  getPosition,
3296
+ isDefinitionFile,
2861
3297
  parse
2862
3298
  });
package/dist/index.mjs CHANGED
@@ -1,3 +1,9 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+
1
7
  // src/parser.ts
2
8
  import { TagType, createParser } from "htmljs-parser";
3
9
 
@@ -661,13 +667,8 @@ var Extractor = class {
661
667
  }
662
668
  };
663
669
  var Extracted = class {
664
- #parsed;
665
- #generated;
666
- #sourceToGenerated;
667
- #generatedToSource;
668
- #cachedGeneratedLines;
669
670
  constructor(parsed, generated, tokens) {
670
- this.#parsed = parsed;
671
+ this.parsed = parsed;
671
672
  this.#generated = generated;
672
673
  if (tokens.length === 0) {
673
674
  this.#generatedToSource = this.#sourceToGenerated = emptyView;
@@ -678,6 +679,10 @@ var Extracted = class {
678
679
  );
679
680
  }
680
681
  }
682
+ #generated;
683
+ #sourceToGenerated;
684
+ #generatedToSource;
685
+ #cachedGeneratedLines;
681
686
  get #generatedLines() {
682
687
  return this.#cachedGeneratedLines || (this.#cachedGeneratedLines = getLines(this.#generated));
683
688
  }
@@ -687,7 +692,7 @@ var Extracted = class {
687
692
  sourcePositionAt(generatedOffset) {
688
693
  const sourceOffset = this.sourceOffsetAt(generatedOffset);
689
694
  if (sourceOffset !== void 0)
690
- return this.#parsed.positionAt(sourceOffset);
695
+ return this.parsed.positionAt(sourceOffset);
691
696
  }
692
697
  sourceLocationAt(generatedStart, generatedEnd) {
693
698
  const sourceRange = this.#generatedToSource.rangeAt(
@@ -695,7 +700,7 @@ var Extracted = class {
695
700
  generatedEnd
696
701
  );
697
702
  if (sourceRange) {
698
- return this.#parsed.locationAt(sourceRange);
703
+ return this.parsed.locationAt(sourceRange);
699
704
  }
700
705
  }
701
706
  generatedOffsetAt(sourceOffset) {
@@ -1492,6 +1497,31 @@ function traverse(node, enter) {
1492
1497
  }
1493
1498
  }
1494
1499
 
1500
+ // src/extractors/script/util/get-component-filename.ts
1501
+ import fs from "fs";
1502
+ import path from "path";
1503
+ function getComponentFilename(from) {
1504
+ const dir = path.dirname(from);
1505
+ const nameNoExt = path.basename(from, ".marko");
1506
+ const isEntry = nameNoExt === "index";
1507
+ const componentFull = `${nameNoExt}.component.`;
1508
+ const componentBrowserFull = `${nameNoExt}.component-browser.`;
1509
+ const componentPartial = isEntry ? "component." : void 0;
1510
+ const componentBrowserPartial = isEntry ? "component-browser." : void 0;
1511
+ for (const entry of tryReaddirSync(dir)) {
1512
+ if (entry !== from && (isEntry && entry.startsWith(componentBrowserPartial) || entry.startsWith(componentPartial)) || entry.startsWith(componentBrowserFull) || entry.startsWith(componentFull)) {
1513
+ return path.join(dir, entry);
1514
+ }
1515
+ }
1516
+ }
1517
+ function tryReaddirSync(dir) {
1518
+ try {
1519
+ return fs.readdirSync(dir);
1520
+ } catch {
1521
+ return [];
1522
+ }
1523
+ }
1524
+
1495
1525
  // src/extractors/script/util/runtime-overrides.ts
1496
1526
  var RuntimeOverloads = /* @__PURE__ */ new Map();
1497
1527
  var commentsReg = /\/\*(?:[^*]+|\*[^/])*\*\//gm;
@@ -1651,13 +1681,14 @@ var ScriptExtractor = class {
1651
1681
  this.#scriptParser = new ScriptParser(parsed.filename, parsed.code);
1652
1682
  this.#read = parsed.read.bind(parsed);
1653
1683
  this.#mutationOffsets = crawlProgramScope(this.#parsed, this.#scriptParser);
1654
- this.#writeProgram(parsed.program, opts.componentFilename);
1684
+ this.#writeProgram(parsed.program);
1655
1685
  }
1656
1686
  end() {
1657
1687
  return this.#extractor.end();
1658
1688
  }
1659
- #writeProgram(program, componentFileName) {
1689
+ #writeProgram(program) {
1660
1690
  this.#writeCommentPragmas(program);
1691
+ const componentFileName = getComponentFilename(this.#filename);
1661
1692
  const inputType = this.#getInputType(program);
1662
1693
  let componentClassBody;
1663
1694
  for (const node of program.static) {
@@ -2815,14 +2846,421 @@ function removeNewLines(str) {
2815
2846
  function isEmptyRange(range) {
2816
2847
  return range.start === range.end;
2817
2848
  }
2849
+
2850
+ // src/util/project.ts
2851
+ var project_exports = {};
2852
+ __export(project_exports, {
2853
+ clearCaches: () => clearCaches,
2854
+ getCache: () => getCache,
2855
+ getCompiler: () => getCompiler,
2856
+ getConfig: () => getConfig,
2857
+ getScriptLang: () => getScriptLang,
2858
+ getTagLookup: () => getTagLookup,
2859
+ getTypeLibs: () => getTypeLibs,
2860
+ setDefaultTypePaths: () => setDefaultTypePaths
2861
+ });
2862
+ import path2 from "path";
2863
+ import { createRequire } from "module";
2864
+ import * as defaultCompiler from "@marko/compiler";
2865
+ import * as defaultConfig from "@marko/compiler/config";
2866
+ import * as defaultTranslator from "@marko/translator-default";
2867
+ import stripJSONComments from "strip-json-comments";
2868
+ var defaultTypeLibs = {};
2869
+ var ignoreErrors = (_err) => {
2870
+ };
2871
+ var metaByDir = /* @__PURE__ */ new Map();
2872
+ var metaByCompiler = /* @__PURE__ */ new Map();
2873
+ var defaultMeta = {
2874
+ compiler: defaultCompiler,
2875
+ config: {
2876
+ ...defaultConfig,
2877
+ cache: /* @__PURE__ */ new Map(),
2878
+ translator: defaultTranslator
2879
+ }
2880
+ };
2881
+ defaultCompiler.configure(defaultMeta.config);
2882
+ function getCompiler(dir) {
2883
+ return getMeta(dir).compiler;
2884
+ }
2885
+ function getCache(dir) {
2886
+ return getMeta(dir).config.cache;
2887
+ }
2888
+ function getConfig(dir) {
2889
+ return getMeta(dir).config;
2890
+ }
2891
+ function getTagLookup(dir) {
2892
+ return getTagLookupForProject(getMeta(dir), dir);
2893
+ }
2894
+ function getTypeLibs(rootDir, ts, host) {
2895
+ const config = getConfig(rootDir);
2896
+ let typeLibs = config.cache.get(getTypeLibs);
2897
+ if (typeLibs)
2898
+ return typeLibs;
2899
+ const resolveTypeCompilerOptions = {
2900
+ moduleResolution: ts.ModuleResolutionKind.Bundler
2901
+ };
2902
+ const markoRunGeneratedTypesFile = path2.join(
2903
+ rootDir,
2904
+ ".marko-run/routes.d.ts"
2905
+ );
2906
+ const resolveFromFile = path2.join(rootDir, "_.d.ts");
2907
+ const { resolvedTypeReferenceDirective: resolvedInternalTypes } = ts.resolveTypeReferenceDirective(
2908
+ "@marko/language-tools/marko.internal.d.ts",
2909
+ resolveFromFile,
2910
+ resolveTypeCompilerOptions,
2911
+ host
2912
+ );
2913
+ const { resolvedTypeReferenceDirective: resolvedMarkoTypes } = ts.resolveTypeReferenceDirective(
2914
+ config.translator.runtimeTypes || "marko",
2915
+ resolveFromFile,
2916
+ resolveTypeCompilerOptions,
2917
+ host
2918
+ );
2919
+ const { resolvedTypeReferenceDirective: resolvedMarkoRunTypes } = ts.resolveTypeReferenceDirective(
2920
+ "@marko/run",
2921
+ resolveFromFile,
2922
+ resolveTypeCompilerOptions,
2923
+ host
2924
+ );
2925
+ const internalTypesFile = (resolvedInternalTypes == null ? void 0 : resolvedInternalTypes.resolvedFileName) || defaultTypeLibs.internalTypesFile;
2926
+ const markoTypesFile = (resolvedMarkoTypes == null ? void 0 : resolvedMarkoTypes.resolvedFileName) || defaultTypeLibs.markoTypesFile;
2927
+ const markoRunTypesFile = resolvedMarkoRunTypes == null ? void 0 : resolvedMarkoRunTypes.resolvedFileName;
2928
+ if (!internalTypesFile || !markoTypesFile) {
2929
+ throw new Error("Could not resolve marko type files.");
2930
+ }
2931
+ config.cache.set(
2932
+ getTypeLibs,
2933
+ typeLibs = {
2934
+ internalTypesFile,
2935
+ markoTypesFile,
2936
+ markoTypesCode: host.readFile(markoTypesFile) || "",
2937
+ markoRunTypesFile,
2938
+ markoRunGeneratedTypesFile: host.fileExists(markoRunGeneratedTypesFile) ? markoRunGeneratedTypesFile : void 0
2939
+ }
2940
+ );
2941
+ return typeLibs;
2942
+ }
2943
+ function getScriptLang(fileName, defaultScriptLang, ts, host) {
2944
+ if (fileName.endsWith(".d.marko"))
2945
+ return "ts" /* ts */;
2946
+ const dir = path2.dirname(fileName);
2947
+ const config = getConfig(dir);
2948
+ const cache = config.cache.get(getScriptLang);
2949
+ let scriptLang = cache == null ? void 0 : cache.get(dir);
2950
+ if (!scriptLang) {
2951
+ const configPath = ts.findConfigFile(
2952
+ dir,
2953
+ host.fileExists.bind(host),
2954
+ "marko.json"
2955
+ );
2956
+ if (configPath) {
2957
+ try {
2958
+ const configSource = host.readFile(configPath);
2959
+ if (configSource) {
2960
+ const config2 = tryParseJSONWithComments(configSource);
2961
+ if (config2) {
2962
+ const definedScriptLang = config2["script-lang"] || config2.scriptLang;
2963
+ if (definedScriptLang !== void 0) {
2964
+ scriptLang = definedScriptLang === "ts" /* ts */ ? "ts" /* ts */ : "js" /* js */;
2965
+ }
2966
+ }
2967
+ }
2968
+ } catch {
2969
+ }
2970
+ }
2971
+ if (scriptLang === void 0) {
2972
+ scriptLang = /[/\\]node_modules[/\\]/.test(dir) ? "js" /* js */ : defaultScriptLang;
2973
+ }
2974
+ if (cache) {
2975
+ cache.set(dir, scriptLang);
2976
+ } else {
2977
+ config.cache.set(getScriptLang, /* @__PURE__ */ new Map([[dir, scriptLang]]));
2978
+ }
2979
+ }
2980
+ return scriptLang;
2981
+ }
2982
+ function clearCaches() {
2983
+ clearCacheForMeta(defaultMeta);
2984
+ for (const project of metaByCompiler.values()) {
2985
+ clearCacheForMeta(project);
2986
+ }
2987
+ }
2988
+ function setDefaultTypePaths(defaults) {
2989
+ Object.assign(defaultTypeLibs, defaults);
2990
+ }
2991
+ function getMeta(dir) {
2992
+ if (!dir)
2993
+ return defaultMeta;
2994
+ let cached = metaByDir.get(dir);
2995
+ if (!cached) {
2996
+ try {
2997
+ const require2 = createRequire(dir);
2998
+ const compilerConfigPath = require2.resolve("@marko/compiler/config");
2999
+ cached = metaByCompiler.get(compilerConfigPath);
3000
+ if (!cached) {
3001
+ const compiler = require2(path2.join(
3002
+ compilerConfigPath,
3003
+ ".."
3004
+ ));
3005
+ const config = interopDefault(
3006
+ require2(compilerConfigPath)
3007
+ );
3008
+ cached = {
3009
+ compiler,
3010
+ config: {
3011
+ ...config,
3012
+ cache: /* @__PURE__ */ new Map(),
3013
+ translator: require2(config.translator)
3014
+ }
3015
+ };
3016
+ compiler.configure(cached.config);
3017
+ metaByCompiler.set(compilerConfigPath, cached);
3018
+ }
3019
+ } catch {
3020
+ cached = defaultMeta;
3021
+ }
3022
+ metaByDir.set(dir, cached);
3023
+ }
3024
+ return cached;
3025
+ }
3026
+ function getTagLookupForProject(meta, dir) {
3027
+ const cache = meta.config.cache.get(getTagLookupForProject);
3028
+ let lookup = cache == null ? void 0 : cache.get(dir);
3029
+ if (lookup === void 0) {
3030
+ try {
3031
+ lookup = meta.compiler.taglib.buildLookup(
3032
+ dir,
3033
+ meta.config.translator,
3034
+ ignoreErrors
3035
+ );
3036
+ } catch {
3037
+ if (meta !== defaultMeta) {
3038
+ lookup = getTagLookupForProject(defaultMeta, dir);
3039
+ }
3040
+ }
3041
+ if (cache) {
3042
+ cache.set(dir, lookup);
3043
+ } else {
3044
+ meta.config.cache.set(getTagLookupForProject, /* @__PURE__ */ new Map([[dir, lookup]]));
3045
+ }
3046
+ }
3047
+ return lookup;
3048
+ }
3049
+ function clearCacheForMeta(meta) {
3050
+ meta.config.cache.clear();
3051
+ meta.compiler.taglib.clearCaches();
3052
+ }
3053
+ function tryParseJSONWithComments(content) {
3054
+ try {
3055
+ return JSON.parse(stripJSONComments(content));
3056
+ } catch {
3057
+ return void 0;
3058
+ }
3059
+ }
3060
+ function interopDefault(mod) {
3061
+ return mod.default || mod;
3062
+ }
3063
+
3064
+ // src/processors/index.ts
3065
+ var processors_exports = {};
3066
+ __export(processors_exports, {
3067
+ create: () => create,
3068
+ extensions: () => extensions,
3069
+ has: () => has
3070
+ });
3071
+
3072
+ // src/util/get-ext.ts
3073
+ function getExt(fileName) {
3074
+ const extIndex = fileName.lastIndexOf(".");
3075
+ if (extIndex !== -1)
3076
+ return fileName.slice(extIndex);
3077
+ }
3078
+
3079
+ // src/processors/marko.ts
3080
+ import path3 from "path";
3081
+ var marko_default = {
3082
+ extension: ".marko",
3083
+ create({ ts, host, configFile }) {
3084
+ const currentDirectory = host.getCurrentDirectory ? host.getCurrentDirectory() : ts.sys.getCurrentDirectory();
3085
+ const defaultScriptLang = configFile && /tsconfig.json$/.test(configFile) ? "ts" /* ts */ : "js" /* js */;
3086
+ const runtimeTypes = getTypeLibs(currentDirectory, ts, host);
3087
+ const rootNames = [
3088
+ runtimeTypes.internalTypesFile,
3089
+ runtimeTypes.markoTypesFile
3090
+ ];
3091
+ if (runtimeTypes.markoRunTypesFile) {
3092
+ rootNames.push(runtimeTypes.markoRunTypesFile);
3093
+ }
3094
+ if (runtimeTypes.markoRunGeneratedTypesFile) {
3095
+ rootNames.push(runtimeTypes.markoRunGeneratedTypesFile);
3096
+ }
3097
+ return {
3098
+ getRootNames() {
3099
+ return rootNames;
3100
+ },
3101
+ getScriptExtension(fileName) {
3102
+ return getScriptLang(fileName, defaultScriptLang, ts, host) === "ts" /* ts */ ? ts.Extension.Ts : ts.Extension.Js;
3103
+ },
3104
+ getScriptKind(fileName) {
3105
+ return getScriptLang(fileName, defaultScriptLang, ts, host) === "ts" /* ts */ ? ts.ScriptKind.TS : ts.ScriptKind.JS;
3106
+ },
3107
+ extract(fileName, code) {
3108
+ const dir = path3.dirname(fileName);
3109
+ const parsed = parse(code, fileName);
3110
+ return extractScript({
3111
+ ts,
3112
+ parsed,
3113
+ lookup: getTagLookup(dir),
3114
+ scriptLang: getScriptLang(
3115
+ fileName,
3116
+ defaultScriptLang,
3117
+ ts,
3118
+ host
3119
+ ),
3120
+ runtimeTypesCode: runtimeTypes.markoTypesCode
3121
+ });
3122
+ },
3123
+ print({ extracted: { parsed } }) {
3124
+ const { code, map } = getCompiler(
3125
+ path3.dirname(parsed.filename)
3126
+ ).compileSync(parsed.code, parsed.filename, {
3127
+ output: "source",
3128
+ stripTypes: true,
3129
+ sourceMaps: true
3130
+ });
3131
+ return { code, map };
3132
+ },
3133
+ printTypes({ printer, typeChecker, sourceFile, formatSettings }) {
3134
+ var _a, _b, _c;
3135
+ let code = "";
3136
+ const nlChar = formatSettings.newLineCharacter;
3137
+ const tabChar = formatSettings.convertTabsToSpaces ? " ".repeat(formatSettings.indentSize) : " ";
3138
+ let defaultExport;
3139
+ let defaultExportId;
3140
+ let componentImpl;
3141
+ let internalRenderImpl;
3142
+ for (const statement of sourceFile.statements) {
3143
+ if (ts.isExportAssignment(statement)) {
3144
+ defaultExport = statement;
3145
+ defaultExportId = ts.isIdentifier(statement.expression) ? statement.expression.escapedText : void 0;
3146
+ } else if (ts.isClassDeclaration(statement) && ((_a = statement.name) == null ? void 0 : _a.escapedText) === "Component") {
3147
+ componentImpl = statement;
3148
+ } else if (ts.isFunctionDeclaration(statement) && ((_b = statement.name) == null ? void 0 : _b.escapedText) === "___marko_internal_template") {
3149
+ internalRenderImpl = statement;
3150
+ }
3151
+ }
3152
+ for (const statement of sourceFile.statements) {
3153
+ if (statement === defaultExport || // skips the generated `export default ...`.
3154
+ statement === componentImpl || // skips the generated `class {}` since it needs special processing.
3155
+ statement === internalRenderImpl || // skips the internal template render code.
3156
+ isExportComponentType(statement) || // skips the generated `export { type Component }`.
3157
+ isImportComponentType(statement) || // skips the generated `import type Component from "..."`.
3158
+ isExportEmptyInputType(statement) || // skips empty exported Input, eg `export type Input = {}` or `export interface Input {}`.
3159
+ isExportInputTypeAsComponentInput(statement) || // skips outputing `export type Input = Component["input"]` since it's inferred.
3160
+ defaultExportId && // If the `export default` was an identifier, we also remove the variable that declared the identifier.
3161
+ isVariableStatementForName(statement, defaultExportId)) {
3162
+ continue;
3163
+ }
3164
+ const printed = printer.printNode(
3165
+ ts.EmitHint.Unspecified,
3166
+ statement,
3167
+ sourceFile
3168
+ );
3169
+ if (!/^(?:import|export) /.test(printed))
3170
+ code += "static ";
3171
+ code += printed + nlChar;
3172
+ }
3173
+ if (componentImpl == null ? void 0 : componentImpl.members.length) {
3174
+ code += `class {${nlChar}`;
3175
+ for (const member of componentImpl.members) {
3176
+ if (ts.isPropertyDeclaration(member)) {
3177
+ code += `${tabChar}declare ${printer.printNode(ts.EmitHint.Unspecified, member, sourceFile) + nlChar}`;
3178
+ } else if (ts.isMethodDeclaration(member) || ts.isGetAccessorDeclaration(member) || ts.isSetAccessorDeclaration(member)) {
3179
+ code += `${tabChar + printer.printNode(ts.EmitHint.Unspecified, member, sourceFile).replace(/;\s*$/, "")} { return ${castType("any")}; }${nlChar}`;
3180
+ } else if (ts.isIndexSignatureDeclaration(member)) {
3181
+ code += tabChar + printer.printNode(ts.EmitHint.Unspecified, member, sourceFile) + nlChar;
3182
+ }
3183
+ }
3184
+ code += `}${nlChar}`;
3185
+ }
3186
+ if (internalRenderImpl) {
3187
+ const returnType = (_c = typeChecker.getSignatureFromDeclaration(internalRenderImpl)) == null ? void 0 : _c.getReturnType();
3188
+ if (returnType) {
3189
+ const props = returnType.getProperties();
3190
+ const valueType = props.length === 1 && props[0].name === "value" && typeChecker.getPropertyOfType(returnType, "value") || void 0;
3191
+ code += "<return ";
3192
+ if (valueType) {
3193
+ code += `= ${castType(
3194
+ typeChecker.typeToString(typeChecker.getTypeOfSymbol(valueType))
3195
+ )}`;
3196
+ } else {
3197
+ code += `...${castType(typeChecker.typeToString(returnType))}`;
3198
+ }
3199
+ code += `/>${nlChar}`;
3200
+ }
3201
+ }
3202
+ return { code };
3203
+ }
3204
+ };
3205
+ function isImportComponentType(statement) {
3206
+ var _a, _b;
3207
+ return ts.isImportDeclaration(statement) && ((_b = (_a = statement.importClause) == null ? void 0 : _a.name) == null ? void 0 : _b.escapedText) === "Component";
3208
+ }
3209
+ function isExportInputTypeAsComponentInput(statement) {
3210
+ return ts.isTypeAliasDeclaration(statement) && statement.name.escapedText === "Input" && ts.isIndexedAccessTypeNode(statement.type) && ts.isTypeReferenceNode(statement.type.objectType) && ts.isIdentifier(statement.type.objectType.typeName) && statement.type.objectType.typeName.escapedText === "Component" && ts.isLiteralTypeNode(statement.type.indexType) && ts.isStringLiteral(statement.type.indexType.literal) && statement.type.indexType.literal.text === "input";
3211
+ }
3212
+ function isExportEmptyInputType(statement) {
3213
+ return ts.isTypeAliasDeclaration(statement) && statement.name.escapedText === "Input" && ts.isTypeLiteralNode(statement.type) && !statement.typeParameters && statement.type.members.length === 0 || ts.isInterfaceDeclaration(statement) && statement.name.escapedText === "Input" && !statement.typeParameters && statement.members.length === 0;
3214
+ }
3215
+ function isExportComponentType(statement) {
3216
+ return ts.isExportDeclaration(statement) && statement.exportClause && ts.isNamedExports(statement.exportClause) && statement.exportClause.elements.length === 1 && statement.exportClause.elements[0].name.escapedText === "Component";
3217
+ }
3218
+ function isVariableStatementForName(statement, name) {
3219
+ if (ts.isVariableStatement(statement)) {
3220
+ for (const decl of statement.declarationList.declarations) {
3221
+ if (ts.isIdentifier(decl.name) && decl.name.escapedText === name) {
3222
+ return true;
3223
+ }
3224
+ }
3225
+ }
3226
+ }
3227
+ }
3228
+ };
3229
+ function castType(type) {
3230
+ if (type === "any") {
3231
+ return "1 as any";
3232
+ }
3233
+ return `(1 as any as ${type})`;
3234
+ }
3235
+
3236
+ // src/processors/index.ts
3237
+ var extensions = [marko_default.extension];
3238
+ function create(options) {
3239
+ return {
3240
+ [marko_default.extension]: marko_default.create(options)
3241
+ };
3242
+ }
3243
+ function has(fileName) {
3244
+ const ext = getExt(fileName);
3245
+ return !!(ext && extensions.includes(ext));
3246
+ }
3247
+
3248
+ // src/util/is-definition-file.ts
3249
+ function isDefinitionFile(fileName) {
3250
+ return /\.d\.[^.]+$/.test(fileName);
3251
+ }
2818
3252
  export {
2819
3253
  NodeType,
3254
+ processors_exports as Processors,
3255
+ project_exports as Project,
2820
3256
  ScriptLang,
2821
3257
  UNFINISHED,
2822
3258
  extractScript,
2823
3259
  extractStyle,
3260
+ getExt,
2824
3261
  getLines,
2825
3262
  getLocation,
2826
3263
  getPosition,
3264
+ isDefinitionFile,
2827
3265
  parse
2828
3266
  };
@@ -0,0 +1,36 @@
1
+ import type ts from "typescript/lib/tsserverlibrary";
2
+ import { Extracted } from "../util/extractor";
3
+ export type ProcessorExtension = `.${string}`;
4
+ export interface ProcessorConfig {
5
+ extension: ProcessorExtension;
6
+ create(options: CreateProcessorOptions): Processor;
7
+ }
8
+ export interface CreateProcessorOptions {
9
+ ts: typeof ts;
10
+ host: ts.ModuleResolutionHost;
11
+ configFile: string | undefined;
12
+ }
13
+ export interface Processor {
14
+ getRootNames?(): string[];
15
+ getScriptExtension(fileName: string): ts.Extension;
16
+ getScriptKind(fileName: string): ts.ScriptKind;
17
+ extract(fileName: string, code: string): Extracted;
18
+ print(context: PrintContext): {
19
+ code: string;
20
+ map?: any;
21
+ };
22
+ printTypes(context: PrintContext): {
23
+ code: string;
24
+ map?: any;
25
+ };
26
+ }
27
+ export interface PrintContext {
28
+ extracted: Extracted;
29
+ printer: ts.Printer;
30
+ sourceFile: ts.SourceFile;
31
+ typeChecker: ts.TypeChecker;
32
+ formatSettings: Required<ts.FormatCodeSettings>;
33
+ }
34
+ export declare const extensions: `.${string}`[];
35
+ export declare function create(options: Parameters<ProcessorConfig["create"]>[0]): Record<`.${string}`, Processor>;
36
+ export declare function has(fileName: string): boolean;
@@ -0,0 +1,18 @@
1
+ import type ts from "typescript/lib/tsserverlibrary";
2
+ declare const _default: {
3
+ extension: ".marko";
4
+ create({ ts, host, configFile }: import(".").CreateProcessorOptions): {
5
+ getRootNames(): string[];
6
+ getScriptExtension(fileName: string): ts.Extension.Ts | ts.Extension.Js;
7
+ getScriptKind(fileName: string): ts.ScriptKind.JS | ts.ScriptKind.TS;
8
+ extract(fileName: string, code: string): import("..").Extracted;
9
+ print({ extracted: { parsed } }: import(".").PrintContext): {
10
+ code: string;
11
+ map: import("magic-string").SourceMap;
12
+ };
13
+ printTypes({ printer, typeChecker, sourceFile, formatSettings }: import(".").PrintContext): {
14
+ code: string;
15
+ };
16
+ };
17
+ };
18
+ export default _default;
@@ -16,6 +16,7 @@ export declare class Extractor {
16
16
  }
17
17
  export declare class Extracted {
18
18
  #private;
19
+ parsed: Parsed;
19
20
  constructor(parsed: Parsed, generated: string, tokens: Token[]);
20
21
  sourceOffsetAt(generatedOffset: number): number | undefined;
21
22
  sourcePositionAt(generatedOffset: number): Position | undefined;
@@ -0,0 +1 @@
1
+ export declare function getExt(fileName: string): `.${string}` | undefined;
@@ -0,0 +1 @@
1
+ export declare function isDefinitionFile(fileName: string): boolean;
@@ -0,0 +1,78 @@
1
+ /// <reference types="node" />
2
+ import type TS from "typescript/lib/tsserverlibrary";
3
+ import type { TaglibLookup } from "@marko/babel-utils";
4
+ import * as defaultCompiler from "@marko/compiler";
5
+ import { ScriptLang } from "../extractors/script";
6
+ export interface Meta {
7
+ compiler: typeof defaultCompiler;
8
+ config: Omit<defaultCompiler.Config, "cache" | "translator"> & {
9
+ cache: Map<any, any>;
10
+ translator: {
11
+ runtimeTypes?: string;
12
+ [x: string]: unknown;
13
+ };
14
+ };
15
+ }
16
+ interface TypeLibs {
17
+ internalTypesFile: string | undefined;
18
+ markoRunTypesFile: string | undefined;
19
+ markoRunGeneratedTypesFile: string | undefined;
20
+ markoTypesFile: string | undefined;
21
+ markoTypesCode: string | undefined;
22
+ }
23
+ declare const defaultTypeLibs: Partial<TypeLibs>;
24
+ export declare function getCompiler(dir?: string): typeof defaultCompiler;
25
+ export declare function getCache(dir?: string): Map<any, any>;
26
+ export declare function getConfig(dir?: string): Omit<{
27
+ output?: "source" | "html" | "dom" | "hydrate" | "migrate" | undefined;
28
+ stripTypes?: boolean | undefined;
29
+ runtimeId?: string | null | undefined;
30
+ ast?: boolean | undefined;
31
+ code?: boolean | undefined;
32
+ writeVersionComment?: boolean | undefined;
33
+ ignoreUnrecognizedTags?: boolean | undefined;
34
+ sourceMaps?: boolean | "inline" | "both" | undefined;
35
+ translator?: any;
36
+ fileSystem?: typeof import("fs") | undefined;
37
+ modules?: "esm" | "cjs" | undefined;
38
+ resolveVirtualDependency?: ((filename: string, dep: {
39
+ virtualPath: string;
40
+ code: string;
41
+ map?: any;
42
+ }) => string) | null | undefined;
43
+ hydrateIncludeImports?: RegExp | ((request: string) => boolean) | undefined;
44
+ optimize?: boolean | undefined;
45
+ cache?: Map<unknown, unknown> | undefined;
46
+ hot?: boolean | undefined;
47
+ meta?: boolean | undefined;
48
+ babelConfig?: {
49
+ [x: string]: unknown;
50
+ ast?: boolean | null | undefined;
51
+ code?: boolean | null | undefined;
52
+ comments?: boolean | null | undefined;
53
+ compact?: boolean | "auto" | null | undefined;
54
+ caller?: {
55
+ [x: string]: unknown;
56
+ name?: string | undefined;
57
+ } | undefined;
58
+ minified?: boolean | null | undefined;
59
+ } | undefined;
60
+ }, "cache" | "translator"> & {
61
+ cache: Map<any, any>;
62
+ translator: {
63
+ [x: string]: unknown;
64
+ runtimeTypes?: string | undefined;
65
+ };
66
+ };
67
+ export declare function getTagLookup(dir: string): TaglibLookup;
68
+ export declare function getTypeLibs(rootDir: string, ts: typeof TS, host: TS.ModuleResolutionHost): {
69
+ internalTypesFile: string;
70
+ markoRunTypesFile: string | undefined;
71
+ markoRunGeneratedTypesFile: string | undefined;
72
+ markoTypesFile: string;
73
+ markoTypesCode: string;
74
+ };
75
+ export declare function getScriptLang(fileName: string, defaultScriptLang: ScriptLang, ts: typeof TS, host: TS.ModuleResolutionHost): ScriptLang;
76
+ export declare function clearCaches(): void;
77
+ export declare function setDefaultTypePaths(defaults: typeof defaultTypeLibs): void;
78
+ export {};
package/package.json CHANGED
@@ -1,23 +1,25 @@
1
1
  {
2
2
  "name": "@marko/language-tools",
3
3
  "description": "Marko Language Tools",
4
- "version": "1.0.3",
4
+ "version": "2.0.1",
5
5
  "bugs": "https://github.com/marko-js/language-server/issues/new?template=Bug_report.md",
6
6
  "dependencies": {
7
7
  "@babel/helper-validator-identifier": "^7.19.1",
8
- "@babel/parser": "^7.21.3",
8
+ "@babel/parser": "^7.21.4",
9
+ "@marko/compiler": "5.27.4",
10
+ "@marko/translator-default": "5.25.4",
9
11
  "htmljs-parser": "^5.4.3",
10
12
  "relative-import-path": "^1.0.0"
11
13
  },
12
14
  "devDependencies": {
13
- "@babel/code-frame": "^7.18.6",
14
- "@marko/compiler": "^5.27.1",
15
+ "@babel/code-frame": "^7.21.4",
16
+ "@marko/compiler": "^5.27.4",
15
17
  "@types/babel__code-frame": "^7.0.3",
16
18
  "@types/babel__helper-validator-identifier": "^7.15.0",
17
19
  "@typescript/vfs": "^1.4.0",
18
- "marko": "^5.25.1",
20
+ "marko": "^5.25.4",
19
21
  "mitata": "^0.1.6",
20
- "tsx": "^3.12.5"
22
+ "tsx": "^3.12.6"
21
23
  },
22
24
  "exports": {
23
25
  ".": {