@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,137 +0,0 @@
1
- import { describe, it, expect, assert, beforeEach } from 'vitest';
2
- import { JSONLanguageService } from '../../JSONLanguageService';
3
- import { DocumentManager } from '../../../documents';
4
- import { getRequestParams, isCompletionList } from '../../test/test-helpers';
5
-
6
- /**
7
- * We only need this because I want to show in the test that @theme and @app are
8
- * completed by the schema... If you write a test that doesn't have a JOIN on
9
- * the completions, feel free to not copy paste this...
10
- */
11
- const simplifiedBlockSchema = JSON.stringify({
12
- $schema: 'http://json-schema.org/draft-07/schema#',
13
- type: 'object',
14
- additionalProperties: false,
15
- properties: {
16
- blocks: {
17
- type: 'array',
18
- items: {
19
- type: 'object',
20
- required: ['type'],
21
- properties: {
22
- type: {
23
- oneOf: [
24
- // blocks[].type is @app, @theme or a string
25
- { const: '@app' },
26
- { const: '@theme' },
27
- {
28
- if: { not: { enum: ['@theme', '@app'] } },
29
- then: { type: 'string' },
30
- },
31
- ],
32
- },
33
- },
34
- },
35
- },
36
- },
37
- });
38
-
39
- describe('Unit: BlockTypeCompletionProvider', () => {
40
- let jsonLanguageService: JSONLanguageService;
41
- let documentManager: DocumentManager;
42
- const blockNames = ['block-1', 'block-2', 'custom-block'];
43
-
44
- beforeEach(async () => {
45
- documentManager = new DocumentManager(
46
- undefined, // don't need a fs
47
- undefined, // don't need a connection
48
- undefined, // don't need client capabilities
49
- async () => 'theme', // 'theme' mode
50
- async () => false, // schema is invalid for tests
51
- );
52
- jsonLanguageService = new JSONLanguageService(
53
- documentManager,
54
- {
55
- schemas: async () => [
56
- {
57
- uri: 'https://shopify.dev/block-schema.json',
58
- schema: simplifiedBlockSchema,
59
- fileMatch: ['**/{blocks,sections}/*.liquid'], // cheating a little here...
60
- },
61
- ],
62
- },
63
- async () => ({}),
64
- async () => 'theme',
65
- async () => blockNames,
66
- async () => undefined,
67
- async () => 'file:///test-root',
68
- );
69
-
70
- await jsonLanguageService.setup({
71
- textDocument: {
72
- completion: {
73
- contextSupport: true,
74
- completionItem: {
75
- snippetSupport: true,
76
- commitCharactersSupport: true,
77
- documentationFormat: ['markdown'],
78
- deprecatedSupport: true,
79
- preselectSupport: true,
80
- },
81
- },
82
- },
83
- });
84
- });
85
-
86
- describe('when there are no local blocks', () => {
87
- it('completes theme block names', async () => {
88
- const source = `
89
- hello world
90
- {% schema %}
91
- {
92
- "blocks": [
93
- { "type": "█" }
94
- ]
95
- }
96
- {% endschema %}
97
- `;
98
- const params = getRequestParams(documentManager, 'sections/section.liquid', source);
99
-
100
- const completions = await jsonLanguageService.completions(params);
101
-
102
- assert(isCompletionList(completions));
103
- // @app & @theme come from the JSON schema. There's no way to not include them.
104
- expect(completions.items).to.have.lengthOf(blockNames.length + ['@app', '@theme'].length);
105
- expect(completions.items.map((item) => item.label)).to.include.members([
106
- '"@app"',
107
- '"@theme"',
108
- ...blockNames.map((x) => `"${x}"`),
109
- ]);
110
- });
111
- });
112
-
113
- describe('when there are local blocks', () => {
114
- it('does not completes theme block names', async () => {
115
- const source = `
116
- hello world
117
- {% schema %}
118
- {
119
- "blocks": [
120
- { "type": "user-defined", "name": "user defined" }
121
- { "type": "█" }
122
- ]
123
- }
124
- {% endschema %}
125
- `;
126
- const params = getRequestParams(documentManager, 'sections/section.liquid', source);
127
-
128
- const completions = await jsonLanguageService.completions(params);
129
-
130
- assert(isCompletionList(completions));
131
- expect(completions.items).to.have.lengthOf(['@app', '@theme'].length);
132
- expect(completions.items.map((item) => item.label)).not.to.include.members([
133
- ...blockNames.map((x) => `"${x}"`),
134
- ]);
135
- });
136
- });
137
- });
@@ -1,108 +0,0 @@
1
- import {
2
- AppBlockSchema,
3
- deepGet,
4
- isError,
5
- SectionSchema,
6
- ThemeBlockSchema,
7
- ThemeSchemaType,
8
- } from '@platformos/platformos-check-common';
9
- import { JSONPath } from 'vscode-json-languageservice';
10
- import { JSONCompletionItem } from 'vscode-json-languageservice/lib/umd/jsonContributions';
11
- import { CompletionItemKind } from 'vscode-languageserver-protocol';
12
- import { isLiquidRequestContext, RequestContext } from '../../RequestContext';
13
- import { isSectionOrBlockFile } from '../../utils';
14
- import { JSONCompletionProvider } from '../JSONCompletionProvider';
15
- import { GetThemeBlockNames } from '../../JSONContributions';
16
-
17
- /**
18
- * The BlockTypeCompletionProvider offers value completions of the
19
- * `blocks.[].type` property inside section and theme block `{% schema %}` tags.
20
- *
21
- * @example
22
- * {% schema %}
23
- * {
24
- * "blocks": [
25
- * { "type": "█" },
26
- * ]
27
- * }
28
- * {% endschema %}
29
- */
30
- export class BlockTypeCompletionProvider implements JSONCompletionProvider {
31
- constructor(private getThemeBlockNames: GetThemeBlockNames) {}
32
-
33
- async completeValue(context: RequestContext, path: JSONPath): Promise<JSONCompletionItem[]> {
34
- if (
35
- !isSectionOrBlockFile(context.doc.uri) ||
36
- !isLiquidRequestContext(context) ||
37
- !isBlockDefinitionPath(path)
38
- ) {
39
- return [];
40
- }
41
- const { doc } = context;
42
- const schema = await doc.getSchema();
43
-
44
- // Can't complete if we can't parse the schema
45
- if (!schema || isError(schema.parsed) || !isSectionOrBlockSchema(schema)) {
46
- return [];
47
- }
48
-
49
- // Local blocks have their type defined in the schema, there's nothing to complete
50
- if (hasLocalBlockDefinitions(schema)) return [];
51
-
52
- const blockNames = await this.getThemeBlockNames(doc.uri, true);
53
-
54
- return createBlockNameCompletionItems(blockNames);
55
- }
56
- }
57
-
58
- export function createBlockNameCompletionItems(blockNames: string[]) {
59
- return blockNames.map((name) => ({
60
- kind: CompletionItemKind.Value,
61
- label: `"${name}"`,
62
- insertText: `"${name}"`,
63
- }));
64
- }
65
-
66
- export function isBlockDefinitionPath(path: JSONPath) {
67
- return path.at(0) === 'blocks';
68
- }
69
-
70
- export function isPresetBlockPath(path: JSONPath) {
71
- return path.at(0) === 'presets';
72
- }
73
-
74
- export function isBlockTypePath(path: JSONPath) {
75
- // We have these cases to support:
76
- // - top level blocks.[].type
77
- // - presets.[](recursive .blocks.[].type)
78
- // - presets.[](recursive .blocks.{}.type)
79
- const topLevel = path.at(0);
80
- if (topLevel !== 'blocks' && topLevel !== 'presets') return false;
81
- if (path.length < 4) return false; // minimum path length
82
- const [shouldBeBlocks, _idOrIndex, shouldBeType] = path.slice(-3);
83
- return shouldBeBlocks === 'blocks' && shouldBeType === 'type';
84
- }
85
-
86
- export function hasLocalBlockDefinitions(schema: SectionSchema | ThemeBlockSchema) {
87
- if (schema.type !== ThemeSchemaType.Section || isError(schema.parsed)) return false;
88
- const blocks = deepGet(schema.parsed, ['blocks']);
89
- if (!blocks || !Array.isArray(blocks)) return false;
90
- return blocks.some((block) => block && block.name !== undefined);
91
- }
92
-
93
- export function isLocalBlockDefinition(
94
- schema: ThemeBlockSchema | SectionSchema,
95
- blockTypePath: JSONPath,
96
- ) {
97
- if (schema.type !== ThemeSchemaType.Section) return false;
98
- const blockNamePath = [...blockTypePath.slice(0, -1), 'name'];
99
- const name = deepGet(schema.parsed, blockNamePath);
100
- return name !== undefined;
101
- }
102
-
103
- const SectionOrBlockSchemaTypes = [ThemeSchemaType.Section, ThemeSchemaType.Block];
104
- export function isSectionOrBlockSchema(
105
- schema: SectionSchema | ThemeBlockSchema | AppBlockSchema,
106
- ): schema is SectionSchema | ThemeBlockSchema {
107
- return SectionOrBlockSchemaTypes.includes(schema.type);
108
- }
@@ -1,132 +0,0 @@
1
- import { describe, it, expect, assert, beforeEach } from 'vitest';
2
- import { JSONLanguageService } from '../../JSONLanguageService';
3
- import { DocumentManager } from '../../../documents';
4
- import {
5
- getRequestParams,
6
- isCompletionList,
7
- mockJSONLanguageService,
8
- } from '../../test/test-helpers';
9
-
10
- describe('Unit: ReferencedBlockTypeCompletionProvider', () => {
11
- const rootUri = 'file:///root/';
12
- let jsonLanguageService: JSONLanguageService;
13
- let documentManager: DocumentManager;
14
-
15
- beforeEach(async () => {
16
- documentManager = new DocumentManager(
17
- undefined, // don't need a fs
18
- undefined, // don't need a connection
19
- undefined, // don't need client capabilities
20
- async () => 'theme', // 'theme' mode
21
- async () => false, // schema is invalid for tests
22
- );
23
- jsonLanguageService = mockJSONLanguageService(rootUri, documentManager, undefined, async () => [
24
- 'block-1',
25
- 'block-2',
26
- 'custom-block',
27
- ]);
28
-
29
- await jsonLanguageService.setup({
30
- textDocument: {
31
- completion: {
32
- contextSupport: true,
33
- completionItem: {
34
- snippetSupport: true,
35
- commitCharactersSupport: true,
36
- documentationFormat: ['markdown'],
37
- deprecatedSupport: true,
38
- preselectSupport: true,
39
- },
40
- },
41
- },
42
- });
43
- });
44
-
45
- const tests = [
46
- {
47
- description: 'select blocks',
48
- configured: [{ type: 'block-1' }],
49
- expected: [`"block-1"`],
50
- },
51
- {
52
- description: '@theme block',
53
- configured: [{ type: '@theme' }],
54
- expected: [`"block-1"`, `"block-2"`, `"custom-block"`],
55
- },
56
- {
57
- description: '@app block',
58
- configured: [{ type: '@app' }],
59
- expected: [],
60
- },
61
- {
62
- description: 'no blocks',
63
- configured: [],
64
- expected: [],
65
- },
66
- ];
67
-
68
- describe('top-level preset blocks', () => {
69
- for (const test of tests) {
70
- it(`completes preset block type when allowed ${test.description}`, async () => {
71
- const source = `
72
- {% schema %}
73
- {
74
- "blocks": ${JSON.stringify(test.configured)},
75
- "presets": [{
76
- "blocks": [
77
- { "type": "█" },
78
- ]
79
- }]
80
- }
81
- {% endschema %}
82
- `;
83
-
84
- const params = getRequestParams(documentManager, 'sections/section.liquid', source);
85
- const completions = await jsonLanguageService.completions(params);
86
-
87
- assert(isCompletionList(completions));
88
- expect(completions.items).to.have.lengthOf(test.expected.length);
89
- expect(completions.items.map((item) => item.label)).to.include.members(test.expected);
90
- });
91
- }
92
- });
93
-
94
- describe('nested preset blocks', () => {
95
- for (const test of tests) {
96
- it(`completes preset block type when parent block allows ${test.description}`, async () => {
97
- const source = `
98
- {% schema %}
99
- {
100
- "blocks": [{"type": "custom-block"}],
101
- "presets": [{
102
- "blocks": [
103
- {
104
- "type": "custom-block",
105
- "blocks": [{"type": "█"}],
106
- },
107
- ]
108
- }]
109
- }
110
- {% endschema %}
111
- `;
112
-
113
- documentManager.open(
114
- `${rootUri}/blocks/custom-block.liquid`,
115
- `{% schema %}
116
- {
117
- "blocks": ${JSON.stringify(test.configured)}
118
- }
119
- {% endschema %}`,
120
- 1,
121
- );
122
-
123
- const params = getRequestParams(documentManager, 'sections/section.liquid', source);
124
- const completions = await jsonLanguageService.completions(params);
125
-
126
- assert(isCompletionList(completions));
127
- expect(completions.items).to.have.lengthOf(test.expected.length);
128
- expect(completions.items.map((item) => item.label)).to.include.members(test.expected);
129
- });
130
- }
131
- });
132
- });
@@ -1,120 +0,0 @@
1
- import { deepGet, isError } from '@platformos/platformos-check-common';
2
- import { JSONPath } from 'vscode-json-languageservice';
3
- import { JSONCompletionItem } from 'vscode-json-languageservice/lib/umd/jsonContributions';
4
- import { isLiquidRequestContext, RequestContext } from '../../RequestContext';
5
- import { isSectionOrBlockFile } from '../../utils';
6
- import { JSONCompletionProvider } from '../JSONCompletionProvider';
7
- import {
8
- createBlockNameCompletionItems,
9
- isSectionOrBlockSchema,
10
- } from './BlockTypeCompletionProvider';
11
- import { GetThemeBlockNames, GetThemeBlockSchema } from '../../JSONContributions';
12
-
13
- /**
14
- * The ReferencedBlockTypeCompletionProvider offers value completions of the
15
- * `presets.[](recursive .blocks.[]).type` value and `default.blocks.[].type` value inside
16
- * section and theme block `{% schema %}` tags.
17
- *
18
- * @example
19
- * {% schema %}
20
- * {
21
- * "presets": [
22
- * {
23
- * "blocks": [
24
- * { "type": "█" },
25
- * ]
26
- * },
27
- * ],
28
- * "default": {
29
- * "blocks": [
30
- * { "type": "█" },
31
- * ]
32
- * }
33
- * }
34
- * {% endschema %}
35
- */
36
- export class ReferencedBlockTypeCompletionProvider implements JSONCompletionProvider {
37
- constructor(
38
- private getThemeBlockNames: GetThemeBlockNames,
39
- private getThemeBlockSchema: GetThemeBlockSchema,
40
- ) {}
41
-
42
- async completeValue(context: RequestContext, path: JSONPath): Promise<JSONCompletionItem[]> {
43
- if (
44
- !isSectionOrBlockFile(context.doc.uri) ||
45
- !isLiquidRequestContext(context) ||
46
- !isBlockTypePath(path)
47
- ) {
48
- return [];
49
- }
50
-
51
- const { doc } = context;
52
- const schema = await doc.getSchema();
53
-
54
- if (!schema || isError(schema.parsed) || !isSectionOrBlockSchema(schema)) {
55
- return [];
56
- }
57
-
58
- let parsedBlockSchema = schema.parsed;
59
-
60
- if (isNestedBlockPath(path)) {
61
- const parentBlockName = getParentBlockName(schema.parsed, path);
62
- if (!parentBlockName) {
63
- return [];
64
- }
65
-
66
- const parentBlockSchema = await this.getThemeBlockSchema(doc.uri, parentBlockName);
67
-
68
- if (
69
- !parentBlockSchema ||
70
- isError(parentBlockSchema.parsed) ||
71
- !isSectionOrBlockSchema(parentBlockSchema)
72
- ) {
73
- return [];
74
- }
75
-
76
- parsedBlockSchema = parentBlockSchema.parsed;
77
- }
78
-
79
- const blocks: { type: string }[] = parsedBlockSchema.blocks || [];
80
-
81
- const blockGroups = {
82
- themeBlocks: false,
83
- specificBlockNames: [] as string[],
84
- };
85
-
86
- blocks.forEach((block) => {
87
- if (block.type === '@theme') {
88
- blockGroups.themeBlocks = true;
89
- } else if (!block.type.startsWith('@')) {
90
- blockGroups.specificBlockNames.push(block.type);
91
- }
92
- });
93
-
94
- let blockNames = blockGroups.specificBlockNames;
95
-
96
- if (blockGroups.themeBlocks) {
97
- blockNames.push(...(await this.getThemeBlockNames(doc.uri, false)));
98
- }
99
-
100
- return createBlockNameCompletionItems(blockNames);
101
- }
102
- }
103
-
104
- // `blocks` can be nested within other `blocks`
105
- // We need to ensure the last leg of the path is { "blocks": [{ "type": "█" }] }
106
- function isBlockTypePath(path: JSONPath) {
107
- return (
108
- (path.at(0) === 'presets' || path.at(0) === 'default') &&
109
- path.at(-3) === 'blocks' &&
110
- path.at(-1) === 'type'
111
- );
112
- }
113
-
114
- function isNestedBlockPath(path: JSONPath) {
115
- return path.at(-5) === 'blocks' && path.at(-3) === 'blocks' && path.at(-1) === 'type';
116
- }
117
-
118
- function getParentBlockName(parsedSchema: any, path: JSONPath) {
119
- return deepGet(parsedSchema, [...path.slice(0, -3), 'type']);
120
- }
@@ -1,51 +0,0 @@
1
- import { deepGet } from '@platformos/platformos-check-common';
2
- import { CompletionItemKind, JSONPath } from 'vscode-json-languageservice';
3
- import {
4
- GetTranslationsForURI,
5
- renderTranslation,
6
- translationOptions,
7
- } from '../../../translations';
8
- import { isLiquidRequestContext, RequestContext } from '../../RequestContext';
9
- import { isSectionOrBlockFile } from '../../utils';
10
- import { JSONCompletionItem, JSONCompletionProvider } from '../JSONCompletionProvider';
11
-
12
- export class SchemaTranslationsCompletionProvider implements JSONCompletionProvider {
13
- constructor(private getDefaultSchemaTranslations: GetTranslationsForURI) {}
14
-
15
- async completeValue(context: RequestContext, path: JSONPath): Promise<JSONCompletionItem[]> {
16
- if (!isSectionOrBlockFile(context.doc.uri) || !isLiquidRequestContext(context)) {
17
- return [];
18
- }
19
-
20
- const { doc, parsed } = context;
21
-
22
- const label = deepGet(parsed, path);
23
- if (!label || typeof label !== 'string' || !label.startsWith('t:')) {
24
- return [];
25
- }
26
-
27
- const partial = /^t:(.*)/.exec(label)?.[1];
28
- if (partial === undefined) return [];
29
-
30
- const translations = await this.getDefaultSchemaTranslations(doc.uri);
31
-
32
- // We'll let the frontend do the filtering. But we'll only include shopify
33
- // translations if the shopify prefix is present
34
- const options = translationOptions(translations);
35
-
36
- return options.map((option): JSONCompletionItem => {
37
- const tLabel = `t:${option.path.join('.')}`;
38
- return {
39
- label: tLabel,
40
- kind: CompletionItemKind.Value,
41
- filterText: `"${tLabel}"`,
42
- insertText: `"${tLabel}"`,
43
- insertTextFormat: 1,
44
- documentation: {
45
- kind: 'markdown',
46
- value: renderTranslation(option.translation),
47
- },
48
- };
49
- });
50
- }
51
- }