@analogjs/language-server 0.1.6 → 0.2.0

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.
package/out/index.js CHANGED
@@ -1,24 +1,43 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const languagePlugin_1 = require("./languagePlugin");
4
3
  const volar_service_emmet_1 = require("volar-service-emmet");
5
4
  const volar_service_html_1 = require("volar-service-html");
6
5
  const volar_service_css_1 = require("volar-service-css");
7
6
  const volar_service_typescript_1 = require("volar-service-typescript");
8
7
  const node_1 = require("@volar/language-server/node");
8
+ const vscode_uri_1 = require("vscode-uri");
9
+ const routeScanner_1 = require("./routeScanner");
10
+ const routingPlugin_1 = require("./plugins/routingPlugin");
9
11
  const connection = (0, node_1.createConnection)();
10
12
  const server = (0, node_1.createServer)(connection);
11
13
  connection.listen();
12
14
  connection.onInitialize(params => {
13
15
  const tsdk = (0, node_1.loadTsdkByPath)(params.initializationOptions.typescript.tsdk, params.locale);
14
- return server.initialize(params, (0, node_1.createTypeScriptProject)(tsdk.typescript, tsdk.diagnosticMessages, () => ({
15
- languagePlugins: [languagePlugin_1.analogLanguagePlugin]
16
- })), [
16
+ // Initialize route scanner with the first workspace folder
17
+ const workspaceFolders = params.workspaceFolders ?? [];
18
+ let scanner;
19
+ if (workspaceFolders.length > 0) {
20
+ const rootUri = vscode_uri_1.URI.parse(workspaceFolders[0].uri);
21
+ scanner = new routeScanner_1.RouteScanner(rootUri.fsPath);
22
+ scanner.scan();
23
+ }
24
+ const servicePlugins = [
17
25
  (0, volar_service_html_1.create)(),
18
26
  (0, volar_service_css_1.create)(),
19
27
  (0, volar_service_emmet_1.create)(),
20
28
  ...(0, volar_service_typescript_1.create)(tsdk.typescript),
21
- ]);
29
+ ];
30
+ if (scanner) {
31
+ servicePlugins.push((0, routingPlugin_1.createRoutingPlugin)(scanner));
32
+ }
33
+ return server.initialize(params, (0, node_1.createTypeScriptProject)(tsdk.typescript, tsdk.diagnosticMessages, () => ({
34
+ languagePlugins: []
35
+ })), servicePlugins);
36
+ });
37
+ // Re-scan routes when watched files change
38
+ connection.onDidChangeWatchedFiles(() => {
39
+ // Scanner re-scan is triggered by the file watcher
40
+ // This will be enhanced with incremental updates
22
41
  });
23
42
  connection.onInitialized(server.initialized);
24
43
  connection.onShutdown(server.shutdown);
@@ -0,0 +1,7 @@
1
+ import type { LanguageServicePlugin } from '@volar/language-service';
2
+ import type { RouteScanner } from '../routeScanner';
3
+ /**
4
+ * Creates a Volar language service plugin that provides
5
+ * route path completions and go-to-definition for Analog's file-based routing.
6
+ */
7
+ export declare function createRoutingPlugin(scanner: RouteScanner): LanguageServicePlugin;
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.createRoutingPlugin = void 0;
27
+ const vscode = __importStar(require("vscode-languageserver-protocol"));
28
+ const vscode_uri_1 = require("vscode-uri");
29
+ /**
30
+ * Check if a position is inside a string literal and return the string content.
31
+ * Handles both single and double quoted strings.
32
+ */
33
+ function getStringAtPosition(document, position) {
34
+ const line = document.getText(vscode.Range.create(position.line, 0, position.line + 1, 0));
35
+ const offset = position.character;
36
+ // Find the string boundaries around the cursor
37
+ let start = -1;
38
+ let end = -1;
39
+ let quote = '';
40
+ for (let i = offset - 1; i >= 0; i--) {
41
+ if ((line[i] === '"' || line[i] === "'") && (i === 0 || line[i - 1] !== '\\')) {
42
+ start = i;
43
+ quote = line[i];
44
+ break;
45
+ }
46
+ }
47
+ if (start === -1 || !quote)
48
+ return undefined;
49
+ for (let i = offset; i < line.length; i++) {
50
+ if (line[i] === quote && line[i - 1] !== '\\') {
51
+ end = i;
52
+ break;
53
+ }
54
+ }
55
+ if (end === -1)
56
+ return undefined;
57
+ const value = line.substring(start + 1, end);
58
+ const range = vscode.Range.create(position.line, start + 1, position.line, end);
59
+ return { value, range };
60
+ }
61
+ /**
62
+ * Check if the string at position is in a routing context.
63
+ * Looks for routerLink, navigate, navigateByUrl, route(), etc.
64
+ */
65
+ function isRoutingContext(document, position) {
66
+ const line = document.getText(vscode.Range.create(position.line, 0, position.line + 1, 0));
67
+ // Check for common routing patterns in the line
68
+ return /routerLink|\.navigate\(|\.navigateByUrl\(|route\(|injectNavigate|injectNavigateByUrl|routerLink\s*=/.test(line);
69
+ }
70
+ /**
71
+ * Creates a Volar language service plugin that provides
72
+ * route path completions and go-to-definition for Analog's file-based routing.
73
+ */
74
+ function createRoutingPlugin(scanner) {
75
+ return {
76
+ name: 'analog-routing',
77
+ capabilities: {
78
+ completionProvider: {
79
+ triggerCharacters: ["'", '"', '/'],
80
+ },
81
+ definitionProvider: true,
82
+ },
83
+ create() {
84
+ return {
85
+ provideCompletionItems(document, position) {
86
+ if (!isRoutingContext(document, position)) {
87
+ return undefined;
88
+ }
89
+ const stringInfo = getStringAtPosition(document, position);
90
+ if (!stringInfo)
91
+ return undefined;
92
+ const routes = scanner.getRoutes();
93
+ if (routes.length === 0)
94
+ return undefined;
95
+ const items = routes
96
+ .filter((route) => !route.isCatchAll)
97
+ .map((route) => {
98
+ const item = {
99
+ label: route.urlPath,
100
+ kind: vscode.CompletionItemKind.File,
101
+ detail: route.filePath.replace(/^.*\/src\//, 'src/'),
102
+ sortText: route.params.length > 0 ? '1' : '0',
103
+ };
104
+ if (route.params.length > 0) {
105
+ item.documentation = {
106
+ kind: vscode.MarkupKind.Markdown,
107
+ value: `**Parameters:** ${route.params.map((p) => '`:' + p + '`').join(', ')}`,
108
+ };
109
+ }
110
+ if (route.serverFilePath) {
111
+ const doc = item.documentation;
112
+ const serverDetail = `\n\nHas server loader: \`${route.serverFilePath.replace(/^.*\/src\//, 'src/')}\``;
113
+ if (typeof doc === 'object' && doc.kind === vscode.MarkupKind.Markdown) {
114
+ doc.value += serverDetail;
115
+ }
116
+ else {
117
+ item.documentation = {
118
+ kind: vscode.MarkupKind.Markdown,
119
+ value: serverDetail.trim(),
120
+ };
121
+ }
122
+ }
123
+ return item;
124
+ });
125
+ return {
126
+ isIncomplete: false,
127
+ items,
128
+ };
129
+ },
130
+ provideDefinition(document, position) {
131
+ const stringInfo = getStringAtPosition(document, position);
132
+ if (!stringInfo)
133
+ return undefined;
134
+ const value = stringInfo.value;
135
+ if (!value.startsWith('/'))
136
+ return undefined;
137
+ const matches = scanner.findByUrlString(value);
138
+ if (matches.length === 0)
139
+ return undefined;
140
+ return matches.map((route) => vscode.LocationLink.create(vscode_uri_1.URI.file(route.filePath).toString(), vscode.Range.create(0, 0, 0, 0), vscode.Range.create(0, 0, 0, 0), stringInfo.range));
141
+ },
142
+ };
143
+ },
144
+ };
145
+ }
146
+ exports.createRoutingPlugin = createRoutingPlugin;
147
+ //# sourceMappingURL=routingPlugin.js.map
@@ -0,0 +1,41 @@
1
+ export interface RouteInfo {
2
+ /** URL path, e.g. "/products/:productId" */
3
+ urlPath: string;
4
+ /** Absolute path to the .page.ts file */
5
+ filePath: string;
6
+ /** Absolute path to the paired .server.ts file, if it exists */
7
+ serverFilePath?: string;
8
+ /** Dynamic parameter names extracted from the path */
9
+ params: string[];
10
+ /** True if this route uses a catch-all pattern */
11
+ isCatchAll: boolean;
12
+ }
13
+ /**
14
+ * Scans the workspace for Analog page files and builds a route map.
15
+ */
16
+ export declare class RouteScanner {
17
+ private routes;
18
+ private workspaceRoot;
19
+ constructor(workspaceRoot: string);
20
+ /**
21
+ * Perform initial scan of the pages directory.
22
+ */
23
+ scan(): void;
24
+ /**
25
+ * Get all discovered routes.
26
+ */
27
+ getRoutes(): RouteInfo[];
28
+ /**
29
+ * Find a route by its URL path.
30
+ */
31
+ findByUrlPath(urlPath: string): RouteInfo | undefined;
32
+ /**
33
+ * Get the paired .server.ts file for a .page.ts file, or vice versa.
34
+ */
35
+ getPairedFile(filePath: string): string | undefined;
36
+ /**
37
+ * Find routes whose URL path matches a given string (for go-to-definition).
38
+ * Matches both exact paths and parameterized patterns.
39
+ */
40
+ findByUrlString(urlString: string): RouteInfo[];
41
+ }
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.RouteScanner = void 0;
27
+ const fs = __importStar(require("node:fs"));
28
+ const tinyglobby_1 = require("tinyglobby");
29
+ /**
30
+ * Converts a page filename to a raw path segment.
31
+ * Adapted from @analogjs/router routes.ts toRawPath().
32
+ */
33
+ function toRawPath(filename) {
34
+ return filename
35
+ .replace(/^(?:[a-zA-Z]:[\\/])?(.*?)[\\/](?:routes|pages)[\\/]|(?:[\\/](?:app[\\/](?:routes|pages)|src[\\/]content)[\\/])|(\.page\.(js|ts)$)|(\.(ts|md)$)/g, '')
36
+ .replace(/\[\[\.\.\.([^\]]+)\]\]/g, '(opt-$1)')
37
+ .replace(/\[\.{3}.+\]/, '**')
38
+ .replace(/\[([^\]]+)\]/g, ':$1');
39
+ }
40
+ /**
41
+ * Converts a raw segment to a clean URL segment.
42
+ * Adapted from @analogjs/router routes.ts toSegment().
43
+ */
44
+ function toSegment(rawSegment) {
45
+ return rawSegment
46
+ .replace(/index|\(.*?\)/g, '')
47
+ .replace(/\.|\/+/g, '/')
48
+ .replace(/^\/+|\/+$/g, '');
49
+ }
50
+ /**
51
+ * Convert a page file path to a URL path.
52
+ */
53
+ function fileToUrlPath(filePath) {
54
+ const raw = toRawPath(filePath);
55
+ const segments = raw.split('/').map(toSegment).filter(Boolean);
56
+ return '/' + segments.join('/');
57
+ }
58
+ /**
59
+ * Extract dynamic parameter names from a URL path.
60
+ */
61
+ function extractParams(urlPath) {
62
+ const params = [];
63
+ for (const match of urlPath.matchAll(/:([^/]+)/g)) {
64
+ params.push(match[1]);
65
+ }
66
+ return params;
67
+ }
68
+ /**
69
+ * Scans the workspace for Analog page files and builds a route map.
70
+ */
71
+ class RouteScanner {
72
+ constructor(workspaceRoot) {
73
+ this.routes = [];
74
+ this.workspaceRoot = workspaceRoot;
75
+ }
76
+ /**
77
+ * Perform initial scan of the pages directory.
78
+ */
79
+ scan() {
80
+ const pageFiles = (0, tinyglobby_1.globSync)(['src/app/pages/**/*.page.ts'], {
81
+ cwd: this.workspaceRoot,
82
+ absolute: true,
83
+ });
84
+ this.routes = pageFiles.map((filePath) => {
85
+ const urlPath = fileToUrlPath(filePath);
86
+ const serverFilePath = filePath.replace(/\.page\.ts$/, '.server.ts');
87
+ const hasServer = fs.existsSync(serverFilePath);
88
+ return {
89
+ urlPath,
90
+ filePath,
91
+ serverFilePath: hasServer ? serverFilePath : undefined,
92
+ params: extractParams(urlPath),
93
+ isCatchAll: urlPath.includes('**'),
94
+ };
95
+ });
96
+ }
97
+ /**
98
+ * Get all discovered routes.
99
+ */
100
+ getRoutes() {
101
+ return this.routes;
102
+ }
103
+ /**
104
+ * Find a route by its URL path.
105
+ */
106
+ findByUrlPath(urlPath) {
107
+ return this.routes.find((r) => r.urlPath === urlPath);
108
+ }
109
+ /**
110
+ * Get the paired .server.ts file for a .page.ts file, or vice versa.
111
+ */
112
+ getPairedFile(filePath) {
113
+ if (filePath.endsWith('.page.ts')) {
114
+ const serverPath = filePath.replace(/\.page\.ts$/, '.server.ts');
115
+ return fs.existsSync(serverPath) ? serverPath : undefined;
116
+ }
117
+ if (filePath.endsWith('.server.ts')) {
118
+ const pagePath = filePath.replace(/\.server\.ts$/, '.page.ts');
119
+ return fs.existsSync(pagePath) ? pagePath : undefined;
120
+ }
121
+ return undefined;
122
+ }
123
+ /**
124
+ * Find routes whose URL path matches a given string (for go-to-definition).
125
+ * Matches both exact paths and parameterized patterns.
126
+ */
127
+ findByUrlString(urlString) {
128
+ const normalized = urlString.startsWith('/') ? urlString : '/' + urlString;
129
+ const exact = this.routes.filter((r) => r.urlPath === normalized);
130
+ if (exact.length > 0)
131
+ return exact;
132
+ // Try matching parameterized routes: "/products/123" against "/products/:productId"
133
+ return this.routes.filter((r) => {
134
+ if (r.isCatchAll)
135
+ return false;
136
+ const routeParts = r.urlPath.split('/');
137
+ const urlParts = normalized.split('/');
138
+ if (routeParts.length !== urlParts.length)
139
+ return false;
140
+ return routeParts.every((part, i) => part.startsWith(':') || part === urlParts[i]);
141
+ });
142
+ }
143
+ }
144
+ exports.RouteScanner = RouteScanner;
145
+ //# sourceMappingURL=routeScanner.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@analogjs/language-server",
3
3
  "description": "LSP server for AnalogJS Language Service",
4
- "version": "0.1.6",
4
+ "version": "0.2.0",
5
5
  "main": "out/index.js",
6
6
  "license": "MIT",
7
7
  "scripts": {
@@ -20,14 +20,16 @@
20
20
  "analog-language-server": "./bin/analog-language-server.js"
21
21
  },
22
22
  "dependencies": {
23
- "@volar/language-core": "~2.4.0",
24
- "@volar/language-server": "~2.4.0",
25
- "@volar/language-service": "~2.4.0",
26
- "volar-service-css": "volar-2.4",
27
- "volar-service-emmet": "volar-2.4",
28
- "volar-service-html": "volar-2.4",
29
- "volar-service-typescript": "volar-2.4",
30
- "vscode-html-languageservice": "^5.2.0",
23
+ "@volar/language-core": "~2.4.28",
24
+ "@volar/language-server": "~2.4.28",
25
+ "@volar/language-service": "~2.4.28",
26
+ "volar-service-css": "0.0.70",
27
+ "volar-service-emmet": "0.0.70",
28
+ "volar-service-html": "0.0.70",
29
+ "volar-service-typescript": "0.0.70",
30
+ "tinyglobby": "^0.2.0",
31
+ "vscode-languageserver-protocol": "^3.17.5",
32
+ "vscode-languageserver-textdocument": "^1.0.11",
31
33
  "vscode-uri": "^3.0.8"
32
34
  },
33
35
  "publishConfig": {
package/out/index.d.ts DELETED
@@ -1 +0,0 @@
1
- export {};
@@ -1,7 +0,0 @@
1
- import { type LanguagePlugin, type VirtualCode } from "@volar/language-core";
2
- import * as html from "vscode-html-languageservice";
3
- import { URI } from "vscode-uri";
4
- export declare const analogLanguagePlugin: LanguagePlugin<URI>;
5
- export interface AnalogVirtualCode extends VirtualCode {
6
- htmlDocument: html.HTMLDocument;
7
- }
@@ -1,251 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.analogLanguagePlugin = void 0;
27
- const language_core_1 = require("@volar/language-core");
28
- const html = __importStar(require("vscode-html-languageservice"));
29
- exports.analogLanguagePlugin = {
30
- getLanguageId(uri) {
31
- if (uri.path.endsWith(".analog") || uri.path.endsWith(".ag")) {
32
- return "analog";
33
- }
34
- },
35
- createVirtualCode(_uri, languageId, snapshot) {
36
- if (languageId === "analog") {
37
- return createAnalogCode(snapshot);
38
- }
39
- },
40
- typescript: {
41
- extraFileExtensions: [
42
- {
43
- extension: "analog",
44
- isMixedContent: true,
45
- scriptKind: 3,
46
- },
47
- ],
48
- getServiceScript() {
49
- return undefined;
50
- },
51
- getExtraServiceScripts(fileName, root) {
52
- const scripts = [];
53
- for (const code of (0, language_core_1.forEachEmbeddedCode)(root)) {
54
- if (code.languageId === "javascript") {
55
- scripts.push({
56
- fileName: fileName + "." + code.id + ".js",
57
- code,
58
- extension: ".js",
59
- scriptKind: 1,
60
- });
61
- }
62
- else if (code.languageId === "typescript") {
63
- scripts.push({
64
- fileName: fileName + "." + code.id + ".ts",
65
- code,
66
- extension: ".ts",
67
- scriptKind: 3,
68
- });
69
- }
70
- else if (code.languageId === "typescriptreact") {
71
- scripts.push({
72
- fileName: fileName + "." + code.id + ".tsx",
73
- code,
74
- extension: ".ts",
75
- scriptKind: 4,
76
- });
77
- }
78
- }
79
- return scripts;
80
- },
81
- },
82
- };
83
- const htmlLs = html.getLanguageService();
84
- function createAnalogCode(snapshot) {
85
- const document = html.TextDocument.create("", "html", 0, snapshot.getText(0, snapshot.getLength()));
86
- const htmlDocument = htmlLs.parseHTMLDocument(document);
87
- return {
88
- id: "root",
89
- languageId: "html",
90
- snapshot,
91
- mappings: [
92
- {
93
- sourceOffsets: [0],
94
- generatedOffsets: [0],
95
- lengths: [snapshot.getLength()],
96
- data: {
97
- completion: true,
98
- format: true,
99
- navigation: true,
100
- semantic: true,
101
- structure: true,
102
- verification: true,
103
- },
104
- },
105
- ],
106
- embeddedCodes: [...createEmbeddedCodes()],
107
- htmlDocument,
108
- };
109
- function* createEmbeddedCodes() {
110
- let styles = 0;
111
- let scripts = 0;
112
- let langs = 0;
113
- for (const root of htmlDocument.roots) {
114
- if (root.tag === "style" &&
115
- root.startTagEnd !== undefined &&
116
- root.endTagStart !== undefined) {
117
- const styleText = snapshot.getText(root.startTagEnd, root.endTagStart);
118
- yield {
119
- id: "style_" + styles++,
120
- languageId: "css",
121
- snapshot: {
122
- getText: (start, end) => styleText.substring(start, end),
123
- getLength: () => styleText.length,
124
- getChangeRange: () => undefined,
125
- },
126
- mappings: [
127
- {
128
- sourceOffsets: [root.startTagEnd],
129
- generatedOffsets: [0],
130
- lengths: [styleText.length],
131
- data: {
132
- completion: true,
133
- format: true,
134
- navigation: true,
135
- semantic: true,
136
- structure: true,
137
- verification: true,
138
- },
139
- },
140
- ],
141
- embeddedCodes: [],
142
- };
143
- }
144
- if (root.tag === "script" &&
145
- root.startTagEnd !== undefined &&
146
- root.endTagStart !== undefined) {
147
- const text = snapshot.getText(root.startTagEnd, root.endTagStart).replace(/(with(((\n|\s)*).*)})/gm, function (_, _$1, $2) {
148
- // replace "with { analog: 'imports' }" with "/**with { analog: 'imports' }*/"
149
- // so its not evaluated inside the script tag
150
- return `/**${$2}*/`;
151
- });
152
- const lang = root.attributes?.lang;
153
- const isTs = lang === "ts" || lang === '"ts"' || lang === "'ts'";
154
- yield {
155
- id: "script_" + scripts++,
156
- languageId: isTs ? "typescript" : "javascript",
157
- snapshot: {
158
- getText: (start, end) => `${text.substring(start, end)}
159
-
160
- type AnalogComponentMetadata = Omit<import('@angular/core').Component, "template" |
161
- "standalone" |
162
- "changeDetection" |
163
- "styles" |
164
- "outputs" |
165
- "inputs"> & { exposes?: any[] };
166
-
167
- /**
168
- * Defines additional metadata for the component such as the
169
- * selector, providers, and more.
170
- */
171
- declare function defineMetadata(metadata: AnalogComponentMetadata): void;
172
-
173
- /**
174
- * Defines the lifecycle hook(ngOnInit) that is called when the
175
- * component is initialized.
176
- */
177
- declare function onInit(initFn: () => void): void;
178
-
179
- /**
180
- * Defines the lifecycle hook(ngOnDestroy) that is called when the
181
- * component is destroyed.
182
- */
183
- declare function onDestroy(destroyFn: () => void): void;`,
184
- getLength: () => text.length,
185
- getChangeRange: () => undefined,
186
- },
187
- mappings: [
188
- {
189
- sourceOffsets: [root.startTagEnd],
190
- generatedOffsets: [0],
191
- lengths: [text.length],
192
- data: {
193
- completion: true,
194
- format: true,
195
- navigation: true,
196
- semantic: true,
197
- structure: true,
198
- verification: true,
199
- },
200
- },
201
- ],
202
- embeddedCodes: [],
203
- };
204
- }
205
- if (root.tag === "template" &&
206
- root.startTagEnd !== undefined &&
207
- root.endTagStart !== undefined) {
208
- const text = snapshot.getText(root.startTagEnd, root.endTagStart);
209
- const lang = root.attributes?.lang;
210
- const isMd = lang === "md" || lang === '"md"' || lang === "'md'";
211
- yield {
212
- id: "lang_" + langs++,
213
- languageId: isMd ? "markdown" : "html",
214
- snapshot: {
215
- getText: (start, end) => text.substring(start, end),
216
- getLength: () => text.length,
217
- getChangeRange: () => undefined,
218
- },
219
- mappings: [
220
- {
221
- sourceOffsets: [root.startTagEnd],
222
- generatedOffsets: [0],
223
- lengths: [text.length],
224
- data: {
225
- completion: true,
226
- format: true,
227
- navigation: true,
228
- semantic: true,
229
- structure: true,
230
- verification: true,
231
- },
232
- },
233
- ],
234
- embeddedCodes: [
235
- {
236
- id: "lang_" + langs + "_ts",
237
- languageId: "typescript",
238
- snapshot: {
239
- getText: (_start, _end) => `increment();`,
240
- getLength: () => `void increment;`.length,
241
- getChangeRange: () => undefined,
242
- },
243
- mappings: []
244
- }
245
- ],
246
- };
247
- }
248
- }
249
- }
250
- }
251
- //# sourceMappingURL=languagePlugin.js.map