@pandacss/typescript-plugin 2.0.0-beta.9

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/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Chakra Systems Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,207 @@
1
+ // src/service/ast.ts
2
+ import ts from "typescript";
3
+ function findNodeAtPosition(root, position) {
4
+ let found = root;
5
+ const visit = (node) => {
6
+ if (position < node.getStart() || position > node.getEnd()) return;
7
+ found = node;
8
+ node.forEachChild(visit);
9
+ };
10
+ visit(root);
11
+ return found;
12
+ }
13
+ function findEnclosingStringLiteral(root, position) {
14
+ const node = findNodeAtPosition(root, position);
15
+ return ts.isStringLiteralLike(node) ? node : void 0;
16
+ }
17
+ function findEnclosingObjectLiteral(node) {
18
+ let current = node;
19
+ while (current) {
20
+ if (ts.isObjectLiteralExpression(current)) return current;
21
+ current = current.parent;
22
+ }
23
+ return void 0;
24
+ }
25
+ function propertyKeyText(name) {
26
+ return ts.isIdentifier(name) || ts.isStringLiteral(name) ? name.text : void 0;
27
+ }
28
+ function getContainerPath(node) {
29
+ const path = [];
30
+ let current = node;
31
+ while (current) {
32
+ if (ts.isPropertyAssignment(current)) {
33
+ const key = propertyKeyText(current.name);
34
+ if (key !== void 0) path.unshift(key);
35
+ }
36
+ current = current.parent;
37
+ }
38
+ return path[0] === "theme" ? path.slice(1) : path;
39
+ }
40
+ var RECIPE_DEFINE_NAMES = /* @__PURE__ */ new Set(["defineRecipe"]);
41
+ var GLOBAL_STYLES_DEFINE_NAMES = /* @__PURE__ */ new Set(["defineGlobalStyles"]);
42
+ function calleeName(call) {
43
+ return ts.isIdentifier(call.expression) ? call.expression.text : void 0;
44
+ }
45
+ function findEnclosingDefineCall(node) {
46
+ let current = node;
47
+ while (current) {
48
+ if (ts.isCallExpression(current)) {
49
+ const name = calleeName(current);
50
+ const [firstArg] = current.arguments;
51
+ if (name && firstArg && ts.isObjectLiteralExpression(firstArg)) {
52
+ if (RECIPE_DEFINE_NAMES.has(name)) return { kind: "recipe", argument: firstArg };
53
+ if (GLOBAL_STYLES_DEFINE_NAMES.has(name)) return { kind: "global-styles", argument: firstArg };
54
+ }
55
+ }
56
+ current = current.parent;
57
+ }
58
+ return void 0;
59
+ }
60
+ function getLocalPath(root, target) {
61
+ const path = [];
62
+ let current = target;
63
+ while (current !== root) {
64
+ const parent = current.parent;
65
+ if (ts.isPropertyAssignment(parent) && parent.initializer === current) {
66
+ const key = propertyKeyText(parent.name);
67
+ if (key !== void 0) path.unshift(key);
68
+ }
69
+ current = parent;
70
+ }
71
+ return path;
72
+ }
73
+ function toStyleObjectPath(kind, fullPath) {
74
+ if (kind === "global-styles") return fullPath.length >= 1 ? fullPath.slice(1) : void 0;
75
+ if (fullPath[0] === "base") return fullPath.slice(1);
76
+ if (fullPath[0] === "variants" && fullPath.length >= 3) return fullPath.slice(3);
77
+ return void 0;
78
+ }
79
+ function getStyleObjectCursorInfo(sourceFile, position) {
80
+ const node = findNodeAtPosition(sourceFile, position);
81
+ const defineCall = findEnclosingDefineCall(node);
82
+ if (!defineCall) return void 0;
83
+ if (ts.isStringLiteralLike(node)) {
84
+ const fullPath2 = getLocalPath(defineCall.argument, node);
85
+ const propertyPath2 = toStyleObjectPath(defineCall.kind, fullPath2);
86
+ if (!propertyPath2 || propertyPath2.length === 0) return void 0;
87
+ return { existingKeys: [], cursorKind: "value", propertyPath: propertyPath2 };
88
+ }
89
+ const objectLiteral = findEnclosingObjectLiteral(node);
90
+ if (!objectLiteral) return void 0;
91
+ const fullPath = getLocalPath(defineCall.argument, objectLiteral);
92
+ const propertyPath = toStyleObjectPath(defineCall.kind, fullPath);
93
+ if (!propertyPath) return void 0;
94
+ const existingKeys = objectLiteral.properties.filter(ts.isPropertyAssignment).map((property) => propertyKeyText(property.name)).filter((key) => key !== void 0);
95
+ return { existingKeys, cursorKind: "key", propertyPath };
96
+ }
97
+ var SEMANTIC_TOKENS_NAME = "defineSemanticTokens";
98
+ function findEnclosingSemanticTokensCall(node) {
99
+ let current = node;
100
+ while (current) {
101
+ if (ts.isCallExpression(current)) {
102
+ const [firstArg] = current.arguments;
103
+ if (firstArg && ts.isObjectLiteralExpression(firstArg)) {
104
+ const callee = current.expression;
105
+ if (ts.isIdentifier(callee) && callee.text === SEMANTIC_TOKENS_NAME) {
106
+ return { argument: firstArg };
107
+ }
108
+ if (ts.isPropertyAccessExpression(callee) && ts.isIdentifier(callee.expression) && callee.expression.text === SEMANTIC_TOKENS_NAME && ts.isIdentifier(callee.name)) {
109
+ return { argument: firstArg, category: callee.name.text };
110
+ }
111
+ }
112
+ }
113
+ current = current.parent;
114
+ }
115
+ return void 0;
116
+ }
117
+ function isTokenValueObject(objectLiteral) {
118
+ let current = objectLiteral;
119
+ while (true) {
120
+ const parent = current.parent;
121
+ if (!ts.isPropertyAssignment(parent) || parent.initializer !== current) return false;
122
+ if (propertyKeyText(parent.name) === "value") return true;
123
+ current = parent.parent;
124
+ if (!ts.isObjectLiteralExpression(current)) return false;
125
+ }
126
+ }
127
+ function getSemanticTokenCursorInfo(sourceFile, position) {
128
+ const node = findNodeAtPosition(sourceFile, position);
129
+ const objectLiteral = findEnclosingObjectLiteral(node);
130
+ if (!objectLiteral) return void 0;
131
+ const call = findEnclosingSemanticTokensCall(objectLiteral);
132
+ if (!call) return void 0;
133
+ const existingKeys = objectLiteral.properties.filter(ts.isPropertyAssignment).map((property) => propertyKeyText(property.name)).filter((key) => key !== void 0);
134
+ if (objectLiteral === call.argument && !call.category) {
135
+ return { cursorKind: "category", existingKeys };
136
+ }
137
+ if (isTokenValueObject(objectLiteral)) {
138
+ return { cursorKind: "condition", existingKeys };
139
+ }
140
+ return void 0;
141
+ }
142
+
143
+ // src/service/language-service.ts
144
+ import ts2 from "typescript";
145
+ import {
146
+ completeConfigStyleObject,
147
+ completeConfigTokenPath,
148
+ completeSemanticTokenObject,
149
+ findConfigTokenRefAt,
150
+ resolveModuleTarget
151
+ } from "@pandacss/compiler/tooling";
152
+ function literalContentStart(literal) {
153
+ return literal.getStart() + 1;
154
+ }
155
+ function getCompletions(query, context) {
156
+ const sourceFile = query.sourceFile ?? ts2.createSourceFile(query.fileName, query.source, ts2.ScriptTarget.Latest, true);
157
+ const literal = findEnclosingStringLiteral(sourceFile, query.position);
158
+ if (literal) {
159
+ const contentStart = literalContentStart(literal);
160
+ const textPosition = query.position - contentStart;
161
+ const tokenRef = findConfigTokenRefAt(literal.text, textPosition);
162
+ if (tokenRef && textPosition >= tokenRef.pathStart && textPosition <= tokenRef.pathEnd) {
163
+ const prefix2 = literal.text.slice(tokenRef.pathStart, textPosition);
164
+ return completeConfigTokenPath(prefix2, context.specIndex).map((name) => ({ name, kind: "token" }));
165
+ }
166
+ }
167
+ const prefix = literal ? query.source.slice(literalContentStart(literal), query.position) : "";
168
+ const cursorInfo = getStyleObjectCursorInfo(sourceFile, query.position);
169
+ if (cursorInfo) {
170
+ return completeConfigStyleObject({ ...cursorInfo, prefix }, context.specIndex);
171
+ }
172
+ const semanticTokenCursorInfo = getSemanticTokenCursorInfo(sourceFile, query.position);
173
+ if (semanticTokenCursorInfo) {
174
+ return completeSemanticTokenObject({ ...semanticTokenCursorInfo, prefix }, context.specIndex);
175
+ }
176
+ return [];
177
+ }
178
+ function getHover(query, context) {
179
+ const sourceFile = query.sourceFile ?? ts2.createSourceFile(query.fileName, query.source, ts2.ScriptTarget.Latest, true);
180
+ const literal = findEnclosingStringLiteral(sourceFile, query.position);
181
+ if (!literal) return null;
182
+ const contentStart = literalContentStart(literal);
183
+ const tokenRef = findConfigTokenRefAt(literal.text, query.position - contentStart);
184
+ if (!tokenRef) return null;
185
+ const value = context.specIndex.resolveTokenValue(tokenRef.path);
186
+ if (value === void 0) return null;
187
+ return {
188
+ text: `${tokenRef.path}
189
+ ${value}`,
190
+ start: contentStart + tokenRef.start,
191
+ end: contentStart + tokenRef.end
192
+ };
193
+ }
194
+ function resolveModule(specifier, context) {
195
+ return resolveModuleTarget(specifier, context.importMap, { outdir: context.outdir });
196
+ }
197
+
198
+ export {
199
+ findNodeAtPosition,
200
+ findEnclosingStringLiteral,
201
+ getContainerPath,
202
+ findEnclosingDefineCall,
203
+ getStyleObjectCursorInfo,
204
+ getCompletions,
205
+ getHover,
206
+ resolveModule
207
+ };
package/dist/index.cjs ADDED
@@ -0,0 +1,305 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ createPluginModuleFactory: () => createPluginModuleFactory,
34
+ default: () => plugin_default
35
+ });
36
+ module.exports = __toCommonJS(index_exports);
37
+
38
+ // src/plugin/index.ts
39
+ var import_typescript3 = __toESM(require("typescript"), 1);
40
+ var import_tooling2 = require("@pandacss/compiler/tooling");
41
+
42
+ // src/service/language-service.ts
43
+ var import_typescript2 = __toESM(require("typescript"), 1);
44
+ var import_tooling = require("@pandacss/compiler/tooling");
45
+
46
+ // src/service/ast.ts
47
+ var import_typescript = __toESM(require("typescript"), 1);
48
+ function findNodeAtPosition(root, position) {
49
+ let found = root;
50
+ const visit = (node) => {
51
+ if (position < node.getStart() || position > node.getEnd()) return;
52
+ found = node;
53
+ node.forEachChild(visit);
54
+ };
55
+ visit(root);
56
+ return found;
57
+ }
58
+ function findEnclosingStringLiteral(root, position) {
59
+ const node = findNodeAtPosition(root, position);
60
+ return import_typescript.default.isStringLiteralLike(node) ? node : void 0;
61
+ }
62
+ function findEnclosingObjectLiteral(node) {
63
+ let current = node;
64
+ while (current) {
65
+ if (import_typescript.default.isObjectLiteralExpression(current)) return current;
66
+ current = current.parent;
67
+ }
68
+ return void 0;
69
+ }
70
+ function propertyKeyText(name) {
71
+ return import_typescript.default.isIdentifier(name) || import_typescript.default.isStringLiteral(name) ? name.text : void 0;
72
+ }
73
+ var RECIPE_DEFINE_NAMES = /* @__PURE__ */ new Set(["defineRecipe"]);
74
+ var GLOBAL_STYLES_DEFINE_NAMES = /* @__PURE__ */ new Set(["defineGlobalStyles"]);
75
+ function calleeName(call) {
76
+ return import_typescript.default.isIdentifier(call.expression) ? call.expression.text : void 0;
77
+ }
78
+ function findEnclosingDefineCall(node) {
79
+ let current = node;
80
+ while (current) {
81
+ if (import_typescript.default.isCallExpression(current)) {
82
+ const name = calleeName(current);
83
+ const [firstArg] = current.arguments;
84
+ if (name && firstArg && import_typescript.default.isObjectLiteralExpression(firstArg)) {
85
+ if (RECIPE_DEFINE_NAMES.has(name)) return { kind: "recipe", argument: firstArg };
86
+ if (GLOBAL_STYLES_DEFINE_NAMES.has(name)) return { kind: "global-styles", argument: firstArg };
87
+ }
88
+ }
89
+ current = current.parent;
90
+ }
91
+ return void 0;
92
+ }
93
+ function getLocalPath(root, target) {
94
+ const path = [];
95
+ let current = target;
96
+ while (current !== root) {
97
+ const parent = current.parent;
98
+ if (import_typescript.default.isPropertyAssignment(parent) && parent.initializer === current) {
99
+ const key = propertyKeyText(parent.name);
100
+ if (key !== void 0) path.unshift(key);
101
+ }
102
+ current = parent;
103
+ }
104
+ return path;
105
+ }
106
+ function toStyleObjectPath(kind, fullPath) {
107
+ if (kind === "global-styles") return fullPath.length >= 1 ? fullPath.slice(1) : void 0;
108
+ if (fullPath[0] === "base") return fullPath.slice(1);
109
+ if (fullPath[0] === "variants" && fullPath.length >= 3) return fullPath.slice(3);
110
+ return void 0;
111
+ }
112
+ function getStyleObjectCursorInfo(sourceFile, position) {
113
+ const node = findNodeAtPosition(sourceFile, position);
114
+ const defineCall = findEnclosingDefineCall(node);
115
+ if (!defineCall) return void 0;
116
+ if (import_typescript.default.isStringLiteralLike(node)) {
117
+ const fullPath2 = getLocalPath(defineCall.argument, node);
118
+ const propertyPath2 = toStyleObjectPath(defineCall.kind, fullPath2);
119
+ if (!propertyPath2 || propertyPath2.length === 0) return void 0;
120
+ return { existingKeys: [], cursorKind: "value", propertyPath: propertyPath2 };
121
+ }
122
+ const objectLiteral = findEnclosingObjectLiteral(node);
123
+ if (!objectLiteral) return void 0;
124
+ const fullPath = getLocalPath(defineCall.argument, objectLiteral);
125
+ const propertyPath = toStyleObjectPath(defineCall.kind, fullPath);
126
+ if (!propertyPath) return void 0;
127
+ const existingKeys = objectLiteral.properties.filter(import_typescript.default.isPropertyAssignment).map((property) => propertyKeyText(property.name)).filter((key) => key !== void 0);
128
+ return { existingKeys, cursorKind: "key", propertyPath };
129
+ }
130
+ var SEMANTIC_TOKENS_NAME = "defineSemanticTokens";
131
+ function findEnclosingSemanticTokensCall(node) {
132
+ let current = node;
133
+ while (current) {
134
+ if (import_typescript.default.isCallExpression(current)) {
135
+ const [firstArg] = current.arguments;
136
+ if (firstArg && import_typescript.default.isObjectLiteralExpression(firstArg)) {
137
+ const callee = current.expression;
138
+ if (import_typescript.default.isIdentifier(callee) && callee.text === SEMANTIC_TOKENS_NAME) {
139
+ return { argument: firstArg };
140
+ }
141
+ if (import_typescript.default.isPropertyAccessExpression(callee) && import_typescript.default.isIdentifier(callee.expression) && callee.expression.text === SEMANTIC_TOKENS_NAME && import_typescript.default.isIdentifier(callee.name)) {
142
+ return { argument: firstArg, category: callee.name.text };
143
+ }
144
+ }
145
+ }
146
+ current = current.parent;
147
+ }
148
+ return void 0;
149
+ }
150
+ function isTokenValueObject(objectLiteral) {
151
+ let current = objectLiteral;
152
+ while (true) {
153
+ const parent = current.parent;
154
+ if (!import_typescript.default.isPropertyAssignment(parent) || parent.initializer !== current) return false;
155
+ if (propertyKeyText(parent.name) === "value") return true;
156
+ current = parent.parent;
157
+ if (!import_typescript.default.isObjectLiteralExpression(current)) return false;
158
+ }
159
+ }
160
+ function getSemanticTokenCursorInfo(sourceFile, position) {
161
+ const node = findNodeAtPosition(sourceFile, position);
162
+ const objectLiteral = findEnclosingObjectLiteral(node);
163
+ if (!objectLiteral) return void 0;
164
+ const call = findEnclosingSemanticTokensCall(objectLiteral);
165
+ if (!call) return void 0;
166
+ const existingKeys = objectLiteral.properties.filter(import_typescript.default.isPropertyAssignment).map((property) => propertyKeyText(property.name)).filter((key) => key !== void 0);
167
+ if (objectLiteral === call.argument && !call.category) {
168
+ return { cursorKind: "category", existingKeys };
169
+ }
170
+ if (isTokenValueObject(objectLiteral)) {
171
+ return { cursorKind: "condition", existingKeys };
172
+ }
173
+ return void 0;
174
+ }
175
+
176
+ // src/service/language-service.ts
177
+ function literalContentStart(literal) {
178
+ return literal.getStart() + 1;
179
+ }
180
+ function getCompletions(query, context) {
181
+ const sourceFile = query.sourceFile ?? import_typescript2.default.createSourceFile(query.fileName, query.source, import_typescript2.default.ScriptTarget.Latest, true);
182
+ const literal = findEnclosingStringLiteral(sourceFile, query.position);
183
+ if (literal) {
184
+ const contentStart = literalContentStart(literal);
185
+ const textPosition = query.position - contentStart;
186
+ const tokenRef = (0, import_tooling.findConfigTokenRefAt)(literal.text, textPosition);
187
+ if (tokenRef && textPosition >= tokenRef.pathStart && textPosition <= tokenRef.pathEnd) {
188
+ const prefix2 = literal.text.slice(tokenRef.pathStart, textPosition);
189
+ return (0, import_tooling.completeConfigTokenPath)(prefix2, context.specIndex).map((name) => ({ name, kind: "token" }));
190
+ }
191
+ }
192
+ const prefix = literal ? query.source.slice(literalContentStart(literal), query.position) : "";
193
+ const cursorInfo = getStyleObjectCursorInfo(sourceFile, query.position);
194
+ if (cursorInfo) {
195
+ return (0, import_tooling.completeConfigStyleObject)({ ...cursorInfo, prefix }, context.specIndex);
196
+ }
197
+ const semanticTokenCursorInfo = getSemanticTokenCursorInfo(sourceFile, query.position);
198
+ if (semanticTokenCursorInfo) {
199
+ return (0, import_tooling.completeSemanticTokenObject)({ ...semanticTokenCursorInfo, prefix }, context.specIndex);
200
+ }
201
+ return [];
202
+ }
203
+ function getHover(query, context) {
204
+ const sourceFile = query.sourceFile ?? import_typescript2.default.createSourceFile(query.fileName, query.source, import_typescript2.default.ScriptTarget.Latest, true);
205
+ const literal = findEnclosingStringLiteral(sourceFile, query.position);
206
+ if (!literal) return null;
207
+ const contentStart = literalContentStart(literal);
208
+ const tokenRef = (0, import_tooling.findConfigTokenRefAt)(literal.text, query.position - contentStart);
209
+ if (!tokenRef) return null;
210
+ const value = context.specIndex.resolveTokenValue(tokenRef.path);
211
+ if (value === void 0) return null;
212
+ return {
213
+ text: `${tokenRef.path}
214
+ ${value}`,
215
+ start: contentStart + tokenRef.start,
216
+ end: contentStart + tokenRef.end
217
+ };
218
+ }
219
+
220
+ // src/plugin/index.ts
221
+ var EMPTY_IMPORT_MAP = { css: [], recipe: [], pattern: [], jsx: [], tokens: [] };
222
+ var defaultRegistry = new import_tooling2.ProjectRegistry();
223
+ var defaultLoadProject = (key) => defaultRegistry.getProject(key);
224
+ function readScriptText(host, fileName) {
225
+ const snapshot = host.getScriptSnapshot(fileName);
226
+ return snapshot?.getText(0, snapshot.getLength());
227
+ }
228
+ function readDocument(languageService, host, fileName) {
229
+ const sourceFile = languageService.getProgram()?.getSourceFile(fileName);
230
+ if (sourceFile) return { source: sourceFile.text, sourceFile };
231
+ const source = readScriptText(host, fileName);
232
+ return source === void 0 ? void 0 : { source };
233
+ }
234
+ function mergeCompletions(prior, entries) {
235
+ const pandaEntries = entries.map((entry) => ({
236
+ name: entry.name,
237
+ kind: import_typescript3.default.ScriptElementKind.string,
238
+ kindModifiers: "",
239
+ sortText: "0",
240
+ source: "panda-css"
241
+ }));
242
+ if (!prior) {
243
+ return {
244
+ isGlobalCompletion: false,
245
+ isMemberCompletion: false,
246
+ isNewIdentifierLocation: false,
247
+ entries: pandaEntries
248
+ };
249
+ }
250
+ return { ...prior, entries: [...pandaEntries, ...prior.entries] };
251
+ }
252
+ function createPluginModuleFactory(loadProject = defaultLoadProject) {
253
+ return () => {
254
+ function create(info) {
255
+ const proxy = /* @__PURE__ */ Object.create(null);
256
+ for (const key of Object.keys(info.languageService)) {
257
+ const original = info.languageService[key];
258
+ proxy[key] = (...args) => original.apply(info.languageService, args);
259
+ }
260
+ let context;
261
+ const refresh = () => {
262
+ loadProject({ cwd: info.project.getCurrentDirectory() }).then((project) => {
263
+ context = {
264
+ specIndex: new import_tooling2.SpecIndex(project.compiler.spec()),
265
+ importMap: project.compiler.spec().importMap ?? EMPTY_IMPORT_MAP,
266
+ outdir: project.outdir
267
+ };
268
+ }).catch(() => void 0);
269
+ };
270
+ refresh();
271
+ proxy.getCompletionsAtPosition = (fileName, position, options, formattingSettings) => {
272
+ refresh();
273
+ const prior = info.languageService.getCompletionsAtPosition(fileName, position, options, formattingSettings);
274
+ if (!context) return prior;
275
+ const doc = readDocument(info.languageService, info.languageServiceHost, fileName);
276
+ if (!doc) return prior;
277
+ const entries = getCompletions({ fileName, position, ...doc }, context);
278
+ return entries.length === 0 ? prior : mergeCompletions(prior, entries);
279
+ };
280
+ proxy.getQuickInfoAtPosition = (fileName, position) => {
281
+ refresh();
282
+ const prior = info.languageService.getQuickInfoAtPosition(fileName, position);
283
+ if (!context) return prior;
284
+ const doc = readDocument(info.languageService, info.languageServiceHost, fileName);
285
+ if (!doc) return prior;
286
+ const hover = getHover({ fileName, position, ...doc }, context);
287
+ if (!hover) return prior;
288
+ return {
289
+ kind: import_typescript3.default.ScriptElementKind.string,
290
+ kindModifiers: "",
291
+ textSpan: { start: hover.start, length: hover.end - hover.start },
292
+ displayParts: [{ text: hover.text, kind: "text" }]
293
+ };
294
+ };
295
+ return proxy;
296
+ }
297
+ return { create };
298
+ };
299
+ }
300
+ var factory = createPluginModuleFactory();
301
+ var plugin_default = factory;
302
+ // Annotate the CommonJS export names for ESM import in node:
303
+ 0 && (module.exports = {
304
+ createPluginModuleFactory
305
+ });
@@ -0,0 +1,10 @@
1
+ import ts from 'typescript';
2
+ import { Project } from '@pandacss/compiler/tooling';
3
+
4
+ type ProjectLoader = (key: {
5
+ cwd: string;
6
+ }) => Promise<Project>;
7
+ declare function createPluginModuleFactory(loadProject?: ProjectLoader): ts.server.PluginModuleFactory;
8
+ declare const factory: ts.server.PluginModuleFactory;
9
+
10
+ export { type ProjectLoader, createPluginModuleFactory, factory as default };
@@ -0,0 +1,10 @@
1
+ import ts from 'typescript';
2
+ import { Project } from '@pandacss/compiler/tooling';
3
+
4
+ type ProjectLoader = (key: {
5
+ cwd: string;
6
+ }) => Promise<Project>;
7
+ declare function createPluginModuleFactory(loadProject?: ProjectLoader): ts.server.PluginModuleFactory;
8
+ declare const factory: ts.server.PluginModuleFactory;
9
+
10
+ export { type ProjectLoader, createPluginModuleFactory, factory as default };
package/dist/index.js ADDED
@@ -0,0 +1,93 @@
1
+ import {
2
+ getCompletions,
3
+ getHover
4
+ } from "./chunk-IR4B4RGW.js";
5
+
6
+ // src/plugin/index.ts
7
+ import ts from "typescript";
8
+ import { ProjectRegistry, SpecIndex } from "@pandacss/compiler/tooling";
9
+ var EMPTY_IMPORT_MAP = { css: [], recipe: [], pattern: [], jsx: [], tokens: [] };
10
+ var defaultRegistry = new ProjectRegistry();
11
+ var defaultLoadProject = (key) => defaultRegistry.getProject(key);
12
+ function readScriptText(host, fileName) {
13
+ const snapshot = host.getScriptSnapshot(fileName);
14
+ return snapshot?.getText(0, snapshot.getLength());
15
+ }
16
+ function readDocument(languageService, host, fileName) {
17
+ const sourceFile = languageService.getProgram()?.getSourceFile(fileName);
18
+ if (sourceFile) return { source: sourceFile.text, sourceFile };
19
+ const source = readScriptText(host, fileName);
20
+ return source === void 0 ? void 0 : { source };
21
+ }
22
+ function mergeCompletions(prior, entries) {
23
+ const pandaEntries = entries.map((entry) => ({
24
+ name: entry.name,
25
+ kind: ts.ScriptElementKind.string,
26
+ kindModifiers: "",
27
+ sortText: "0",
28
+ source: "panda-css"
29
+ }));
30
+ if (!prior) {
31
+ return {
32
+ isGlobalCompletion: false,
33
+ isMemberCompletion: false,
34
+ isNewIdentifierLocation: false,
35
+ entries: pandaEntries
36
+ };
37
+ }
38
+ return { ...prior, entries: [...pandaEntries, ...prior.entries] };
39
+ }
40
+ function createPluginModuleFactory(loadProject = defaultLoadProject) {
41
+ return () => {
42
+ function create(info) {
43
+ const proxy = /* @__PURE__ */ Object.create(null);
44
+ for (const key of Object.keys(info.languageService)) {
45
+ const original = info.languageService[key];
46
+ proxy[key] = (...args) => original.apply(info.languageService, args);
47
+ }
48
+ let context;
49
+ const refresh = () => {
50
+ loadProject({ cwd: info.project.getCurrentDirectory() }).then((project) => {
51
+ context = {
52
+ specIndex: new SpecIndex(project.compiler.spec()),
53
+ importMap: project.compiler.spec().importMap ?? EMPTY_IMPORT_MAP,
54
+ outdir: project.outdir
55
+ };
56
+ }).catch(() => void 0);
57
+ };
58
+ refresh();
59
+ proxy.getCompletionsAtPosition = (fileName, position, options, formattingSettings) => {
60
+ refresh();
61
+ const prior = info.languageService.getCompletionsAtPosition(fileName, position, options, formattingSettings);
62
+ if (!context) return prior;
63
+ const doc = readDocument(info.languageService, info.languageServiceHost, fileName);
64
+ if (!doc) return prior;
65
+ const entries = getCompletions({ fileName, position, ...doc }, context);
66
+ return entries.length === 0 ? prior : mergeCompletions(prior, entries);
67
+ };
68
+ proxy.getQuickInfoAtPosition = (fileName, position) => {
69
+ refresh();
70
+ const prior = info.languageService.getQuickInfoAtPosition(fileName, position);
71
+ if (!context) return prior;
72
+ const doc = readDocument(info.languageService, info.languageServiceHost, fileName);
73
+ if (!doc) return prior;
74
+ const hover = getHover({ fileName, position, ...doc }, context);
75
+ if (!hover) return prior;
76
+ return {
77
+ kind: ts.ScriptElementKind.string,
78
+ kindModifiers: "",
79
+ textSpan: { start: hover.start, length: hover.end - hover.start },
80
+ displayParts: [{ text: hover.text, kind: "text" }]
81
+ };
82
+ };
83
+ return proxy;
84
+ }
85
+ return { create };
86
+ };
87
+ }
88
+ var factory = createPluginModuleFactory();
89
+ var plugin_default = factory;
90
+ export {
91
+ createPluginModuleFactory,
92
+ plugin_default as default
93
+ };
@@ -0,0 +1,52 @@
1
+ import ts from 'typescript';
2
+ import { ImportMapOutput } from '@pandacss/compiler-shared';
3
+ import { SpecIndex, CompletionEntry } from '@pandacss/compiler/tooling';
4
+
5
+ declare function findNodeAtPosition(root: ts.Node, position: number): ts.Node;
6
+ declare function findEnclosingStringLiteral(root: ts.Node, position: number): ts.StringLiteralLike | undefined;
7
+ declare function getContainerPath(node: ts.Node): string[];
8
+ type StyleObjectDefineKind = 'recipe' | 'global-styles';
9
+ interface DefineCallMatch {
10
+ kind: StyleObjectDefineKind;
11
+ argument: ts.ObjectLiteralExpression;
12
+ }
13
+ declare function findEnclosingDefineCall(node: ts.Node): DefineCallMatch | undefined;
14
+ interface StyleObjectCursorInfo {
15
+ existingKeys: string[];
16
+ cursorKind: 'key' | 'value';
17
+ /**
18
+ * Style-object-relative key chain leading to the cursor — e.g. `['color']` for a plain
19
+ * `color: 're'`, or `['backgroundColor', 'sm']` for `backgroundColor: { sm: 're' }` (a
20
+ * utility's own inline conditional value, which can nest to any depth:
21
+ * `ConditionalValue<V> = V | Array<V> | { [condition]?: ConditionalValue<V> }`). This layer
22
+ * has no spec access, so it can't tell a condition key (nested style object) from a utility
23
+ * key (its own conditional-value wrapper) apart — the completion layer, which does have the
24
+ * spec, resolves the first segment that's a real utility and treats everything after it as
25
+ * condition keys wrapping that same property's value.
26
+ */
27
+ propertyPath: string[];
28
+ }
29
+ declare function getStyleObjectCursorInfo(sourceFile: ts.SourceFile, position: number): StyleObjectCursorInfo | undefined;
30
+
31
+ interface DocumentQuery {
32
+ fileName: string;
33
+ source: string;
34
+ position: number;
35
+ /** Reuse an already-parsed AST (e.g. tsserver's own Program) instead of re-parsing `source`. */
36
+ sourceFile?: ts.SourceFile;
37
+ }
38
+ interface LanguageServiceContext {
39
+ specIndex: SpecIndex;
40
+ importMap: ImportMapOutput;
41
+ outdir: string;
42
+ }
43
+ interface HoverInfo {
44
+ text: string;
45
+ start: number;
46
+ end: number;
47
+ }
48
+ declare function getCompletions(query: DocumentQuery, context: LanguageServiceContext): CompletionEntry[];
49
+ declare function getHover(query: DocumentQuery, context: LanguageServiceContext): HoverInfo | null;
50
+ declare function resolveModule(specifier: string, context: LanguageServiceContext): string | undefined;
51
+
52
+ export { type DefineCallMatch, type DocumentQuery, type HoverInfo, type LanguageServiceContext, type StyleObjectCursorInfo, type StyleObjectDefineKind, findEnclosingDefineCall, findEnclosingStringLiteral, findNodeAtPosition, getCompletions, getContainerPath, getHover, getStyleObjectCursorInfo, resolveModule };
@@ -0,0 +1,20 @@
1
+ import {
2
+ findEnclosingDefineCall,
3
+ findEnclosingStringLiteral,
4
+ findNodeAtPosition,
5
+ getCompletions,
6
+ getContainerPath,
7
+ getHover,
8
+ getStyleObjectCursorInfo,
9
+ resolveModule
10
+ } from "../chunk-IR4B4RGW.js";
11
+ export {
12
+ findEnclosingDefineCall,
13
+ findEnclosingStringLiteral,
14
+ findNodeAtPosition,
15
+ getCompletions,
16
+ getContainerPath,
17
+ getHover,
18
+ getStyleObjectCursorInfo,
19
+ resolveModule
20
+ };
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@pandacss/typescript-plugin",
3
+ "version": "2.0.0-beta.9",
4
+ "description": "TypeScript language service plugin for Panda CSS config authoring",
5
+ "keywords": [
6
+ "typescript-plugin",
7
+ "tsserver",
8
+ "panda",
9
+ "pandacss",
10
+ "css-in-js"
11
+ ],
12
+ "type": "module",
13
+ "main": "./plugin.cjs",
14
+ "types": "./dist/index.d.ts",
15
+ "exports": {
16
+ ".": {
17
+ "source": "./src/index.ts",
18
+ "types": "./dist/index.d.ts",
19
+ "require": "./plugin.cjs",
20
+ "default": "./dist/index.js"
21
+ },
22
+ "./service": {
23
+ "source": "./src/service/index.ts",
24
+ "types": "./dist/service/index.d.ts",
25
+ "default": "./dist/service/index.js"
26
+ },
27
+ "./package.json": "./package.json"
28
+ },
29
+ "author": "Segun Adebayo <joseshegs@gmail.com>",
30
+ "license": "MIT",
31
+ "sideEffects": false,
32
+ "homepage": "https://panda-css.com",
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "git+https://github.com/chakra-ui/panda.git",
36
+ "directory": "packages/typescript-plugin"
37
+ },
38
+ "publishConfig": {
39
+ "access": "public"
40
+ },
41
+ "files": [
42
+ "dist",
43
+ "plugin.cjs"
44
+ ],
45
+ "dependencies": {
46
+ "@pandacss/compiler": "2.0.0-beta.9",
47
+ "@pandacss/compiler-shared": "2.0.0-beta.9"
48
+ },
49
+ "devDependencies": {
50
+ "typescript": "6.0.2",
51
+ "@pandacss/dev": "2.0.0-beta.9"
52
+ },
53
+ "peerDependencies": {
54
+ "typescript": ">=5"
55
+ },
56
+ "engines": {
57
+ "node": ">=22"
58
+ },
59
+ "scripts": {
60
+ "build": "tsup --dts",
61
+ "build:fast": "tsup --no-dts",
62
+ "dev": "pnpm build:fast --watch",
63
+ "test": "vitest run"
64
+ }
65
+ }
package/plugin.cjs ADDED
@@ -0,0 +1,7 @@
1
+ // Static, hand-written — not built by tsup. tsserver's plugin loader does a plain
2
+ // CommonJS `require()` and needs `module.exports` to literally be the callable
3
+ // factory. The compiled `dist/index.cjs` exports `{ default: factory, ... }` (esbuild's
4
+ // ESM-to-CJS interop shape), which real tsserver could not call directly — confirmed
5
+ // via a real tsserver process logging "did not expose a proper factory function"
6
+ // before this shim existed. This unwraps it.
7
+ module.exports = require('./dist/index.cjs').default