@platformos/platformos-language-server-common 0.0.7 → 0.0.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.
Files changed (249) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/PropertyShapeInference.d.ts +18 -0
  3. package/dist/PropertyShapeInference.js +62 -0
  4. package/dist/PropertyShapeInference.js.map +1 -1
  5. package/dist/TypeSystem.d.ts +4 -9
  6. package/dist/TypeSystem.js +246 -390
  7. package/dist/TypeSystem.js.map +1 -1
  8. package/dist/codeActions/providers/GenerateDocBlockProvider.d.ts +10 -0
  9. package/dist/codeActions/providers/GenerateDocBlockProvider.js +39 -0
  10. package/dist/codeActions/providers/GenerateDocBlockProvider.js.map +1 -0
  11. package/dist/commands/providers/GenerateDocBlockCommandProvider.d.ts +19 -0
  12. package/dist/commands/providers/GenerateDocBlockCommandProvider.js +64 -0
  13. package/dist/commands/providers/GenerateDocBlockCommandProvider.js.map +1 -0
  14. package/dist/completions/CompletionsProvider.d.ts +6 -10
  15. package/dist/completions/CompletionsProvider.js +6 -9
  16. package/dist/completions/CompletionsProvider.js.map +1 -1
  17. package/dist/completions/params/LiquidCompletionParams.js +6 -17
  18. package/dist/completions/params/LiquidCompletionParams.js.map +1 -1
  19. package/dist/completions/providers/ContentForCompletionProvider.js +2 -4
  20. package/dist/completions/providers/ContentForCompletionProvider.js.map +1 -1
  21. package/dist/completions/providers/FilterNamedParameterCompletionProvider.d.ts +3 -3
  22. package/dist/completions/providers/FilterNamedParameterCompletionProvider.js +6 -6
  23. package/dist/completions/providers/FilterNamedParameterCompletionProvider.js.map +1 -1
  24. package/dist/completions/providers/LiquidDocParamTypeCompletionProvider.d.ts +3 -3
  25. package/dist/completions/providers/LiquidDocParamTypeCompletionProvider.js +3 -3
  26. package/dist/completions/providers/LiquidDocParamTypeCompletionProvider.js.map +1 -1
  27. package/dist/completions/providers/LiquidTagsCompletionProvider.d.ts +3 -3
  28. package/dist/completions/providers/LiquidTagsCompletionProvider.js +3 -3
  29. package/dist/completions/providers/LiquidTagsCompletionProvider.js.map +1 -1
  30. package/dist/completions/providers/RenderPartialParameterCompletionProvider.js +1 -1
  31. package/dist/completions/providers/RenderPartialParameterCompletionProvider.js.map +1 -1
  32. package/dist/completions/providers/index.d.ts +0 -3
  33. package/dist/completions/providers/index.js +1 -7
  34. package/dist/completions/providers/index.js.map +1 -1
  35. package/dist/css/CSSLanguageService.d.ts +19 -5
  36. package/dist/css/CSSLanguageService.js +77 -63
  37. package/dist/css/CSSLanguageService.js.map +1 -1
  38. package/dist/definitions/DefinitionProvider.d.ts +1 -1
  39. package/dist/definitions/DefinitionProvider.js +1 -3
  40. package/dist/definitions/DefinitionProvider.js.map +1 -1
  41. package/dist/diagnostics/offenseToDiagnostic.js +1 -1
  42. package/dist/diagnostics/offenseToDiagnostic.js.map +1 -1
  43. package/dist/diagnostics/runChecks.d.ts +3 -5
  44. package/dist/diagnostics/runChecks.js +12 -64
  45. package/dist/diagnostics/runChecks.js.map +1 -1
  46. package/dist/docset/MarkdownRenderer.js +1 -1
  47. package/dist/docset/MarkdownRenderer.js.map +1 -1
  48. package/dist/documentLinks/DocumentLinksProvider.d.ts +3 -3
  49. package/dist/documentLinks/DocumentLinksProvider.js +3 -3
  50. package/dist/documentLinks/DocumentLinksProvider.js.map +1 -1
  51. package/dist/documents/DocumentManager.d.ts +4 -5
  52. package/dist/documents/DocumentManager.js +17 -12
  53. package/dist/documents/DocumentManager.js.map +1 -1
  54. package/dist/documents/types.d.ts +16 -3
  55. package/dist/documents/types.js +3 -3
  56. package/dist/documents/types.js.map +1 -1
  57. package/dist/hover/HoverProvider.d.ts +5 -8
  58. package/dist/hover/HoverProvider.js +8 -14
  59. package/dist/hover/HoverProvider.js.map +1 -1
  60. package/dist/hover/providers/LiquidFilterArgumentHoverProvider.d.ts +3 -3
  61. package/dist/hover/providers/LiquidFilterArgumentHoverProvider.js +3 -3
  62. package/dist/hover/providers/LiquidFilterArgumentHoverProvider.js.map +1 -1
  63. package/dist/hover/providers/LiquidFilterHoverProvider.d.ts +3 -3
  64. package/dist/hover/providers/LiquidFilterHoverProvider.js +3 -3
  65. package/dist/hover/providers/LiquidFilterHoverProvider.js.map +1 -1
  66. package/dist/hover/providers/LiquidTagHoverProvider.d.ts +3 -3
  67. package/dist/hover/providers/LiquidTagHoverProvider.js +3 -3
  68. package/dist/hover/providers/LiquidTagHoverProvider.js.map +1 -1
  69. package/dist/hover/providers/RenderPartialHoverProvider.js +1 -1
  70. package/dist/hover/providers/RenderPartialHoverProvider.js.map +1 -1
  71. package/dist/hover/providers/RenderPartialParameterHoverProvider.js +1 -1
  72. package/dist/hover/providers/RenderPartialParameterHoverProvider.js.map +1 -1
  73. package/dist/hover/providers/TranslationHoverProvider.d.ts +3 -3
  74. package/dist/hover/providers/TranslationHoverProvider.js +3 -3
  75. package/dist/hover/providers/TranslationHoverProvider.js.map +1 -1
  76. package/dist/index.d.ts +1 -1
  77. package/dist/index.js.map +1 -1
  78. package/dist/internal-types.d.ts +1 -1
  79. package/dist/json/JSONContributions.d.ts +1 -5
  80. package/dist/json/JSONContributions.js +4 -36
  81. package/dist/json/JSONContributions.js.map +1 -1
  82. package/dist/json/JSONLanguageService.d.ts +4 -12
  83. package/dist/json/JSONLanguageService.js +17 -80
  84. package/dist/json/JSONLanguageService.js.map +1 -1
  85. package/dist/json/test/test-helpers.d.ts +1 -3
  86. package/dist/json/test/test-helpers.js +3 -19
  87. package/dist/json/test/test-helpers.js.map +1 -1
  88. package/dist/json/utils.d.ts +0 -5
  89. package/dist/json/utils.js +0 -24
  90. package/dist/json/utils.js.map +1 -1
  91. package/dist/rename/RenameProvider.d.ts +2 -2
  92. package/dist/rename/RenameProvider.js +2 -2
  93. package/dist/rename/RenameProvider.js.map +1 -1
  94. package/dist/rename/providers/LiquidVariableRenameProvider.d.ts +3 -3
  95. package/dist/rename/providers/LiquidVariableRenameProvider.js +4 -4
  96. package/dist/rename/providers/LiquidVariableRenameProvider.js.map +1 -1
  97. package/dist/renamed/RenameHandler.d.ts +2 -3
  98. package/dist/renamed/RenameHandler.js +3 -8
  99. package/dist/renamed/RenameHandler.js.map +1 -1
  100. package/dist/renamed/handlers/AssetRenameHandler.d.ts +3 -3
  101. package/dist/renamed/handlers/AssetRenameHandler.js +5 -5
  102. package/dist/renamed/handlers/AssetRenameHandler.js.map +1 -1
  103. package/dist/renamed/handlers/PartialRenameHandler.d.ts +3 -3
  104. package/dist/renamed/handlers/PartialRenameHandler.js +5 -5
  105. package/dist/renamed/handlers/PartialRenameHandler.js.map +1 -1
  106. package/dist/renamed/handlers/utils.d.ts +1 -1
  107. package/dist/server/AppGraphManager.d.ts +32 -0
  108. package/dist/server/AppGraphManager.js +155 -0
  109. package/dist/server/AppGraphManager.js.map +1 -0
  110. package/dist/server/startServer.d.ts +2 -2
  111. package/dist/server/startServer.js +62 -164
  112. package/dist/server/startServer.js.map +1 -1
  113. package/dist/tsconfig.tsbuildinfo +1 -1
  114. package/dist/types.d.ts +33 -54
  115. package/dist/types.js +21 -26
  116. package/dist/types.js.map +1 -1
  117. package/dist/utils/liquidDoc.js +1 -1
  118. package/dist/utils/liquidDoc.js.map +1 -1
  119. package/dist/utils/uri.d.ts +2 -9
  120. package/dist/utils/uri.js +5 -21
  121. package/dist/utils/uri.js.map +1 -1
  122. package/package.json +4 -4
  123. package/src/ClientCapabilities.ts +1 -1
  124. package/src/PropertyShapeInference.ts +81 -1
  125. package/src/TypeSystem.spec.ts +206 -449
  126. package/src/TypeSystem.ts +267 -460
  127. package/src/codeActions/providers/FixAllProvider.spec.ts +1 -1
  128. package/src/codeActions/providers/FixProvider.spec.ts +11 -11
  129. package/src/codeActions/providers/SuggestionProvider.spec.ts +2 -2
  130. package/src/commands/providers/ApplyFixesProvider.ts +2 -2
  131. package/src/commands/providers/ApplySuggestionProvider.ts +2 -2
  132. package/src/commands/providers/RunChecksProvider.ts +2 -2
  133. package/src/completions/CompletionsProvider.ts +14 -35
  134. package/src/completions/params/LiquidCompletionParams.spec.ts +0 -9
  135. package/src/completions/params/LiquidCompletionParams.ts +8 -17
  136. package/src/completions/params/fix.spec.ts +0 -3
  137. package/src/completions/providers/FilterCompletionProvider.spec.ts +2 -8
  138. package/src/completions/providers/FilterNamedParameterCompletionProvider.spec.ts +1 -5
  139. package/src/completions/providers/FilterNamedParameterCompletionProvider.ts +6 -6
  140. package/src/completions/providers/HtmlAttributeCompletionProvider.spec.ts +1 -4
  141. package/src/completions/providers/HtmlAttributeValueCompletionProvider.spec.ts +1 -4
  142. package/src/completions/providers/HtmlTagCompletionProvider.spec.ts +1 -4
  143. package/src/completions/providers/LiquidDocParamTypeCompletionProvider.spec.ts +1 -28
  144. package/src/completions/providers/LiquidDocParamTypeCompletionProvider.ts +3 -3
  145. package/src/completions/providers/LiquidDocTagCompletionProvider.spec.ts +1 -26
  146. package/src/completions/providers/LiquidTagsCompletionProvider.spec.ts +4 -18
  147. package/src/completions/providers/LiquidTagsCompletionProvider.ts +3 -3
  148. package/src/completions/providers/ObjectAttributeCompletionProvider.spec.ts +2 -31
  149. package/src/completions/providers/ObjectCompletionProvider.spec.ts +34 -123
  150. package/src/completions/providers/PartialCompletionProvider.spec.ts +6 -15
  151. package/src/completions/providers/RenderPartialParameterCompletionProvider.spec.ts +13 -15
  152. package/src/completions/providers/RenderPartialParameterCompletionProvider.ts +2 -3
  153. package/src/completions/providers/TranslationCompletionProvider.spec.ts +1 -4
  154. package/src/completions/providers/TranslationCompletionProvider.ts +3 -3
  155. package/src/completions/providers/index.ts +0 -3
  156. package/src/css/CSSLanguageService.ts +97 -81
  157. package/src/definitions/DefinitionProvider.ts +0 -6
  158. package/src/definitions/providers/TranslationStringDefinitionProvider.spec.ts +1 -5
  159. package/src/diagnostics/offenseToDiagnostic.ts +1 -1
  160. package/src/diagnostics/runChecks.spec.ts +22 -30
  161. package/src/diagnostics/runChecks.ts +17 -91
  162. package/src/docset/MarkdownRenderer.ts +1 -1
  163. package/src/documentLinks/DocumentLinksProvider.ts +10 -10
  164. package/src/documents/DocumentManager.spec.ts +46 -119
  165. package/src/documents/DocumentManager.ts +19 -15
  166. package/src/documents/types.ts +18 -9
  167. package/src/hover/HoverProvider.ts +9 -21
  168. package/src/hover/providers/HtmlAttributeHoverProvider.spec.ts +1 -3
  169. package/src/hover/providers/HtmlAttributeValueHoverProvider.spec.ts +1 -3
  170. package/src/hover/providers/HtmlTagHoverProvider.spec.ts +1 -3
  171. package/src/hover/providers/LiquidDocTagHoverProvider.spec.ts +1 -4
  172. package/src/hover/providers/LiquidFilterArgumentHoverProvider.spec.ts +0 -3
  173. package/src/hover/providers/LiquidFilterArgumentHoverProvider.ts +3 -3
  174. package/src/hover/providers/LiquidFilterHoverProvider.spec.ts +0 -3
  175. package/src/hover/providers/LiquidFilterHoverProvider.ts +3 -3
  176. package/src/hover/providers/LiquidObjectAttributeHoverProvider.spec.ts +1 -3
  177. package/src/hover/providers/LiquidObjectHoverProvider.spec.ts +46 -129
  178. package/src/hover/providers/LiquidTagHoverProvider.spec.ts +0 -3
  179. package/src/hover/providers/LiquidTagHoverProvider.ts +3 -3
  180. package/src/hover/providers/RenderPartialHoverProvider.spec.ts +11 -14
  181. package/src/hover/providers/RenderPartialHoverProvider.ts +1 -5
  182. package/src/hover/providers/RenderPartialParameterHoverProvider.spec.ts +10 -13
  183. package/src/hover/providers/RenderPartialParameterHoverProvider.ts +2 -3
  184. package/src/hover/providers/TranslationHoverProvider.spec.ts +1 -4
  185. package/src/hover/providers/TranslationHoverProvider.ts +3 -3
  186. package/src/index.ts +4 -7
  187. package/src/internal-types.ts +1 -1
  188. package/src/json/JSONContributions.ts +4 -61
  189. package/src/json/JSONLanguageService.ts +19 -117
  190. package/src/json/test/test-helpers.ts +4 -35
  191. package/src/json/utils.ts +0 -27
  192. package/src/rename/RenameProvider.ts +4 -4
  193. package/src/rename/providers/LiquidVariableRenameProvider.spec.ts +5 -5
  194. package/src/rename/providers/LiquidVariableRenameProvider.ts +6 -6
  195. package/src/renamed/RenameHandler.ts +4 -9
  196. package/src/renamed/handlers/AssetRenameHandler.spec.ts +28 -28
  197. package/src/renamed/handlers/AssetRenameHandler.ts +6 -6
  198. package/src/renamed/handlers/PartialRenameHandler.spec.ts +9 -9
  199. package/src/renamed/handlers/PartialRenameHandler.ts +10 -10
  200. package/src/server/{ThemeGraphManager.ts → AppGraphManager.ts} +21 -90
  201. package/src/server/safe.ts +1 -1
  202. package/src/server/startServer.spec.ts +10 -12
  203. package/src/server/startServer.ts +69 -222
  204. package/src/test/CompletionItemsAssertion.spec.ts +1 -4
  205. package/src/types.ts +33 -63
  206. package/src/utils/debounce.ts +1 -1
  207. package/src/utils/liquidDoc.ts +6 -6
  208. package/src/utils/uri.ts +5 -17
  209. package/src/completions/providers/ContentForBlockTypeCompletionProvider.spec.ts +0 -41
  210. package/src/completions/providers/ContentForBlockTypeCompletionProvider.ts +0 -42
  211. package/src/completions/providers/ContentForCompletionProvider.spec.ts +0 -96
  212. package/src/completions/providers/ContentForCompletionProvider.ts +0 -113
  213. package/src/completions/providers/ContentForParameterCompletionProvider.spec.ts +0 -362
  214. package/src/completions/providers/ContentForParameterCompletionProvider.ts +0 -187
  215. package/src/completions/providers/data/contentForParameterCompletionOptions.ts +0 -9
  216. package/src/css/CSSLanguageService.spec.ts +0 -159
  217. package/src/css/test/test-helpers.ts +0 -30
  218. package/src/definitions/providers/SchemaTranslationStringDefinitionProvider.spec.ts +0 -96
  219. package/src/definitions/providers/SchemaTranslationStringDefinitionProvider.ts +0 -82
  220. package/src/hover/providers/ContentForArgumentHoverProvider.spec.ts +0 -76
  221. package/src/hover/providers/ContentForArgumentHoverProvider.ts +0 -56
  222. package/src/hover/providers/ContentForTypeHoverProvider.spec.ts +0 -91
  223. package/src/hover/providers/ContentForTypeHoverProvider.ts +0 -42
  224. package/src/json/JSONLanguageService.spec.ts +0 -424
  225. package/src/json/completions/providers/BlockSettingsPropertyCompletionProvider.spec.ts +0 -163
  226. package/src/json/completions/providers/BlockSettingsPropertyCompletionProvider.ts +0 -121
  227. package/src/json/completions/providers/BlockTypeCompletionProvider.spec.ts +0 -137
  228. package/src/json/completions/providers/BlockTypeCompletionProvider.ts +0 -108
  229. package/src/json/completions/providers/ReferencedBlockTypeCompletionProvider.spec.ts +0 -132
  230. package/src/json/completions/providers/ReferencedBlockTypeCompletionProvider.ts +0 -120
  231. package/src/json/completions/providers/SchemaTranslationCompletionProvider.ts +0 -51
  232. package/src/json/completions/providers/SettingsPropertyCompletionProvider.spec.ts +0 -211
  233. package/src/json/completions/providers/SettingsPropertyCompletionProvider.ts +0 -75
  234. package/src/json/documentLinks/DocumentLinksProvider.spec.ts +0 -223
  235. package/src/json/documentLinks/DocumentLinksProvider.ts +0 -61
  236. package/src/json/hover/providers/BlockSettingsHoverProvider.spec.ts +0 -292
  237. package/src/json/hover/providers/BlockSettingsHoverProvider.ts +0 -99
  238. package/src/json/hover/providers/SchemaTranslationHoverProvider.ts +0 -35
  239. package/src/json/hover/providers/SettingsHoverProvider.spec.ts +0 -139
  240. package/src/json/hover/providers/SettingsHoverProvider.ts +0 -79
  241. package/src/json/schemaSettings.spec.ts +0 -103
  242. package/src/json/schemaSettings.ts +0 -53
  243. package/src/plugins/css.ts +0 -12
  244. package/src/renamed/handlers/BlockRenameHandler.spec.ts +0 -399
  245. package/src/renamed/handlers/BlockRenameHandler.ts +0 -402
  246. package/src/renamed/handlers/SectionRenameHandler.spec.ts +0 -321
  247. package/src/renamed/handlers/SectionRenameHandler.ts +0 -224
  248. package/src/renamed/handlers/utils.ts +0 -22
  249. package/src/settings/index.ts +0 -50
@@ -1,362 +0,0 @@
1
- import { describe, afterEach, beforeEach, it, expect, vi } from 'vitest';
2
- import { CompletionsProvider } from '../CompletionsProvider';
3
- import { DocumentManager } from '../../documents';
4
- import { MetafieldDefinitionMap } from '@platformos/platformos-check-common';
5
- import { TextEdit, InsertTextFormat } from 'vscode-languageserver-protocol';
6
- import { TextDocument } from 'vscode-languageserver-textdocument';
7
- import { CURSOR } from '../params';
8
-
9
- vi.mock('./data/contentForParameterCompletionOptions', async () => {
10
- const actual = (await vi.importActual(
11
- './data/contentForParameterCompletionOptions',
12
- )) as typeof import('./data/contentForParameterCompletionOptions');
13
- return {
14
- DEFAULT_COMPLETION_OPTIONS: {
15
- ...actual.DEFAULT_COMPLETION_OPTIONS,
16
- // Add another option here so we can properly test some scenarios that
17
- // we wouldn't be able to otherwise.
18
- testOption: '',
19
- },
20
- };
21
- });
22
-
23
- describe('Module: ContentForBlockParameterCompletionProvider', async () => {
24
- let provider: CompletionsProvider;
25
-
26
- beforeEach(async () => {
27
- provider = new CompletionsProvider({
28
- documentManager: new DocumentManager(),
29
- themeDocset: {
30
- graphQL: async () => null,
31
- filters: async () => [],
32
- objects: async () => [],
33
- liquidDrops: async () => [],
34
- tags: async () => [],
35
- systemTranslations: async () => ({}),
36
- },
37
- getMetafieldDefinitions: async (_rootUri: string) => ({}) as MetafieldDefinitionMap,
38
- });
39
- });
40
-
41
- afterEach(() => {
42
- vi.restoreAllMocks();
43
- });
44
-
45
- it('offers a full list of completion items', async () => {
46
- await expect(provider).to.complete('{% content_for "block", █ %}', [
47
- 'type',
48
- 'id',
49
- 'closest',
50
- 'testOption',
51
- ]);
52
- });
53
-
54
- it('does not offer completion items if they are already present', async () => {
55
- const context = `{% content_for "block", type: "fake-block", id: "fake-id", █ %}`;
56
-
57
- await expect(provider).to.complete(context, ['closest', 'testOption']);
58
- });
59
-
60
- it('uses text edits to insert the completion item', async () => {
61
- // char 24 ⌄
62
- const context = `{% content_for "block", █ %}`;
63
-
64
- const textEdit: TextEdit = {
65
- newText: "type: '$1'",
66
- range: {
67
- end: { line: 0, character: 24 },
68
- start: { line: 0, character: 24 },
69
- },
70
- };
71
-
72
- await expect(provider).to.complete(
73
- context,
74
- expect.arrayContaining([
75
- expect.objectContaining({
76
- label: 'type',
77
- insertTextFormat: InsertTextFormat.Snippet,
78
- textEdit,
79
- }),
80
- ]),
81
- );
82
-
83
- const textDocument = TextDocument.create('', 'liquid', 0, context.replace(CURSOR, ''));
84
-
85
- expect(TextDocument.applyEdits(textDocument, [textEdit])).toBe(
86
- `{% content_for "block", type: '$1' %}`,
87
- );
88
- });
89
-
90
- it('provides a different style of completion for "closest"', async () => {
91
- // char 24 ⌄
92
- const context = `{% content_for "block", █ %}`;
93
-
94
- const textEdit: TextEdit = {
95
- newText: 'closest.',
96
- range: {
97
- end: { line: 0, character: 24 },
98
- start: { line: 0, character: 24 },
99
- },
100
- };
101
-
102
- await expect(provider).to.complete(
103
- context,
104
- expect.arrayContaining([
105
- expect.objectContaining({
106
- label: 'closest',
107
- insertTextFormat: InsertTextFormat.PlainText,
108
- textEdit,
109
- }),
110
- ]),
111
- );
112
-
113
- const textDocument = TextDocument.create('', 'liquid', 0, context.replace(CURSOR, ''));
114
-
115
- expect(TextDocument.applyEdits(textDocument, [textEdit])).toBe(
116
- `{% content_for "block", closest. %}`,
117
- );
118
- });
119
-
120
- describe("when we're completing for blocks we allow `closest`", () => {
121
- it('does something', async () => {
122
- await expect(provider).to.complete('{% content_for "blocks", █ %}', ['closest']);
123
- });
124
- });
125
-
126
- describe('when the user has already started typing the name of the parameter', () => {
127
- it('filters the completion options to only include ones that match', async () => {
128
- await expect(provider).to.complete('{% content_for "block", t█ %}', ['type', 'testOption']);
129
- });
130
- });
131
-
132
- describe('when the user has already typed out a parameter name', () => {
133
- describe('and the cursor is in the middle of the parameter', () => {
134
- it('changes the range depending on the completion item', async () => {
135
- // char 24 ⌄ ⌄ char 38
136
- const context = `{% content_for "block", t█ype: "button" %}`;
137
- // ⌃ char 28
138
-
139
- const typeTextEdit: TextEdit = {
140
- newText: 'type',
141
- range: {
142
- end: { line: 0, character: 28 },
143
- start: { line: 0, character: 24 },
144
- },
145
- };
146
-
147
- const testTextEdit: TextEdit = {
148
- newText: "testOption: '$1'",
149
- range: {
150
- end: { line: 0, character: 38 },
151
- start: { line: 0, character: 24 },
152
- },
153
- };
154
-
155
- await expect(provider).to.complete(context, [
156
- expect.objectContaining({
157
- label: 'type',
158
- insertTextFormat: InsertTextFormat.PlainText,
159
- textEdit: expect.objectContaining(typeTextEdit),
160
- }),
161
- expect.objectContaining({
162
- label: 'testOption',
163
- insertTextFormat: InsertTextFormat.Snippet,
164
- textEdit: expect.objectContaining(testTextEdit),
165
- }),
166
- ]);
167
-
168
- const textDocument = TextDocument.create('', 'liquid', 0, context.replace(CURSOR, ''));
169
-
170
- expect(TextDocument.applyEdits(textDocument, [testTextEdit])).toBe(
171
- `{% content_for "block", testOption: '$1' %}`,
172
- );
173
-
174
- expect(TextDocument.applyEdits(textDocument, [typeTextEdit])).toBe(
175
- `{% content_for "block", type: "button" %}`,
176
- );
177
- });
178
- });
179
-
180
- describe('and the cursor is at the beginning of the parameter', () => {
181
- it('offers a full list of completion items', async () => {
182
- const context = `{% content_for "block", █type: "button" %}`;
183
-
184
- await expect(provider).to.complete(context, ['type', 'id', 'closest', 'testOption']);
185
- });
186
-
187
- it('does not replace the existing text', async () => {
188
- // char 24 ⌄
189
- const context = `{% content_for "block", █type: "button" %}`;
190
-
191
- const textEdit: TextEdit = {
192
- newText: "testOption: '$1', ",
193
- range: {
194
- end: { line: 0, character: 24 },
195
- start: { line: 0, character: 24 },
196
- },
197
- };
198
-
199
- await expect(provider).to.complete(
200
- context,
201
- expect.arrayContaining([
202
- expect.objectContaining({
203
- label: 'testOption',
204
- insertTextFormat: InsertTextFormat.Snippet,
205
- textEdit,
206
- }),
207
- ]),
208
- );
209
-
210
- const textDocument = TextDocument.create('', 'liquid', 0, context.replace(CURSOR, ''));
211
-
212
- expect(TextDocument.applyEdits(textDocument, [textEdit])).toBe(
213
- `{% content_for "block", testOption: '$1', type: "button" %}`,
214
- );
215
- });
216
- });
217
-
218
- describe('and the cursor is at the end of the parameter', () => {
219
- it('offers only the same completion item', async () => {
220
- const context = `{% content_for "block", type█: "button" %}`;
221
-
222
- await expect(provider).to.complete(context, ['type']);
223
- });
224
-
225
- it('only replaces the parameter name', async () => {
226
- // char 24 ⌄ ⌄ char 28
227
- const context = `{% content_for "block", type█: "button" %}`;
228
-
229
- const textEdit: TextEdit = {
230
- newText: 'type',
231
- range: {
232
- end: { line: 0, character: 28 },
233
- start: { line: 0, character: 24 },
234
- },
235
- };
236
-
237
- await expect(provider).to.complete(
238
- context,
239
- expect.arrayContaining([
240
- expect.objectContaining({
241
- label: 'type',
242
- insertTextFormat: InsertTextFormat.PlainText,
243
- textEdit,
244
- }),
245
- ]),
246
- );
247
-
248
- const textDocument = TextDocument.create('', 'liquid', 0, context.replace(CURSOR, ''));
249
-
250
- expect(TextDocument.applyEdits(textDocument, [textEdit])).toBe(
251
- `{% content_for "block", type: "button" %}`,
252
- );
253
- });
254
- });
255
- });
256
-
257
- describe('when the referred block has LiquidDoc parameters', () => {
258
- beforeEach(async () => {
259
- provider = new CompletionsProvider({
260
- documentManager: new DocumentManager(),
261
- themeDocset: {
262
- graphQL: async () => null,
263
- filters: async () => [],
264
- objects: async () => [],
265
- liquidDrops: async () => [],
266
- tags: async () => [],
267
- systemTranslations: async () => ({}),
268
- },
269
- getMetafieldDefinitions: async (_rootUri: string) => ({}) as MetafieldDefinitionMap,
270
- getDocDefinitionForURI: async (_uri, _category, _name) => {
271
- return {
272
- uri: 'file:///blocks/product-card.liquid',
273
- liquidDoc: {
274
- parameters: [
275
- {
276
- nodeType: 'param',
277
- name: 'example-string-param',
278
- type: 'string',
279
- description: 'An example string parameter',
280
- required: true,
281
- },
282
- {
283
- nodeType: 'param',
284
- name: 'example-number-param',
285
- type: 'number',
286
- description: 'An example number parameter',
287
- required: true,
288
- },
289
- {
290
- nodeType: 'param',
291
- name: 'example-boolean-param',
292
- type: 'boolean',
293
- description: 'An example boolean parameter',
294
- required: true,
295
- },
296
- {
297
- nodeType: 'param',
298
- name: 'example-object-param',
299
- type: 'object',
300
- description: 'An example object parameter',
301
- required: true,
302
- },
303
- {
304
- nodeType: 'param',
305
- name: 'example-unknown-param',
306
- type: 'unknown',
307
- description: 'An example unknown parameter',
308
- required: true,
309
- },
310
- ],
311
- },
312
- };
313
- },
314
- });
315
- });
316
-
317
- it('offers the LiquidDoc parameters as completions', async () => {
318
- const context = `{% content_for "block", type: 'fake-block', █ %}`;
319
-
320
- await expect(provider).to.complete(
321
- context,
322
- expect.arrayContaining([
323
- expect.objectContaining({
324
- label: 'example-string-param',
325
- insertTextFormat: InsertTextFormat.Snippet,
326
- textEdit: expect.objectContaining({
327
- newText: "example-string-param: '$1'$0",
328
- }),
329
- }),
330
- expect.objectContaining({
331
- label: 'example-number-param',
332
- insertTextFormat: InsertTextFormat.Snippet,
333
- textEdit: expect.objectContaining({
334
- newText: 'example-number-param: ${1:0}$0',
335
- }),
336
- }),
337
- expect.objectContaining({
338
- label: 'example-boolean-param',
339
- insertTextFormat: InsertTextFormat.Snippet,
340
- textEdit: expect.objectContaining({
341
- newText: 'example-boolean-param: ${1:false}$0',
342
- }),
343
- }),
344
- expect.objectContaining({
345
- label: 'example-object-param',
346
- insertTextFormat: InsertTextFormat.Snippet,
347
- textEdit: expect.objectContaining({
348
- newText: 'example-object-param: ${1:}$0',
349
- }),
350
- }),
351
- expect.objectContaining({
352
- label: 'example-unknown-param',
353
- insertTextFormat: InsertTextFormat.Snippet,
354
- textEdit: expect.objectContaining({
355
- newText: 'example-unknown-param: ${1:}$0',
356
- }),
357
- }),
358
- ]),
359
- );
360
- });
361
- });
362
- });
@@ -1,187 +0,0 @@
1
- import { LiquidVariableLookup, NodeTypes } from '@platformos/liquid-html-parser';
2
- import {
3
- CompletionItem,
4
- CompletionItemKind,
5
- InsertTextFormat,
6
- TextEdit,
7
- } from 'vscode-languageserver';
8
- import { CURSOR, LiquidCompletionParams } from '../params';
9
- import { Provider } from './common';
10
- import { AugmentedLiquidSourceCode } from '../../documents';
11
- import { DEFAULT_COMPLETION_OPTIONS } from './data/contentForParameterCompletionOptions';
12
- import { DocDefinition, GetDocDefinitionForURI } from '@platformos/platformos-check-common';
13
- import { getParameterCompletionTemplate } from '../../utils/liquidDoc';
14
-
15
- /**
16
- * Offers completions for parameters for the `content_for` tag after a user has
17
- * specificied the type.
18
- *
19
- * @example {% content_for "block", █ %}
20
- */
21
- export class ContentForParameterCompletionProvider implements Provider {
22
- constructor(private readonly getDocDefinitionForURI: GetDocDefinitionForURI) {}
23
-
24
- async completions(params: LiquidCompletionParams): Promise<CompletionItem[]> {
25
- if (!params.completionContext) return [];
26
-
27
- const { node, ancestors } = params.completionContext;
28
-
29
- const parentNode = ancestors.at(-1);
30
-
31
- const parentIsContentFor = parentNode?.type == NodeTypes.ContentForMarkup;
32
- const nodeIsVariableLookup = node?.type == NodeTypes.VariableLookup;
33
-
34
- if (!parentIsContentFor || !nodeIsVariableLookup) {
35
- return [];
36
- }
37
-
38
- if (!node.name || node.lookups.length > 0) {
39
- return [];
40
- }
41
-
42
- const completionItems = this.staticCompletions(
43
- node,
44
- parentNode.contentForType.value == 'blocks',
45
- params.document,
46
- );
47
-
48
- if (parentNode.contentForType.value === 'block') {
49
- const typeArg = parentNode.args.find((arg) => arg.name === 'type')?.value;
50
-
51
- if (typeArg?.type === NodeTypes.String) {
52
- const snippetDefinition = await this.getDocDefinitionForURI(
53
- params.textDocument.uri,
54
- 'blocks',
55
- typeArg.value,
56
- );
57
-
58
- completionItems.push(
59
- ...this.liquidDocParameterCompletions(node, params.document, snippetDefinition),
60
- );
61
- }
62
- }
63
-
64
- // We need to find out existing params in the content_for tag so we don't offer it again for completion
65
- const existingParams = parentNode.args
66
- .filter((arg) => arg.type === NodeTypes.NamedArgument)
67
- .map((arg) => arg.name);
68
-
69
- return completionItems.filter((item) => !existingParams.includes(item.label));
70
- }
71
-
72
- textEdit(
73
- node: LiquidVariableLookup,
74
- document: AugmentedLiquidSourceCode,
75
- name: string,
76
- textTemplate: string = `${name}: '$1'`,
77
- ): {
78
- textEdit: TextEdit;
79
- format: InsertTextFormat;
80
- } {
81
- const remainingText = document.source.slice(node.position.end);
82
-
83
- // Match all the way up to the termination of the parameter which could be
84
- // another parameter (`,`), filter (`|`), or the end of a liquid statement.
85
- const match = remainingText.match(/^(.*?)\s*(?=,|\||-?\}\}|-?\%\})|^(.*)$/);
86
- const offset = match ? match[0].trimEnd().length : remainingText.length;
87
- const existingParameterOffset = remainingText.match(/[^a-zA-Z]/)?.index ?? remainingText.length;
88
-
89
- let start = document.textDocument.positionAt(node.position.start);
90
- let end = document.textDocument.positionAt(node.position.end + offset);
91
- let newText = name === 'closest' ? `${name}.` : textTemplate;
92
- let format = name === 'closest' ? InsertTextFormat.PlainText : InsertTextFormat.Snippet;
93
-
94
- // If the cursor is inside the parameter or at the end and it's the same
95
- // value as the one we're offering a completion for then we want to restrict
96
- // the insert to just the name of the parameter.
97
- // e.g. `{% content_for "block", t█ype: "button" %}` and we're offering `type`
98
- if (node.name + remainingText.slice(0, existingParameterOffset) == name) {
99
- newText = name;
100
- format = InsertTextFormat.PlainText;
101
- end = document.textDocument.positionAt(node.position.end + existingParameterOffset);
102
- }
103
-
104
- // If the cursor is at the beginning of the string we can consider all
105
- // options and should not replace any text.
106
- // e.g. `{% content_for "block", █type: "button" %}`
107
- // e.g. `{% content_for "block", █ %}`
108
- if (node.name === CURSOR) {
109
- end = start;
110
-
111
- // If we're inserting text in front of an existing parameter then we need
112
- // to add a comma to separate them.
113
- if (existingParameterOffset > 0) {
114
- newText += ', ';
115
- }
116
- }
117
-
118
- return {
119
- textEdit: TextEdit.replace(
120
- {
121
- start,
122
- end,
123
- },
124
- newText,
125
- ),
126
- format,
127
- };
128
- }
129
-
130
- private staticCompletions(
131
- node: LiquidVariableLookup,
132
- isTypeBlocks: boolean,
133
- document: AugmentedLiquidSourceCode,
134
- ) {
135
- let options = DEFAULT_COMPLETION_OPTIONS;
136
-
137
- const partial = node.name!.replace(CURSOR, '');
138
-
139
- if (isTypeBlocks) {
140
- options = {
141
- closest: DEFAULT_COMPLETION_OPTIONS.closest,
142
- };
143
- }
144
-
145
- return Object.entries(options)
146
- .filter(([keyword, _description]) => keyword.startsWith(partial))
147
- .map(([keyword, description]): CompletionItem => {
148
- const { textEdit, format } = this.textEdit(node, document, keyword);
149
- return {
150
- label: keyword,
151
- kind: CompletionItemKind.Keyword,
152
- documentation: {
153
- kind: 'markdown',
154
- value: description,
155
- },
156
- insertTextFormat: format,
157
- textEdit,
158
- };
159
- });
160
- }
161
-
162
- private liquidDocParameterCompletions(
163
- node: LiquidVariableLookup,
164
- document: AugmentedLiquidSourceCode,
165
- docDefinition?: DocDefinition,
166
- ) {
167
- return (docDefinition?.liquidDoc?.parameters || []).map((liquidDocParam): CompletionItem => {
168
- const { textEdit, format } = this.textEdit(
169
- node,
170
- document,
171
- liquidDocParam.name,
172
- getParameterCompletionTemplate(liquidDocParam.name, liquidDocParam.type),
173
- );
174
-
175
- return {
176
- label: liquidDocParam.name,
177
- kind: CompletionItemKind.Keyword,
178
- documentation: {
179
- kind: 'markdown',
180
- value: liquidDocParam.description || '',
181
- },
182
- insertTextFormat: format,
183
- textEdit,
184
- };
185
- });
186
- }
187
- }
@@ -1,9 +0,0 @@
1
- /**
2
- * These definitions are not currently available in the generated Liquid Docs
3
- * so we're hardcoding them here in the interim.
4
- */
5
- export const DEFAULT_COMPLETION_OPTIONS: { [key: string]: string } = {
6
- type: "The type (name) of an existing theme block in your theme’s /blocks folder. Only applicable when `content_type` is 'block'.",
7
- id: "A unique identifier and literal string within the section or block that contains the static blocks. Only applicable when `content_type` is 'block'.",
8
- closest: 'A path that provides a way to access the closest resource of a given type.',
9
- };