@platformos/platformos-language-server-common 0.0.6 → 0.0.8

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 (247) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/PropertyShapeInference.d.ts +18 -0
  3. package/dist/PropertyShapeInference.js +58 -0
  4. package/dist/PropertyShapeInference.js.map +1 -1
  5. package/dist/TypeSystem.d.ts +4 -9
  6. package/dist/TypeSystem.js +234 -388
  7. package/dist/TypeSystem.js.map +1 -1
  8. package/dist/completions/CompletionsProvider.d.ts +6 -10
  9. package/dist/completions/CompletionsProvider.js +6 -9
  10. package/dist/completions/CompletionsProvider.js.map +1 -1
  11. package/dist/completions/params/LiquidCompletionParams.js +4 -16
  12. package/dist/completions/params/LiquidCompletionParams.js.map +1 -1
  13. package/dist/completions/providers/ContentForCompletionProvider.js +2 -4
  14. package/dist/completions/providers/ContentForCompletionProvider.js.map +1 -1
  15. package/dist/completions/providers/FilterCompletionProvider.js.map +1 -1
  16. package/dist/completions/providers/FilterNamedParameterCompletionProvider.d.ts +3 -3
  17. package/dist/completions/providers/FilterNamedParameterCompletionProvider.js +6 -6
  18. package/dist/completions/providers/FilterNamedParameterCompletionProvider.js.map +1 -1
  19. package/dist/completions/providers/LiquidDocParamTypeCompletionProvider.d.ts +3 -3
  20. package/dist/completions/providers/LiquidDocParamTypeCompletionProvider.js +3 -3
  21. package/dist/completions/providers/LiquidDocParamTypeCompletionProvider.js.map +1 -1
  22. package/dist/completions/providers/LiquidTagsCompletionProvider.d.ts +3 -3
  23. package/dist/completions/providers/LiquidTagsCompletionProvider.js +3 -3
  24. package/dist/completions/providers/LiquidTagsCompletionProvider.js.map +1 -1
  25. package/dist/completions/providers/RenderPartialParameterCompletionProvider.js +1 -1
  26. package/dist/completions/providers/RenderPartialParameterCompletionProvider.js.map +1 -1
  27. package/dist/completions/providers/TranslationCompletionProvider.js +1 -1
  28. package/dist/completions/providers/TranslationCompletionProvider.js.map +1 -1
  29. package/dist/completions/providers/index.d.ts +0 -3
  30. package/dist/completions/providers/index.js +1 -7
  31. package/dist/completions/providers/index.js.map +1 -1
  32. package/dist/css/CSSLanguageService.d.ts +19 -5
  33. package/dist/css/CSSLanguageService.js +77 -63
  34. package/dist/css/CSSLanguageService.js.map +1 -1
  35. package/dist/definitions/DefinitionProvider.d.ts +1 -1
  36. package/dist/definitions/DefinitionProvider.js +1 -3
  37. package/dist/definitions/DefinitionProvider.js.map +1 -1
  38. package/dist/diagnostics/offenseToDiagnostic.js +1 -1
  39. package/dist/diagnostics/offenseToDiagnostic.js.map +1 -1
  40. package/dist/diagnostics/runChecks.d.ts +3 -5
  41. package/dist/diagnostics/runChecks.js +12 -64
  42. package/dist/diagnostics/runChecks.js.map +1 -1
  43. package/dist/docset/MarkdownRenderer.js +1 -1
  44. package/dist/docset/MarkdownRenderer.js.map +1 -1
  45. package/dist/documentHighlights/providers/HtmlTagNameDocumentHighlightsProvider.d.ts +1 -1
  46. package/dist/documentLinks/DocumentLinksProvider.d.ts +3 -3
  47. package/dist/documentLinks/DocumentLinksProvider.js +3 -3
  48. package/dist/documentLinks/DocumentLinksProvider.js.map +1 -1
  49. package/dist/documents/DocumentManager.d.ts +4 -5
  50. package/dist/documents/DocumentManager.js +12 -11
  51. package/dist/documents/DocumentManager.js.map +1 -1
  52. package/dist/documents/types.d.ts +16 -3
  53. package/dist/documents/types.js +3 -3
  54. package/dist/documents/types.js.map +1 -1
  55. package/dist/formatting/OnTypeFormattingProvider.d.ts +1 -1
  56. package/dist/formatting/providers/HtmlElementAutoclosingOnTypeFormattingProvider.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/linkedEditingRanges/providers/HtmlTagNameLinkedRangesProvider.d.ts +1 -1
  92. package/dist/progress.js.map +1 -1
  93. package/dist/rename/RenameProvider.d.ts +2 -2
  94. package/dist/rename/RenameProvider.js +2 -2
  95. package/dist/rename/RenameProvider.js.map +1 -1
  96. package/dist/rename/providers/LiquidVariableRenameProvider.d.ts +3 -3
  97. package/dist/rename/providers/LiquidVariableRenameProvider.js +4 -4
  98. package/dist/rename/providers/LiquidVariableRenameProvider.js.map +1 -1
  99. package/dist/renamed/RenameHandler.d.ts +2 -3
  100. package/dist/renamed/RenameHandler.js +3 -8
  101. package/dist/renamed/RenameHandler.js.map +1 -1
  102. package/dist/renamed/handlers/AssetRenameHandler.d.ts +3 -3
  103. package/dist/renamed/handlers/AssetRenameHandler.js +5 -5
  104. package/dist/renamed/handlers/AssetRenameHandler.js.map +1 -1
  105. package/dist/renamed/handlers/PartialRenameHandler.d.ts +3 -3
  106. package/dist/renamed/handlers/PartialRenameHandler.js +5 -5
  107. package/dist/renamed/handlers/PartialRenameHandler.js.map +1 -1
  108. package/dist/renamed/handlers/utils.d.ts +1 -1
  109. package/dist/server/AppGraphManager.d.ts +32 -0
  110. package/dist/server/AppGraphManager.js +155 -0
  111. package/dist/server/AppGraphManager.js.map +1 -0
  112. package/dist/server/Configuration.js.map +1 -1
  113. package/dist/server/startServer.d.ts +2 -2
  114. package/dist/server/startServer.js +62 -164
  115. package/dist/server/startServer.js.map +1 -1
  116. package/dist/tsconfig.tsbuildinfo +1 -1
  117. package/dist/types.d.ts +33 -54
  118. package/dist/types.js +21 -26
  119. package/dist/types.js.map +1 -1
  120. package/dist/utils/liquidDoc.js +1 -1
  121. package/dist/utils/liquidDoc.js.map +1 -1
  122. package/dist/utils/uri.d.ts +0 -8
  123. package/dist/utils/uri.js +1 -17
  124. package/dist/utils/uri.js.map +1 -1
  125. package/package.json +9 -9
  126. package/src/PropertyShapeInference.ts +76 -1
  127. package/src/TypeSystem.spec.ts +187 -452
  128. package/src/TypeSystem.ts +253 -459
  129. package/src/completions/CompletionsProvider.ts +13 -34
  130. package/src/completions/params/LiquidCompletionParams.spec.ts +0 -9
  131. package/src/completions/params/LiquidCompletionParams.ts +4 -14
  132. package/src/completions/params/fix.spec.ts +0 -3
  133. package/src/completions/providers/FilterCompletionProvider.spec.ts +2 -8
  134. package/src/completions/providers/FilterCompletionProvider.ts +6 -6
  135. package/src/completions/providers/FilterNamedParameterCompletionProvider.spec.ts +1 -5
  136. package/src/completions/providers/FilterNamedParameterCompletionProvider.ts +6 -6
  137. package/src/completions/providers/HtmlAttributeCompletionProvider.spec.ts +1 -4
  138. package/src/completions/providers/HtmlAttributeValueCompletionProvider.spec.ts +1 -4
  139. package/src/completions/providers/HtmlTagCompletionProvider.spec.ts +1 -4
  140. package/src/completions/providers/LiquidDocParamTypeCompletionProvider.spec.ts +1 -28
  141. package/src/completions/providers/LiquidDocParamTypeCompletionProvider.ts +3 -3
  142. package/src/completions/providers/LiquidDocTagCompletionProvider.spec.ts +1 -26
  143. package/src/completions/providers/LiquidTagsCompletionProvider.spec.ts +2 -16
  144. package/src/completions/providers/LiquidTagsCompletionProvider.ts +3 -3
  145. package/src/completions/providers/ObjectAttributeCompletionProvider.spec.ts +2 -31
  146. package/src/completions/providers/ObjectCompletionProvider.spec.ts +34 -123
  147. package/src/completions/providers/PartialCompletionProvider.spec.ts +4 -13
  148. package/src/completions/providers/RenderPartialParameterCompletionProvider.spec.ts +3 -5
  149. package/src/completions/providers/RenderPartialParameterCompletionProvider.ts +0 -1
  150. package/src/completions/providers/TranslationCompletionProvider.spec.ts +1 -4
  151. package/src/completions/providers/TranslationCompletionProvider.ts +1 -1
  152. package/src/completions/providers/index.ts +0 -3
  153. package/src/css/CSSLanguageService.ts +97 -81
  154. package/src/definitions/DefinitionProvider.ts +0 -6
  155. package/src/definitions/providers/TranslationStringDefinitionProvider.spec.ts +1 -5
  156. package/src/diagnostics/offenseToDiagnostic.ts +1 -1
  157. package/src/diagnostics/runChecks.spec.ts +16 -24
  158. package/src/diagnostics/runChecks.ts +17 -91
  159. package/src/docset/MarkdownRenderer.ts +1 -1
  160. package/src/documentLinks/DocumentLinksProvider.ts +3 -3
  161. package/src/documents/DocumentManager.spec.ts +12 -97
  162. package/src/documents/DocumentManager.ts +13 -14
  163. package/src/documents/types.ts +18 -9
  164. package/src/formatting/providers/HtmlElementAutoclosingOnTypeFormattingProvider.ts +1 -3
  165. package/src/hover/HoverProvider.ts +9 -21
  166. package/src/hover/providers/HtmlAttributeHoverProvider.spec.ts +1 -3
  167. package/src/hover/providers/HtmlAttributeValueHoverProvider.spec.ts +1 -3
  168. package/src/hover/providers/HtmlTagHoverProvider.spec.ts +1 -3
  169. package/src/hover/providers/LiquidDocTagHoverProvider.spec.ts +0 -3
  170. package/src/hover/providers/LiquidFilterArgumentHoverProvider.spec.ts +0 -3
  171. package/src/hover/providers/LiquidFilterArgumentHoverProvider.ts +3 -3
  172. package/src/hover/providers/LiquidFilterHoverProvider.spec.ts +0 -3
  173. package/src/hover/providers/LiquidFilterHoverProvider.ts +3 -3
  174. package/src/hover/providers/LiquidObjectAttributeHoverProvider.spec.ts +1 -3
  175. package/src/hover/providers/LiquidObjectHoverProvider.spec.ts +46 -129
  176. package/src/hover/providers/LiquidTagHoverProvider.spec.ts +0 -3
  177. package/src/hover/providers/LiquidTagHoverProvider.ts +3 -3
  178. package/src/hover/providers/RenderPartialHoverProvider.spec.ts +1 -4
  179. package/src/hover/providers/RenderPartialHoverProvider.ts +1 -5
  180. package/src/hover/providers/RenderPartialParameterHoverProvider.spec.ts +1 -4
  181. package/src/hover/providers/RenderPartialParameterHoverProvider.ts +0 -1
  182. package/src/hover/providers/TranslationHoverProvider.spec.ts +1 -4
  183. package/src/hover/providers/TranslationHoverProvider.ts +3 -3
  184. package/src/index.ts +2 -5
  185. package/src/internal-types.ts +1 -1
  186. package/src/json/JSONContributions.ts +4 -61
  187. package/src/json/JSONLanguageService.ts +19 -117
  188. package/src/json/test/test-helpers.ts +4 -35
  189. package/src/json/utils.ts +0 -27
  190. package/src/progress.ts +4 -1
  191. package/src/rename/RenameProvider.ts +3 -3
  192. package/src/rename/providers/LiquidVariableRenameProvider.spec.ts +4 -4
  193. package/src/rename/providers/LiquidVariableRenameProvider.ts +4 -4
  194. package/src/renamed/RenameHandler.ts +4 -9
  195. package/src/renamed/handlers/AssetRenameHandler.spec.ts +3 -3
  196. package/src/renamed/handlers/AssetRenameHandler.ts +5 -5
  197. package/src/renamed/handlers/PartialRenameHandler.spec.ts +2 -2
  198. package/src/renamed/handlers/PartialRenameHandler.ts +5 -5
  199. package/src/renamed/handlers/utils.ts +1 -1
  200. package/src/server/{ThemeGraphManager.ts → AppGraphManager.ts} +21 -90
  201. package/src/server/Configuration.ts +4 -1
  202. package/src/server/startServer.spec.ts +7 -9
  203. package/src/server/startServer.ts +65 -217
  204. package/src/test/CompletionItemsAssertion.spec.ts +1 -4
  205. package/src/types.ts +33 -63
  206. package/src/utils/liquidDoc.ts +1 -1
  207. package/src/utils/uri.ts +0 -14
  208. package/src/completions/providers/ContentForBlockTypeCompletionProvider.spec.ts +0 -41
  209. package/src/completions/providers/ContentForBlockTypeCompletionProvider.ts +0 -42
  210. package/src/completions/providers/ContentForCompletionProvider.spec.ts +0 -96
  211. package/src/completions/providers/ContentForCompletionProvider.ts +0 -113
  212. package/src/completions/providers/ContentForParameterCompletionProvider.spec.ts +0 -362
  213. package/src/completions/providers/ContentForParameterCompletionProvider.ts +0 -187
  214. package/src/completions/providers/data/contentForParameterCompletionOptions.ts +0 -9
  215. package/src/css/CSSLanguageService.spec.ts +0 -161
  216. package/src/css/test/test-helpers.ts +0 -30
  217. package/src/definitions/providers/SchemaTranslationStringDefinitionProvider.spec.ts +0 -96
  218. package/src/definitions/providers/SchemaTranslationStringDefinitionProvider.ts +0 -82
  219. package/src/hover/providers/ContentForArgumentHoverProvider.spec.ts +0 -76
  220. package/src/hover/providers/ContentForArgumentHoverProvider.ts +0 -56
  221. package/src/hover/providers/ContentForTypeHoverProvider.spec.ts +0 -91
  222. package/src/hover/providers/ContentForTypeHoverProvider.ts +0 -42
  223. package/src/json/JSONLanguageService.spec.ts +0 -424
  224. package/src/json/completions/providers/BlockSettingsPropertyCompletionProvider.spec.ts +0 -163
  225. package/src/json/completions/providers/BlockSettingsPropertyCompletionProvider.ts +0 -121
  226. package/src/json/completions/providers/BlockTypeCompletionProvider.spec.ts +0 -137
  227. package/src/json/completions/providers/BlockTypeCompletionProvider.ts +0 -108
  228. package/src/json/completions/providers/ReferencedBlockTypeCompletionProvider.spec.ts +0 -132
  229. package/src/json/completions/providers/ReferencedBlockTypeCompletionProvider.ts +0 -120
  230. package/src/json/completions/providers/SchemaTranslationCompletionProvider.ts +0 -51
  231. package/src/json/completions/providers/SettingsPropertyCompletionProvider.spec.ts +0 -211
  232. package/src/json/completions/providers/SettingsPropertyCompletionProvider.ts +0 -75
  233. package/src/json/documentLinks/DocumentLinksProvider.spec.ts +0 -223
  234. package/src/json/documentLinks/DocumentLinksProvider.ts +0 -61
  235. package/src/json/hover/providers/BlockSettingsHoverProvider.spec.ts +0 -292
  236. package/src/json/hover/providers/BlockSettingsHoverProvider.ts +0 -99
  237. package/src/json/hover/providers/SchemaTranslationHoverProvider.ts +0 -35
  238. package/src/json/hover/providers/SettingsHoverProvider.spec.ts +0 -139
  239. package/src/json/hover/providers/SettingsHoverProvider.ts +0 -79
  240. package/src/json/schemaSettings.spec.ts +0 -103
  241. package/src/json/schemaSettings.ts +0 -53
  242. package/src/plugins/css.ts +0 -12
  243. package/src/renamed/handlers/BlockRenameHandler.spec.ts +0 -399
  244. package/src/renamed/handlers/BlockRenameHandler.ts +0 -402
  245. package/src/renamed/handlers/SectionRenameHandler.spec.ts +0 -321
  246. package/src/renamed/handlers/SectionRenameHandler.ts +0 -224
  247. 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
- };