Skip to content

Commit 1563921

Browse files
authored
Merge pull request #174 from panoply/next
v4.0.1
2 parents ccf49d6 + 363c6b1 commit 1563921

22 files changed

Lines changed: 1529 additions & 369 deletions

.vscode/settings.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,9 @@
2525
],
2626
"liquid.format.rules": {
2727
"json": {}
28+
},
29+
"[liquid]": {
30+
"editor.defaultFormatter": "sissel.shopify-liquid",
31+
"editor.formatOnSave": true
2832
}
2933
}

extension/data/liquid.ts

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import slash, { entries, keys } from 'utils';
1+
import slash, { entries, isArray, isBoolean, isNumber, isObject, isString, keys } from 'utils';
22
import { basename, join, dirname } from 'node:path';
3-
import { Filter, Tags, IObject, Type, Types, liquid, IProperty, $, p } from '@liquify/specs';
3+
import { Filter, Tags, IObject, Type, Types, liquid, IProperty, $, p, Engine } from '@liquify/specs';
44
import { mdString, settingsType } from 'parse/helpers';
55
import { has, path } from 'rambdax';
66
import { Complete, SettingsSchema } from 'types';
@@ -249,6 +249,66 @@ export function getSettingsCompletions (uri: string, data: SettingsSchema[]) {
249249
return liquid.shopify.objects;
250250
};
251251

252+
export function getEleventyDataComponents (uri: string) {
253+
254+
const objects:{ [prop: string]: IProperty } = { data: { type: Type.any } };
255+
256+
const build = (function traverse (data, spec?: IProperty) {
257+
258+
if (spec) {
259+
if (spec.type === Type.object) {
260+
261+
for (const prop in data) {
262+
263+
if (isString(data[prop])) {
264+
spec.properties[prop] = { type: Type.string };
265+
} else if (isBoolean(data[prop])) {
266+
spec.properties[prop] = { type: Type.boolean };
267+
} else if (isObject(data[prop])) {
268+
spec.properties[prop] = { type: Type.object };
269+
traverse(data[prop], spec.properties[prop]);
270+
} else if (isNumber(data[prop])) {
271+
spec.properties[prop] = { type: Type.number };
272+
} else if (isArray(data[prop])) {
273+
spec.properties[prop] = { type: Type.array };
274+
traverse(data[prop], spec.properties[prop]);
275+
}
276+
277+
}
278+
}
279+
} else {
280+
281+
if (isObject(data)) {
282+
283+
for (const item in data) {
284+
285+
if (isObject(data[item])) {
286+
objects[item] = { type: Type.object, properties: {} };
287+
traverse(data[item], objects[item]);
288+
} else if (isArray(data[item])) {
289+
objects[item] = { type: Type.array };
290+
}
291+
}
292+
293+
}
294+
295+
if (isArray(data)) {
296+
for (const item of data) {
297+
objects[item] = { type: Type.array };
298+
for (const value of data[item]) {
299+
traverse(value, objects[item]);
300+
}
301+
}
302+
}
303+
}
304+
305+
return objects;
306+
307+
})($.liquid.files.get(uri));
308+
309+
liquid.extend(Engine.standard, { objects: build });
310+
311+
}
252312
/**
253313
* Get Locale Completions
254314
*

extension/extension.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Engines } from '@liquify/specs';
44
import { Config, URI, Meta, Files } from './typings/store';
55
import { Liquidrc, PackageJSON } from './typings/files';
66
import { Selectors, LanguageIds } from './typings/document';
7-
import { ConfigurationTarget, Extension as IExtension, Uri, workspace, Disposable, EventEmitter } from 'vscode';
7+
import { ConfigurationTarget, Extension as IExtension, Uri, workspace, EventEmitter } from 'vscode';
88
import { ConfigMethod } from './typings/enums';
99
import { Service } from './services';
1010
import { FormatEvent } from 'providers/FormattingProvider';
@@ -105,7 +105,7 @@ export class Extension extends Service {
105105
layouts: null
106106
},
107107
'11ty': {
108-
data: null,
108+
data: new Set(),
109109
includes: new Set(),
110110
layouts: new Set()
111111
},

extension/providers/DocumentLinkProvider.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export class DocumentLinkProvider implements IDocumentLinkProvider {
2828
/**
2929
*The `settings_schema.json` URI
3030
*/
31-
settings: Uri;
31+
settings: Uri = null;
3232

3333
/**
3434
* Render Tag URI's
@@ -44,8 +44,13 @@ export class DocumentLinkProvider implements IDocumentLinkProvider {
4444
const content = document.getText();
4545
const links: DocumentLink[] = [];
4646

47-
this.getSnippetLinks(document, content, links);
48-
this.getSettingsLinks(document, content, links);
47+
if (this.snippets.length > 0) {
48+
this.getSnippetLinks(document, content, links);
49+
}
50+
51+
if (this.settings !== null) {
52+
this.getSettingsLinks(document, content, links);
53+
}
4954

5055
return links;
5156

extension/providers/HoverProvider.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ function walkProps (cursor: string, next: string[], object: IProperty) {
4545

4646
export function getPropertyHover (cursor: string, token: string, objects: string[]) {
4747

48-
if (!$.liquid.data.variation?.objects) return null;
48+
if (!$.liquid.data.variation?.objects?.[token]) return null;
4949

5050
const root = $.liquid.data.variation.objects[token];
5151

@@ -55,7 +55,12 @@ export function getPropertyHover (cursor: string, token: string, objects: string
5555
return mdString(root.description, root.reference);
5656
}
5757

58+
if (!('properties' in root)) return null;
59+
5860
const prop = objects.shift();
61+
62+
if (!(prop in root.properties)) return null;
63+
5964
const spec = walkProps(cursor, objects, root.properties[prop]);
6065

6166
return mdString(spec.description, root.reference);

extension/services/JSONLanguageService.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ export class JSONLanguageProvider {
125125
extend (uri: Uri, shared: SharedSchema) {
126126

127127
this.schema = getSharedSchema(uri, shared, this.schema);
128+
this.configure();
128129

129130
}
130131

extension/typings/schema.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* eslint-disable no-unused-vars */
22

3-
import { LiteralUnion, Merge } from 'type-fest';
3+
import { LiteralUnion } from 'type-fest';
44
import { Position, TextDocument } from 'vscode';
55

66
export interface SchemaRegion {

extension/workspace/WorkspaceSettings.ts

Lines changed: 89 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { has, isNil, difference, hasPath, isEmpty, equals, T } from 'rambdax';
1717
import anymatch from 'anymatch';
1818
import { OutputChannel } from './OutputChannel';
1919
import * as u from '../utils';
20-
import { getSettingsCompletions } from 'data/liquid';
20+
import { getEleventyDataComponents, getSettingsCompletions } from 'data/liquid';
2121
import { $ } from '@liquify/specs';
2222

2323
export class WorkspaceSettings extends OutputChannel {
@@ -305,6 +305,8 @@ export class WorkspaceSettings extends OutputChannel {
305305
}
306306
}
307307

308+
if (input === undefined) return;
309+
308310
for (let i = 0; i < input.length; i++) {
309311

310312
const path = input[i];
@@ -456,6 +458,60 @@ export class WorkspaceSettings extends OutputChannel {
456458
return this;
457459
}
458460

461+
/**
462+
* Set Settings File
463+
*
464+
* Function method for data files in Eleventy
465+
*/
466+
async setDataFile () {
467+
468+
let config: 'workspace' | '.liquidrc';
469+
let input: string[];
470+
471+
if (this.config.sources.files.data === ConfigMethod.Workspace) {
472+
config = 'workspace';
473+
input = workspace.getConfiguration().get<string[]>('liquid.files.11ty.data');
474+
} else {
475+
config = '.liquidrc';
476+
input = (this.liquidrc.files as { data: string[] }).data;
477+
}
478+
479+
for (let i = 0; i < input.length; i++) {
480+
481+
const path = input[i];
482+
const relative = new RelativePattern(this.uri.root, u.refineURI(path));
483+
const paths = await workspace.findFiles(relative);
484+
485+
for (const entry of paths) {
486+
487+
const file = Uri.file(path);
488+
489+
if (!file.fsPath.endsWith('.json')) {
490+
this.warn(`Unable to resolve data (File must be a JSON file type): ${path}`);
491+
continue;
492+
}
493+
494+
try {
495+
496+
const data = await u.parseJsonFile<any>(entry);
497+
498+
$.liquid.files.set(file.fsPath, data);
499+
500+
getEleventyDataComponents(file.fsPath);
501+
502+
} catch (e) {
503+
504+
this.catch('JSON Error', e);
505+
506+
}
507+
508+
}
509+
}
510+
511+
return this;
512+
513+
}
514+
459515
/**
460516
* Set Settings File
461517
*
@@ -722,7 +778,7 @@ export class WorkspaceSettings extends OutputChannel {
722778
]) {
723779
if (has(v, settings) && u.isBoolean(settings[v])) {
724780
if (v === 'schema' && this.engine !== 'shopify') {
725-
this.warn('Hovers for {% schema %} only work in the Shopify variation');
781+
continue;
726782
} else {
727783

728784
if (settings[v] !== this.hovers.enable[v]) {
@@ -751,20 +807,18 @@ export class WorkspaceSettings extends OutputChannel {
751807
const settings = workspace.getConfiguration().get<Workspace.Validate>('liquid.validate');
752808

753809
if (has('schema', settings) && u.isBoolean(settings.schema)) {
754-
if (this.engine !== 'shopify') {
755-
this.warn('Validations for {% schema %} only work when the Liquid "engine" is Shopify');
756-
} else {
810+
if (this.engine !== 'shopify') return;
757811

758-
if (settings.schema !== this.json.config.validate) {
759-
if (settings.schema) {
760-
this.info('Enabled {% schema %} validations');
761-
} else {
762-
this.info('Disable {% schema %} validations');
763-
}
812+
if (settings.schema !== this.json.config.validate) {
813+
if (settings.schema) {
814+
this.info('Enabled {% schema %} validations');
815+
} else {
816+
this.info('Disable {% schema %} validations');
764817
}
765-
766-
this.json.config.validate = settings.schema;
767818
}
819+
820+
this.json.config.validate = settings.schema;
821+
768822
}
769823

770824
}
@@ -796,17 +850,17 @@ export class WorkspaceSettings extends OutputChannel {
796850

797851
if (has(v, settings) && u.isBoolean(settings[v])) {
798852

799-
if (v === 'section' || v === 'objects' || v === 'schema') {
853+
if (v === 'sections' || v === 'objects' || v === 'schema') {
800854
if (this.engine !== 'shopify' && settings[v] === true) {
801-
this.warn(`Completion for ${v} will not work in Liquid ${u.upcase(this.engine)}`);
855+
continue;
802856
}
803857
}
804858

805859
if (settings[v] !== this.completion.enable[v]) {
806860
if (settings[v]) {
807-
this.info(`enabled ${v} completions`);
861+
this.info(`Enabled ${v} completions`);
808862
} else {
809-
this.info(`disabled ${v} completions`);
863+
this.info(`Disabled ${v} completions`);
810864
}
811865
}
812866

@@ -1107,10 +1161,18 @@ export class WorkspaceSettings extends OutputChannel {
11071161
this.getEngine();
11081162
this.getFormatRules();
11091163

1110-
await this.getFileCompletions([ 'sections', 'snippets' ]);
1111-
await this.setLocaleFile();
1112-
await this.setSettingsFile();
1113-
await this.getSharedSchema();
1164+
if (this.engine === 'shopify') {
1165+
1166+
await this.getFileCompletions([ 'sections', 'snippets' ]);
1167+
await this.setLocaleFile();
1168+
await this.setSettingsFile();
1169+
await this.getSharedSchema();
1170+
1171+
} else if (this.engine === '11ty' || this.engine === 'eleventy') {
1172+
1173+
await this.getFileCompletions([ 'includes', 'layouts' ]);
1174+
1175+
}
11141176

11151177
}
11161178

@@ -1280,6 +1342,7 @@ export class WorkspaceSettings extends OutputChannel {
12801342

12811343
this.config.target = ConfigurationTarget.Workspace;
12821344
this.config.inspect = 'workspaceValue';
1345+
12831346
} else {
12841347
this.config.target = ConfigurationTarget.Global;
12851348
this.config.inspect = 'globalValue';
@@ -1305,19 +1368,19 @@ export class WorkspaceSettings extends OutputChannel {
13051368

13061369
await this.getFileSource();
13071370

1308-
if (this.engine === 'shopify') {
1371+
if (this.config.method === ConfigMethod.Workspace) {
1372+
if (this.engine === 'shopify') {
13091373

1310-
if (this.config.method === ConfigMethod.Workspace) {
13111374
await this.getFileCompletions([ 'sections', 'snippets' ]);
13121375
await this.setLocaleFile();
13131376
await this.setSettingsFile();
13141377
await this.getSharedSchema();
1315-
}
13161378

1317-
} else if (this.engine === '11ty' || this.engine === 'eleventy') {
1379+
} else if (this.engine === '11ty' || this.engine === 'eleventy') {
13181380

1319-
await this.getFileCompletions([ 'data', 'includes', 'layouts' ]);
1381+
await this.getFileCompletions([ 'includes', 'layouts' ]);
13201382

1383+
}
13211384
}
13221385

13231386
this.getCompletions();

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"publisher": "sissel",
66
"icon": "images/logo.png",
77
"author": "Νίκος Σαβίδης <n.savvidis@gmx.com>",
8-
"version": "4.0.0",
8+
"version": "4.0.1",
99
"keywords": [
1010
"liquid",
1111
"shopify",
@@ -1293,7 +1293,7 @@
12931293
},
12941294
"scripts": {
12951295
"dev": "tsup --watch",
1296-
"build": "tsup --onSuccess \"vsce package --no-dependencies\"",
1296+
"build": "tsup --minify --onSuccess \"vsce package --no-dependencies\"",
12971297
"dry": "vsce ls package --no-dependencies",
12981298
"schema": "node ./scripts/schemas.cjs",
12991299
"grammar": "node ./scripts/grammars.cjs"

releases/readme.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ The extension is currently in the version **4.x.x** range.
66

77
## v4.0.0 ~ Latest
88

9-
The extension is currently shipping on version 4.
9+
The extension is currently shipping on version 4
1010

11+
- [4.0.1](/releases/v4/4.0.1.md)
1112
- [4.0.0](/releases/v4/4.0.0.md)
1213

1314
## v3.0.0 ~ v3.2.2

0 commit comments

Comments
 (0)