@platformos/platformos-check-common 0.0.8 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/README.md +4 -4
- package/dist/checks/graphql-variables/index.js +4 -0
- package/dist/checks/graphql-variables/index.js.map +1 -1
- package/dist/checks/img-width-and-height/index.js +1 -1
- package/dist/checks/img-width-and-height/index.js.map +1 -1
- package/dist/checks/index.d.ts +1 -1
- package/dist/checks/json-syntax-error/index.js +1 -1
- package/dist/checks/json-syntax-error/index.js.map +1 -1
- package/dist/checks/liquid-html-syntax-error/checks/InvalidLoopArguments.js +1 -1
- package/dist/checks/liquid-html-syntax-error/checks/InvalidLoopArguments.js.map +1 -1
- package/dist/checks/liquid-html-syntax-error/checks/InvalidTagSyntax.d.ts +19 -0
- package/dist/checks/liquid-html-syntax-error/checks/InvalidTagSyntax.js +79 -0
- package/dist/checks/liquid-html-syntax-error/checks/InvalidTagSyntax.js.map +1 -0
- package/dist/checks/liquid-html-syntax-error/checks/UnknownTag.d.ts +3 -0
- package/dist/checks/liquid-html-syntax-error/checks/UnknownTag.js +32 -0
- package/dist/checks/liquid-html-syntax-error/checks/UnknownTag.js.map +1 -0
- package/dist/checks/liquid-html-syntax-error/index.js +21 -3
- package/dist/checks/liquid-html-syntax-error/index.js.map +1 -1
- package/dist/checks/matching-translations/index.js +103 -68
- package/dist/checks/matching-translations/index.js.map +1 -1
- package/dist/checks/metadata-params/index.js +1 -1
- package/dist/checks/missing-partial/index.js +6 -6
- package/dist/checks/undefined-object/index.js +6 -1
- package/dist/checks/undefined-object/index.js.map +1 -1
- package/dist/checks/unused-assign/index.js +1 -1
- package/dist/checks/unused-assign/index.js.map +1 -1
- package/dist/checks/valid-json/index.js +1 -1
- package/dist/checks/valid-json/index.js.map +1 -1
- package/dist/context-utils.d.ts +16 -0
- package/dist/context-utils.js +30 -1
- package/dist/context-utils.js.map +1 -1
- package/dist/disabled-checks/index.js +2 -4
- package/dist/disabled-checks/index.js.map +1 -1
- package/dist/disabled-checks/test-checks.js +4 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.js +17 -1
- package/dist/index.js.map +1 -1
- package/dist/liquid-doc/arguments.js +10 -3
- package/dist/liquid-doc/arguments.js.map +1 -1
- package/dist/liquid-doc/utils.d.ts +4 -4
- package/dist/liquid-doc/utils.js +13 -3
- package/dist/liquid-doc/utils.js.map +1 -1
- package/dist/path.d.ts +1 -1
- package/dist/path.js +12 -1
- package/dist/path.js.map +1 -1
- package/dist/test/MockApp.d.ts +2 -2
- package/dist/test/MockApp.js +2 -2
- package/dist/test/test-helper.d.ts +7 -7
- package/dist/test/test-helper.js +24 -24
- package/dist/test/test-helper.js.map +1 -1
- package/dist/to-source-code.d.ts +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types.d.ts +8 -0
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
- package/src/checks/duplicate-render-partial-arguments/index.spec.ts +12 -12
- package/src/checks/graphql-variables/index.spec.ts +95 -0
- package/src/checks/graphql-variables/index.ts +4 -0
- package/src/checks/img-width-and-height/index.ts +1 -1
- package/src/checks/invalid-hash-assign-target/index.spec.ts +26 -26
- package/src/checks/json-syntax-error/index.ts +1 -1
- package/src/checks/liquid-html-syntax-error/checks/InvalidLoopArguments.ts +2 -2
- package/src/checks/liquid-html-syntax-error/checks/InvalidTagSyntax.spec.ts +259 -0
- package/src/checks/liquid-html-syntax-error/checks/InvalidTagSyntax.ts +89 -0
- package/src/checks/liquid-html-syntax-error/checks/UnknownTag.spec.ts +293 -0
- package/src/checks/liquid-html-syntax-error/checks/UnknownTag.ts +43 -0
- package/src/checks/liquid-html-syntax-error/index.ts +24 -3
- package/src/checks/matching-translations/index.spec.ts +114 -24
- package/src/checks/matching-translations/index.ts +102 -81
- package/src/checks/metadata-params/index.ts +1 -1
- package/src/checks/missing-partial/index.ts +6 -6
- package/src/checks/undefined-object/index.spec.ts +29 -2
- package/src/checks/undefined-object/index.ts +7 -1
- package/src/checks/unused-assign/index.ts +1 -1
- package/src/checks/valid-json/index.ts +1 -1
- package/src/checks/valid-render-partial-argument-types/index.spec.ts +13 -13
- package/src/context-utils.ts +42 -1
- package/src/disabled-checks/index.spec.ts +26 -61
- package/src/disabled-checks/index.ts +2 -4
- package/src/disabled-checks/test-checks.ts +4 -4
- package/src/ignore.spec.ts +4 -4
- package/src/index.ts +18 -0
- package/src/liquid-doc/arguments.ts +9 -3
- package/src/liquid-doc/liquidDoc.spec.ts +1 -1
- package/src/liquid-doc/utils.ts +13 -5
- package/src/path.ts +16 -1
- package/src/test/MockApp.ts +2 -2
- package/src/test/MockFileSystem.spec.ts +10 -11
- package/src/test/contain-offense.spec.ts +11 -3
- package/src/test/test-helper.ts +24 -28
- package/src/types.ts +8 -0
- package/src/visitor.spec.ts +2 -2
- package/src/types/schemas/index.ts +0 -3
- package/src/types/schemas/preset.ts +0 -52
- package/src/types/schemas/setting.ts +0 -320
- package/src/types/schemas/template.ts +0 -34
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @platformos/theme-check-common
|
|
2
2
|
|
|
3
|
+
## 0.0.10
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Beta release
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @platformos/liquid-html-parser@0.0.10
|
|
10
|
+
|
|
11
|
+
## 0.0.9
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Beta release
|
|
16
|
+
- Updated dependencies
|
|
17
|
+
- @platformos/liquid-html-parser@0.0.9
|
|
18
|
+
|
|
3
19
|
## 0.0.8
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
platformOS Check helps you follow best practices by analyzing your platformOS files.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
platformOS Check is available [to code editors that support the Language Server Protocol](https://github.com/Platform-OS/platformos-tools/wiki).
|
|
13
13
|
|
|
14
14
|
You may be interested by the sibling modules:
|
|
15
15
|
|
|
@@ -61,10 +61,10 @@ main();
|
|
|
61
61
|
The browser version is a bit more complex, you need to provide your own implementation of all the dependency injections.
|
|
62
62
|
|
|
63
63
|
```ts
|
|
64
|
-
import { simpleCheck, recommended,
|
|
64
|
+
import { simpleCheck, recommended, Config, Dependencies } from '@platformos/platformos-check-browser';
|
|
65
65
|
|
|
66
66
|
async function main() {
|
|
67
|
-
const
|
|
67
|
+
const appDesc = {
|
|
68
68
|
'app/views/partials/product-card.liquid': '{{ product | image_url | image_tag }}',
|
|
69
69
|
'app/views/partials/for-loop.liquid': '{% for variant in product.variants %}...{% endfor %}',
|
|
70
70
|
};
|
|
@@ -79,7 +79,7 @@ async function main() {
|
|
|
79
79
|
// ...
|
|
80
80
|
};
|
|
81
81
|
|
|
82
|
-
const offenses = await simpleCheck(
|
|
82
|
+
const offenses = await simpleCheck(appDesc, config, dependencies);
|
|
83
83
|
|
|
84
84
|
console.log(offenses);
|
|
85
85
|
}
|
|
@@ -50,6 +50,10 @@ exports.GraphQLVariablesCheck = {
|
|
|
50
50
|
create(context) {
|
|
51
51
|
const locator = new platformos_common_1.DocumentsLocator(context.fs);
|
|
52
52
|
const validate = async (targetFile, args, position) => {
|
|
53
|
+
// `args` is a special parameter that splats a hash as all GraphQL variables
|
|
54
|
+
// at runtime — we can't know which keys will be provided statically.
|
|
55
|
+
if (args.some((arg) => arg.name === 'args'))
|
|
56
|
+
return;
|
|
53
57
|
const locatedFile = await locator.locate(vscode_uri_1.URI.parse(context.config.rootUri), 'graphql', targetFile);
|
|
54
58
|
if (!locatedFile) {
|
|
55
59
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/checks/graphql-variables/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/checks/graphql-variables/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,7 +8,7 @@ exports.ImgWidthAndHeight = {
|
|
|
8
8
|
code: 'ImgWidthAndHeight',
|
|
9
9
|
name: 'Width and height attributes on image tags',
|
|
10
10
|
docs: {
|
|
11
|
-
description: 'This check is aimed at eliminating content layout shift
|
|
11
|
+
description: 'This check is aimed at eliminating content layout shift by enforcing the use of the width and height attributes on img tags.',
|
|
12
12
|
recommended: true,
|
|
13
13
|
url: 'https://documentation.platformos.com/developer-guide/platformos-check/checks/img-width-and-height',
|
|
14
14
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/checks/img-width-and-height/index.ts"],"names":[],"mappings":";;;AAAA,uCAA8E;AAC9E,oCAA8E;AAEjE,QAAA,iBAAiB,GAA0B;IACtD,IAAI,EAAE;QACJ,IAAI,EAAE,mBAAmB;QACzB,IAAI,EAAE,2CAA2C;QACjD,IAAI,EAAE;YACJ,WAAW,EACT,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/checks/img-width-and-height/index.ts"],"names":[],"mappings":";;;AAAA,uCAA8E;AAC9E,oCAA8E;AAEjE,QAAA,iBAAiB,GAA0B;IACtD,IAAI,EAAE;QACJ,IAAI,EAAE,mBAAmB;QACzB,IAAI,EAAE,2CAA2C;QACjD,IAAI,EAAE;YACJ,WAAW,EACT,8HAA8H;YAChI,WAAW,EAAE,IAAI;YACjB,GAAG,EAAE,mGAAmG;SACzG;QACD,IAAI,EAAE,sBAAc,CAAC,UAAU;QAC/B,QAAQ,EAAE,gBAAQ,CAAC,KAAK;QACxB,MAAM,EAAE,EAAE;QACV,OAAO,EAAE,EAAE;KACZ;IAED,MAAM,CAAC,OAAO;QACZ,OAAO;YACL,KAAK,CAAC,eAAe,CAAC,IAAI;gBACxB,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;oBACxB,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CACpC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAA,6BAAqB,EAAC,IAAI,CAAC,IAAI,IAAA,cAAM,EAAC,IAAI,EAAE,OAAO,CAAC,CAC5B,CAAC;oBAErC,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CACrC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAA,6BAAqB,EAAC,IAAI,CAAC,IAAI,IAAA,cAAM,EAAC,IAAI,EAAE,QAAQ,CAAC,CAC7B,CAAC;oBAErC,IAAI,iBAAiB,GAAG,EAAE,CAAC;oBAC3B,IAAI,CAAC,SAAS,EAAE,CAAC;wBACf,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBAClC,CAAC;oBACD,IAAI,CAAC,UAAU,EAAE,CAAC;wBAChB,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;oBACnC,CAAC;oBAED,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACjC,MAAM,aAAa,GAAG,iBAAiB,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC;wBAClF,OAAO,CAAC,MAAM,CAAC;4BACb,OAAO,EAAE,WAAW,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,aAAa,aAAa;4BACjF,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK;4BAC/B,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG;yBAC5B,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC"}
|
package/dist/checks/index.d.ts
CHANGED
|
@@ -5,4 +5,4 @@ export declare const allChecks: (LiquidCheckDefinition | JSONCheckDefinition | G
|
|
|
5
5
|
* - meta.docs.recommended: true
|
|
6
6
|
* - Either no meta.targets list exist or if it does exist then Recommended is a target
|
|
7
7
|
*/
|
|
8
|
-
export declare const recommended: (LiquidCheckDefinition | JSONCheckDefinition |
|
|
8
|
+
export declare const recommended: (LiquidCheckDefinition | JSONCheckDefinition | GraphQLCheckDefinition | YAMLCheckDefinition)[];
|
|
@@ -13,7 +13,7 @@ exports.JSONSyntaxError = {
|
|
|
13
13
|
code: 'JSONSyntaxError',
|
|
14
14
|
name: 'Enforce valid JSON',
|
|
15
15
|
docs: {
|
|
16
|
-
description: 'This check exists to prevent invalid JSON files in
|
|
16
|
+
description: 'This check exists to prevent invalid JSON files in apps.',
|
|
17
17
|
recommended: true,
|
|
18
18
|
url: 'https://documentation.platformos.com/developer-guide/platformos-check/checks/json-syntax-error',
|
|
19
19
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/checks/json-syntax-error/index.ts"],"names":[],"mappings":";;;AACA,6CAAqD;AACrD,uCAA4E;AAC5E,uCAAsC;AAEtC,SAAS,iBAAiB,CAAC,KAAY;IACrC,MAAM,OAAO,GAAG,YAAY,IAAI,KAAK,CAAC,CAAC,CAAE,KAAK,CAAC,UAAqB,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC;IACrF,OAAO,OAAO,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;AAC9C,CAAC;AAEY,QAAA,eAAe,GAAwB;IAClD,IAAI,EAAE;QACJ,IAAI,EAAE,iBAAiB;QACvB,IAAI,EAAE,oBAAoB;QAC1B,IAAI,EAAE;YACJ,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/checks/json-syntax-error/index.ts"],"names":[],"mappings":";;;AACA,6CAAqD;AACrD,uCAA4E;AAC5E,uCAAsC;AAEtC,SAAS,iBAAiB,CAAC,KAAY;IACrC,MAAM,OAAO,GAAG,YAAY,IAAI,KAAK,CAAC,CAAC,CAAE,KAAK,CAAC,UAAqB,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC;IACrF,OAAO,OAAO,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;AAC9C,CAAC;AAEY,QAAA,eAAe,GAAwB;IAClD,IAAI,EAAE;QACJ,IAAI,EAAE,iBAAiB;QACvB,IAAI,EAAE,oBAAoB;QAC1B,IAAI,EAAE;YACJ,WAAW,EAAE,0DAA0D;YACvE,WAAW,EAAE,IAAI;YACjB,GAAG,EAAE,gGAAgG;SACtG;QACD,IAAI,EAAE,sBAAc,CAAC,IAAI;QACzB,QAAQ,EAAE,gBAAQ,CAAC,KAAK;QACxB,MAAM,EAAE,EAAE;QACV,OAAO,EAAE,EAAE;QACX,UAAU,EAAE,IAAI;KACjB;IAED,MAAM,CAAC,OAAO;QACZ,IAAI,OAAO,CAAC,YAAY;YAAE,OAAO,EAAE,CAAC,CAAC,qDAAqD;QAE1F,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC;QAC/B,IAAI,CAAC,IAAA,eAAO,EAAC,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAE/B,OAAO;YACL,KAAK,CAAC,eAAe,CAAC,IAAI;gBACxB,IAAI,IAAI,CAAC,GAAG,YAAY,wBAAgB,EAAE,CAAC;oBACzC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;wBACpC,OAAO,CAAC,MAAM,CAAC;4BACb,OAAO,EAAE,sBAAsB,CAAC,KAAK,CAAC,KAAK,CAAC;4BAC5C,UAAU,EAAE,KAAK,CAAC,MAAM;4BACxB,QAAQ,EAAE,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM;yBACtC,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,MAAM,CAAC;wBACb,OAAO,EAAE,iBAAiB,CAAC,KAAK,CAAC;wBACjC,UAAU,EAAE,CAAC;wBACb,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM;qBAC7B,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,SAAS,sBAAsB,CAAC,SAAyB;IACvD,QAAQ,SAAS,EAAE,CAAC;QAClB;YACE,OAAO,gBAAgB,CAAC;QAC1B;YACE,OAAO,uBAAuB,CAAC;QACjC;YACE,OAAO,wBAAwB,CAAC;QAClC;YACE,OAAO,mBAAmB,CAAC;QAC7B;YACE,OAAO,6CAA6C,CAAC;QACvD;YACE,OAAO,mBAAmB,CAAC;QAC7B;YACE,OAAO,+BAA+B,CAAC;QACzC;YACE,OAAO,iCAAiC,CAAC;QAC3C;YACE,OAAO,uBAAuB,CAAC;QACjC;YACE,OAAO,uBAAuB,CAAC;QACjC;YACE,OAAO,2BAA2B,CAAC;QACrC;YACE,OAAO,0BAA0B,CAAC;QACpC;YACE,OAAO,0BAA0B,CAAC;QACpC;YACE,OAAO,iBAAiB,CAAC;QAC3B;YACE,OAAO,0BAA0B,CAAC;QACpC;YACE,OAAO,mBAAmB,CAAC;QAC7B;YACE,OAAO,qCAAqC,CAAC;IACjD,CAAC;AACH,CAAC"}
|
|
@@ -66,7 +66,7 @@ function detectInvalidLoopArguments(node, tags = []) {
|
|
|
66
66
|
};
|
|
67
67
|
}
|
|
68
68
|
function isSupportedTagArgument(tags, tagName, key, positional) {
|
|
69
|
-
return (tags
|
|
69
|
+
return ((tags ?? [])
|
|
70
70
|
.find((tag) => tag.name === tagName)
|
|
71
71
|
?.parameters?.some((parameter) => parameter.name === key && parameter.positional === positional) || false);
|
|
72
72
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InvalidLoopArguments.js","sourceRoot":"","sources":["../../../../src/checks/liquid-html-syntax-error/checks/InvalidLoopArguments.ts"],"names":[],"mappings":";;AAeA,gEAqFC;AApGD,uEAMwC;AAExC,mCAIiB;AACjB,uCAA8C;AAE9C,SAAgB,0BAA0B,CACxC,IAAe,EACf,OAAmB,EAAE;IAErB,IAAI,IAAI,CAAC,IAAI,KAAK,8BAAS,CAAC,SAAS,IAAI,CAAC,IAAA,uBAAe,EAAC,IAAI,CAAC,EAAE,CAAC;QAChE,OAAO;IACT,CAAC;IAED,IAAI,MAAM,GAAwB,IAAyC,CAAC,MAAM,CAAC;IAEnF,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO;IACT,CAAC;IAED,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC3E,CAAC;IAED,MAAM,SAAS,GAAG,IAAA,4BAAoB,EAAC,MAAM,CAAC,CAAC;IAE/C,yDAAyD;IACzD,4EAA4E;IAC5E,IAAI,SAAS,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QAC1B,OAAO;IACT,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACrE,IAAI,UAAU,GAAG,WAAW,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC,CAAE,CAAC,KAAM,CAAC;IACvD,IAAI,QAAQ,GAAG,WAAW,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAE,CAAC,KAAM,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,MAAM,CAAC;IAEvF,MAAM,iBAAiB,GAAa,EAAE,CAAC;IAEvC,4FAA4F;IAC5F,IAAI,yBAAyB,GAAG,KAAK,CAAC;IACtC,MAAM,gBAAgB,GAAa,EAAE,CAAC;IAEtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;QAE9B,IAAI,IAAA,iDAAyC,EAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9D,yBAAyB,GAAG,IAAI,CAAC;YACjC,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACtC,SAAS;QACX,CAAC;QAED,MAAM,YAAY,GAAG,IAAA,4BAAoB,EAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAE1D,qBAAqB;QACrB,IAAI,YAAY,EAAE,CAAC;YACjB,yBAAyB,GAAG,IAAI,CAAC;YAEjC,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC;gBACtE,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;gBACtC,SAAS;YACX,CAAC;QACH,CAAC;QACD,sCAAsC;aACjC,IACH,yBAAyB;YACzB,CAAC,sBAAsB,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,EAC9D,CAAC;YACD,yBAAyB,GAAG,IAAI,CAAC;YACjC,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACtC,SAAS;QACX,CAAC;QAED,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;IAED,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO;IACT,CAAC;IAED,OAAO;QACL,OAAO,EAAE,8CACP,IAAI,CAAC,IACP,sFAAsF,gBAAgB,CAAC,IAAI,CACzG,IAAI,CACL,EAAE;QACH,UAAU;QACV,QAAQ;QACR,GAAG,EAAE,CAAC,SAAS,EAAE,EAAE;YACjB,SAAS,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,EAAE,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACvE,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAC7B,
|
|
1
|
+
{"version":3,"file":"InvalidLoopArguments.js","sourceRoot":"","sources":["../../../../src/checks/liquid-html-syntax-error/checks/InvalidLoopArguments.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { LiquidTag } from '@platformos/liquid-html-parser';
|
|
2
|
+
import { Problem, SourceCodeType, TagEntry } from '../../..';
|
|
3
|
+
/**
|
|
4
|
+
* Detects known tags whose markup couldn't be parsed by the grammar.
|
|
5
|
+
*
|
|
6
|
+
* When the tolerant parser encounters a known tag name (e.g. "render") but can't parse
|
|
7
|
+
* the markup with the strict grammar rule, it falls back to the base case and stores
|
|
8
|
+
* the markup as a raw string. This function detects that situation.
|
|
9
|
+
*
|
|
10
|
+
* This check only applies to tags that DON'T have more specific sub-checks.
|
|
11
|
+
* Tags like assign, echo, if, for etc. have dedicated checks that provide
|
|
12
|
+
* better error messages and autofixes for their specific syntax patterns.
|
|
13
|
+
*
|
|
14
|
+
* Examples:
|
|
15
|
+
* {% graphql %} → name: 'graphql', markup: '' (string — invalid)
|
|
16
|
+
* {% render %} → name: 'render', markup: '' (string — invalid)
|
|
17
|
+
* {% function res 'path' %} → name: 'function', markup: "res 'path'" (string — invalid)
|
|
18
|
+
*/
|
|
19
|
+
export declare function detectInvalidTagSyntax(node: LiquidTag, tags?: TagEntry[]): Problem<SourceCodeType.LiquidHtml> | undefined;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.detectInvalidTagSyntax = detectInvalidTagSyntax;
|
|
4
|
+
const liquid_html_parser_1 = require("@platformos/liquid-html-parser");
|
|
5
|
+
/**
|
|
6
|
+
* Tags that use no markup at all — they are valid as `{% else %}`, `{% break %}`, etc.
|
|
7
|
+
* When their markup is a string, it's always '' (empty), so they should not trigger this check.
|
|
8
|
+
*/
|
|
9
|
+
const TAGS_WITH_NO_EXPECTED_MARKUP = new Set(liquid_html_parser_1.TAGS_WITHOUT_MARKUP);
|
|
10
|
+
/**
|
|
11
|
+
* Tags that have dedicated sub-checks handling their string-markup cases with
|
|
12
|
+
* more specific error messages and autofixes. This check should NOT fire on these
|
|
13
|
+
* to avoid double-reporting or overriding their nuanced decisions.
|
|
14
|
+
*
|
|
15
|
+
* - assign → MultipleAssignValues, InvalidFilterName, InvalidPipeSyntax
|
|
16
|
+
* - echo → InvalidEchoValue, InvalidFilterName, InvalidPipeSyntax
|
|
17
|
+
* - if/elsif/unless → InvalidConditionalNode, InvalidConditionalNodeParenthesis
|
|
18
|
+
* - for/tablerow → InvalidLoopRange, InvalidLoopArguments
|
|
19
|
+
*/
|
|
20
|
+
const TAGS_WITH_DEDICATED_CHECKS = new Set([
|
|
21
|
+
liquid_html_parser_1.NamedTags.assign,
|
|
22
|
+
liquid_html_parser_1.NamedTags.echo,
|
|
23
|
+
liquid_html_parser_1.NamedTags.if,
|
|
24
|
+
liquid_html_parser_1.NamedTags.elsif,
|
|
25
|
+
liquid_html_parser_1.NamedTags.unless,
|
|
26
|
+
liquid_html_parser_1.NamedTags.for,
|
|
27
|
+
liquid_html_parser_1.NamedTags.tablerow,
|
|
28
|
+
liquid_html_parser_1.NamedTags.when,
|
|
29
|
+
]);
|
|
30
|
+
/**
|
|
31
|
+
* All tag names in the NamedTags enum — these have specific grammar rules for their markup.
|
|
32
|
+
* If a NamedTag's markup is a string (instead of a parsed object), it means the strict grammar
|
|
33
|
+
* rule failed and the tag fell through to the base case.
|
|
34
|
+
*/
|
|
35
|
+
const NAMED_TAGS = new Set(Object.values(liquid_html_parser_1.NamedTags));
|
|
36
|
+
/**
|
|
37
|
+
* Detects known tags whose markup couldn't be parsed by the grammar.
|
|
38
|
+
*
|
|
39
|
+
* When the tolerant parser encounters a known tag name (e.g. "render") but can't parse
|
|
40
|
+
* the markup with the strict grammar rule, it falls back to the base case and stores
|
|
41
|
+
* the markup as a raw string. This function detects that situation.
|
|
42
|
+
*
|
|
43
|
+
* This check only applies to tags that DON'T have more specific sub-checks.
|
|
44
|
+
* Tags like assign, echo, if, for etc. have dedicated checks that provide
|
|
45
|
+
* better error messages and autofixes for their specific syntax patterns.
|
|
46
|
+
*
|
|
47
|
+
* Examples:
|
|
48
|
+
* {% graphql %} → name: 'graphql', markup: '' (string — invalid)
|
|
49
|
+
* {% render %} → name: 'render', markup: '' (string — invalid)
|
|
50
|
+
* {% function res 'path' %} → name: 'function', markup: "res 'path'" (string — invalid)
|
|
51
|
+
*/
|
|
52
|
+
function detectInvalidTagSyntax(node, tags = []) {
|
|
53
|
+
const tagName = node.name;
|
|
54
|
+
// Only check tags known to the grammar with specific markup rules
|
|
55
|
+
if (!NAMED_TAGS.has(tagName)) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
// Tags without expected markup (else, break, continue, etc.) always have string markup
|
|
59
|
+
if (TAGS_WITH_NO_EXPECTED_MARKUP.has(tagName)) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
// Skip tags that have dedicated sub-checks with more specific error handling
|
|
63
|
+
if (TAGS_WITH_DEDICATED_CHECKS.has(tagName)) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
// If markup is not a string, it was parsed successfully — no error
|
|
67
|
+
if (typeof node.markup !== 'string') {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
// Build a helpful hint from the docset if available
|
|
71
|
+
const tagEntry = tags.find((t) => t.name === tagName);
|
|
72
|
+
const syntaxHint = tagEntry?.syntax ? ` Expected syntax: ${tagEntry.syntax}` : '';
|
|
73
|
+
return {
|
|
74
|
+
message: `Invalid syntax for tag '${tagName}'${syntaxHint}`,
|
|
75
|
+
startIndex: node.position.start,
|
|
76
|
+
endIndex: node.position.end,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=InvalidTagSyntax.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InvalidTagSyntax.js","sourceRoot":"","sources":["../../../../src/checks/liquid-html-syntax-error/checks/InvalidTagSyntax.ts"],"names":[],"mappings":";;AAqDA,wDAmCC;AAxFD,uEAA2F;AAG3F;;;GAGG;AACH,MAAM,4BAA4B,GAAG,IAAI,GAAG,CAAS,wCAAmB,CAAC,CAAC;AAE1E;;;;;;;;;GASG;AACH,MAAM,0BAA0B,GAAG,IAAI,GAAG,CAAS;IACjD,8BAAS,CAAC,MAAM;IAChB,8BAAS,CAAC,IAAI;IACd,8BAAS,CAAC,EAAE;IACZ,8BAAS,CAAC,KAAK;IACf,8BAAS,CAAC,MAAM;IAChB,8BAAS,CAAC,GAAG;IACb,8BAAS,CAAC,QAAQ;IAClB,8BAAS,CAAC,IAAI;CACf,CAAC,CAAC;AAEH;;;;GAIG;AACH,MAAM,UAAU,GAAG,IAAI,GAAG,CAAS,MAAM,CAAC,MAAM,CAAC,8BAAS,CAAC,CAAC,CAAC;AAE7D;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,sBAAsB,CACpC,IAAe,EACf,OAAmB,EAAE;IAErB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC;IAE1B,kEAAkE;IAClE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7B,OAAO;IACT,CAAC;IAED,uFAAuF;IACvF,IAAI,4BAA4B,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9C,OAAO;IACT,CAAC;IAED,6EAA6E;IAC7E,IAAI,0BAA0B,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5C,OAAO;IACT,CAAC;IAED,mEAAmE;IACnE,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QACpC,OAAO;IACT,CAAC;IAED,oDAAoD;IACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;IACtD,MAAM,UAAU,GAAG,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,qBAAqB,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAElF,OAAO;QACL,OAAO,EAAE,2BAA2B,OAAO,IAAI,UAAU,EAAE;QAC3D,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK;QAC/B,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG;KAC5B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.detectUnknownTag = detectUnknownTag;
|
|
4
|
+
const liquid_html_parser_1 = require("@platformos/liquid-html-parser");
|
|
5
|
+
/**
|
|
6
|
+
* All tag names known to the grammar (NamedTags enum + TAGS_WITHOUT_MARKUP + BLOCKS + RAW_TAGS).
|
|
7
|
+
* These are tags that the parser recognizes with specific grammar rules.
|
|
8
|
+
*/
|
|
9
|
+
const GRAMMAR_KNOWN_TAGS = new Set([
|
|
10
|
+
...Object.values(liquid_html_parser_1.NamedTags),
|
|
11
|
+
...liquid_html_parser_1.TAGS_WITHOUT_MARKUP,
|
|
12
|
+
...liquid_html_parser_1.BLOCKS,
|
|
13
|
+
...liquid_html_parser_1.RAW_TAGS,
|
|
14
|
+
'#', // inline comment: {% # this is a comment %}
|
|
15
|
+
]);
|
|
16
|
+
function detectUnknownTag(node, tags = []) {
|
|
17
|
+
const tagName = node.name;
|
|
18
|
+
// If the tag is known to the grammar, it's not unknown
|
|
19
|
+
if (GRAMMAR_KNOWN_TAGS.has(tagName)) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
// If the tag is known to the docset, it's not unknown
|
|
23
|
+
if (tags.some((tag) => tag.name === tagName)) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
message: `Unknown tag '${tagName}'`,
|
|
28
|
+
startIndex: node.position.start,
|
|
29
|
+
endIndex: node.position.end,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=UnknownTag.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UnknownTag.js","sourceRoot":"","sources":["../../../../src/checks/liquid-html-syntax-error/checks/UnknownTag.ts"],"names":[],"mappings":";;AAqBA,4CAqBC;AA1CD,uEAMwC;AAGxC;;;GAGG;AACH,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAS;IACzC,GAAG,MAAM,CAAC,MAAM,CAAC,8BAAS,CAAC;IAC3B,GAAG,wCAAmB;IACtB,GAAG,2BAAM;IACT,GAAG,6BAAQ;IACX,GAAG,EAAE,4CAA4C;CAClD,CAAC,CAAC;AAEH,SAAgB,gBAAgB,CAC9B,IAAe,EACf,OAAmB,EAAE;IAErB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC;IAE1B,uDAAuD;IACvD,IAAI,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QACpC,OAAO;IACT,CAAC;IAED,sDAAsD;IACtD,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,OAAO,CAAC,EAAE,CAAC;QAC7C,OAAO;IACT,CAAC;IAED,OAAO;QACL,OAAO,EAAE,gBAAgB,OAAO,GAAG;QACnC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK;QAC/B,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG;KAC5B,CAAC;AACJ,CAAC"}
|
|
@@ -12,6 +12,8 @@ const InvalidLoopArguments_1 = require("./checks/InvalidLoopArguments");
|
|
|
12
12
|
const InvalidConditionalNodeParenthesis_1 = require("./checks/InvalidConditionalNodeParenthesis");
|
|
13
13
|
const InvalidFilterName_1 = require("./checks/InvalidFilterName");
|
|
14
14
|
const InvalidPipeSyntax_1 = require("./checks/InvalidPipeSyntax");
|
|
15
|
+
const UnknownTag_1 = require("./checks/UnknownTag");
|
|
16
|
+
const InvalidTagSyntax_1 = require("./checks/InvalidTagSyntax");
|
|
15
17
|
const utils_2 = require("../utils");
|
|
16
18
|
function isParsingErrorWithLocation(error) {
|
|
17
19
|
return 'name' in error && error.name === 'LiquidHTMLParsingError' && 'loc' in error;
|
|
@@ -53,11 +55,19 @@ exports.LiquidHTMLSyntaxError = {
|
|
|
53
55
|
async LiquidTag(node, ancestors) {
|
|
54
56
|
if ((0, utils_2.isWithinRawTagThatDoesNotParseItsContents)(ancestors))
|
|
55
57
|
return;
|
|
58
|
+
const tags = (await tagsPromise) ?? [];
|
|
59
|
+
// Unknown tags are fatal — no point in further syntax checks.
|
|
60
|
+
const unknownTagProblem = (0, UnknownTag_1.detectUnknownTag)(node, tags);
|
|
61
|
+
if (unknownTagProblem) {
|
|
62
|
+
context.report(unknownTagProblem);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
// Run specific sub-checks first — they provide better error messages and autofixes.
|
|
56
66
|
const problems = [
|
|
57
67
|
(0, MultipleAssignValues_1.detectMultipleAssignValues)(node),
|
|
58
68
|
(0, InvalidEchoValue_1.detectInvalidEchoValue)(node),
|
|
59
69
|
(0, InvalidLoopRange_1.detectInvalidLoopRange)(node),
|
|
60
|
-
(0, InvalidLoopArguments_1.detectInvalidLoopArguments)(node,
|
|
70
|
+
(0, InvalidLoopArguments_1.detectInvalidLoopArguments)(node, tags),
|
|
61
71
|
].filter(Boolean);
|
|
62
72
|
// Fixers for `detectConditionalNodeUnsupportedParenthesis` and `detectInvalidConditionalNode` consume
|
|
63
73
|
// the whole node markup, so we MUST not run both.
|
|
@@ -65,8 +75,16 @@ exports.LiquidHTMLSyntaxError = {
|
|
|
65
75
|
if (conditionalNodeProblem) {
|
|
66
76
|
problems.push(conditionalNodeProblem);
|
|
67
77
|
}
|
|
78
|
+
// InvalidTagSyntax is a catch-all for known tags with unparseable markup.
|
|
79
|
+
// Only fire it if no more specific sub-check already reported on this tag.
|
|
80
|
+
if (problems.length === 0) {
|
|
81
|
+
const invalidSyntaxProblem = (0, InvalidTagSyntax_1.detectInvalidTagSyntax)(node, tags);
|
|
82
|
+
if (invalidSyntaxProblem) {
|
|
83
|
+
problems.push(invalidSyntaxProblem);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
68
86
|
problems.forEach(context.report);
|
|
69
|
-
const filterProblems = await (0, InvalidFilterName_1.detectInvalidFilterName)(node, await filtersPromise);
|
|
87
|
+
const filterProblems = await (0, InvalidFilterName_1.detectInvalidFilterName)(node, (await filtersPromise) ?? []);
|
|
70
88
|
if (filterProblems.length > 0) {
|
|
71
89
|
filterProblems.forEach((filterProblem) => context.report(filterProblem));
|
|
72
90
|
}
|
|
@@ -87,7 +105,7 @@ exports.LiquidHTMLSyntaxError = {
|
|
|
87
105
|
async LiquidVariableOutput(node, ancestors) {
|
|
88
106
|
if ((0, utils_2.isWithinRawTagThatDoesNotParseItsContents)(ancestors))
|
|
89
107
|
return;
|
|
90
|
-
const filterProblems = await (0, InvalidFilterName_1.detectInvalidFilterName)(node, await filtersPromise);
|
|
108
|
+
const filterProblems = await (0, InvalidFilterName_1.detectInvalidFilterName)(node, (await filtersPromise) ?? []);
|
|
91
109
|
if (filterProblems.length > 0) {
|
|
92
110
|
filterProblems.forEach((problem) => context.report(problem));
|
|
93
111
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/checks/liquid-html-syntax-error/index.ts"],"names":[],"mappings":";;;AAAA,uCAAuF;AACvF,uCAAiD;AACjD,wEAA2E;AAC3E,kFAAqF;AACrF,gEAAmE;AACnE,4EAA+E;AAC/E,gEAAmE;AACnE,wEAA2E;AAC3E,kGAAyG;AACzG,kEAAqE;AACrE,kEAAqE;AACrE,oCAAqE;AAOrE,SAAS,0BAA0B,CACjC,KAAY;IAEZ,OAAO,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,wBAAwB,IAAI,KAAK,IAAI,KAAK,CAAC;AACtF,CAAC;AAED,SAAS,iBAAiB,CAAC,OAAe,EAAE,SAAiB;IAC3D,OAAO,OAAO;SACX,OAAO,CAAC,uBAAuB,EAAE,eAAe,CAAC;SACjD,OAAO,CAAC,4BAA4B,EAAE,SAAS,SAAS,GAAG,CAAC,CAAC;AAClE,CAAC;AAEY,QAAA,qBAAqB,GAA0B;IAC1D,IAAI,EAAE;QACJ,IAAI,EAAE,uBAAuB;QAC7B,OAAO,EAAE,CAAC,aAAa,EAAE,kBAAkB,CAAC;QAC5C,IAAI,EAAE,kCAAkC;QACxC,IAAI,EAAE;YACJ,WAAW,EAAE,oEAAoE;YACjF,WAAW,EAAE,IAAI;SAClB;QACD,IAAI,EAAE,sBAAc,CAAC,UAAU;QAC/B,QAAQ,EAAE,gBAAQ,CAAC,KAAK;QACxB,MAAM,EAAE,EAAE;QACV,OAAO,EAAE,EAAE;KACZ;IAED,MAAM,CAAC,OAAO;QACZ,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC;QAC7B,MAAM,cAAc,GAAG,OAAO,CAAC,gBAAgB,EAAE,OAAO,EAAE,CAAC;QAC3D,MAAM,WAAW,GAAG,OAAO,CAAC,gBAAgB,EAAE,IAAI,EAAE,CAAC;QAErD,IAAI,CAAC,IAAA,eAAO,EAAC,GAAG,CAAC,EAAE,CAAC;YAClB,OAAO;gBACL,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,SAAS;oBACrC,IAAI,IAAA,iDAAyC,EAAC,SAAS,CAAC;wBAAE,OAAO;oBAEjE,MAAM,OAAO,GAAG,IAAA,2DAA+B,EAAC,IAAI,EAAE,SAAS,CAAC,CAAC;oBAEjE,IAAI,CAAC,OAAO,EAAE,CAAC;wBACb,OAAO;oBACT,CAAC;oBAED,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBAC1B,CAAC;gBACD,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS;oBAC7B,IAAI,IAAA,iDAAyC,EAAC,SAAS,CAAC;wBAAE,OAAO;oBAEjE,MAAM,QAAQ,GAAG;wBACf,IAAA,iDAA0B,EAAC,IAAI,CAAC;wBAChC,IAAA,yCAAsB,EAAC,IAAI,CAAC;wBAC5B,IAAA,yCAAsB,EAAC,IAAI,CAAC;wBAC5B,IAAA,iDAA0B,EAAC,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/checks/liquid-html-syntax-error/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,36 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.MatchingTranslations = void 0;
|
|
4
4
|
const types_1 = require("../../types");
|
|
5
5
|
const PLURALIZATION_KEYS = new Set(['zero', 'one', 'two', 'few', 'many', 'other']);
|
|
6
|
+
/**
|
|
7
|
+
* Returns the locale declared in a YAML translation file by reading its first
|
|
8
|
+
* top-level key (e.g. `en`, `pt-BR`, `fr`). platformOS determines a file's
|
|
9
|
+
* locale from content, not from its path.
|
|
10
|
+
*/
|
|
11
|
+
function getLocaleFromAst(ast) {
|
|
12
|
+
if (ast instanceof Error)
|
|
13
|
+
return null;
|
|
14
|
+
if (ast.type !== 'Object')
|
|
15
|
+
return null;
|
|
16
|
+
const firstProp = ast.children[0];
|
|
17
|
+
if (!firstProp || firstProp.type !== 'Property')
|
|
18
|
+
return null;
|
|
19
|
+
return firstProp.key.value || null;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Extracts the translations base directory from a relative file path.
|
|
23
|
+
*
|
|
24
|
+
* e.g. `app/translations/pt-BR.yml` → `app/translations`
|
|
25
|
+
* `app/translations/pt-BR/validation.yml` → `app/translations`
|
|
26
|
+
* `modules/x/public/translations/en.yml` → `modules/x/public/translations`
|
|
27
|
+
*
|
|
28
|
+
* Returns `null` if the path doesn't contain a `/translations/` segment.
|
|
29
|
+
*/
|
|
30
|
+
function getTranslationRelativeBase(relativePath) {
|
|
31
|
+
const idx = relativePath.lastIndexOf('/translations/');
|
|
32
|
+
if (idx === -1)
|
|
33
|
+
return null;
|
|
34
|
+
return relativePath.substring(0, idx + '/translations'.length);
|
|
35
|
+
}
|
|
6
36
|
exports.MatchingTranslations = {
|
|
7
37
|
meta: {
|
|
8
38
|
code: 'MatchingTranslations',
|
|
@@ -18,38 +48,55 @@ exports.MatchingTranslations = {
|
|
|
18
48
|
targets: [],
|
|
19
49
|
},
|
|
20
50
|
create(context) {
|
|
21
|
-
// State
|
|
22
|
-
const
|
|
23
|
-
const
|
|
51
|
+
// ── State ──────────────────────────────────────────────────────────────
|
|
52
|
+
const enTranslations = new Set(); // keys present in the en scope
|
|
53
|
+
const missingFromLocale = new Set(); // en keys absent from the entire locale scope
|
|
24
54
|
const nodesByPath = new Map();
|
|
25
55
|
const file = context.file;
|
|
26
56
|
const fileUri = file.uri;
|
|
27
57
|
const relativePath = context.toRelativePath(fileUri);
|
|
28
58
|
const ast = file.ast;
|
|
59
|
+
// ── Guard: only lint translation files ────────────────────────────────
|
|
29
60
|
const isTranslationFile = relativePath.includes('/translations/');
|
|
30
|
-
//
|
|
31
|
-
|
|
32
|
-
const
|
|
33
|
-
if (!isTranslationFile ||
|
|
34
|
-
// No need to lint a file that isn't a non-default translation file
|
|
61
|
+
// The locale is always the first top-level key in the YAML file (e.g. `en`,
|
|
62
|
+
// `pt-BR`). platformOS resolves locale from content, not from the file path.
|
|
63
|
+
const locale = getLocaleFromAst(ast);
|
|
64
|
+
if (!isTranslationFile || !locale || locale === 'en' || ast instanceof Error) {
|
|
35
65
|
return {};
|
|
36
66
|
}
|
|
37
|
-
//
|
|
38
|
-
const
|
|
67
|
+
// ── Derive scope (translation base URI) ──────────────────────────────
|
|
68
|
+
const relativeBase = getTranslationRelativeBase(relativePath);
|
|
69
|
+
if (!relativeBase)
|
|
70
|
+
return {};
|
|
71
|
+
const translationBaseUri = context.toUri(relativeBase);
|
|
72
|
+
// A "primary" locale file is the top-level `{locale}.yml` (not inside a
|
|
73
|
+
// locale sub-directory like `pt-BR/`). Only the primary file reports
|
|
74
|
+
// missing translations to avoid duplicate offenses across split files.
|
|
75
|
+
const pathAfterBase = relativePath.substring(relativeBase.length + 1);
|
|
76
|
+
const isPrimaryLocaleFile = !pathAfterBase.includes('/');
|
|
77
|
+
// ── Helpers ───────────────────────────────────────────────────────────
|
|
39
78
|
const isTerminalNode = ({ type }) => type === 'Literal';
|
|
40
79
|
const isPluralizationNode = (node) => PLURALIZATION_KEYS.has(node.key.value);
|
|
41
|
-
const hasDefaultTranslation = (translationPath) => defaultTranslations.has(translationPath) ?? false;
|
|
42
80
|
const isPluralizationPath = (path) => [...PLURALIZATION_KEYS].some((key) => path.endsWith(key));
|
|
43
|
-
const
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
if (
|
|
47
|
-
return
|
|
81
|
+
const countCommonParts = (a, b) => {
|
|
82
|
+
const min = Math.min(a.length, b.length);
|
|
83
|
+
for (let i = 0; i < min; i++)
|
|
84
|
+
if (a[i] !== b[i])
|
|
85
|
+
return i;
|
|
86
|
+
return min;
|
|
87
|
+
};
|
|
88
|
+
const closestTranslationKey = (key) => {
|
|
89
|
+
const keyParts = key.split('.');
|
|
90
|
+
let closest = '';
|
|
91
|
+
let max = 0;
|
|
92
|
+
for (const path of nodesByPath.keys()) {
|
|
93
|
+
const common = countCommonParts(path.split('.'), keyParts);
|
|
94
|
+
if (common > max) {
|
|
95
|
+
max = common;
|
|
96
|
+
closest = path;
|
|
48
97
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return acc.concat(childPaths.map((path) => `${key}.${path}`));
|
|
52
|
-
}, []);
|
|
98
|
+
}
|
|
99
|
+
return nodesByPath.get(closest) ?? ast;
|
|
53
100
|
};
|
|
54
101
|
// Strip the locale prefix (first Property in the ancestors chain).
|
|
55
102
|
// YAML files wrap content under a locale key: { en: { hello: 'Hello' } }
|
|
@@ -57,77 +104,65 @@ exports.MatchingTranslations = {
|
|
|
57
104
|
const objectPath = (nodes) => {
|
|
58
105
|
const props = nodes.filter((n) => n.type === 'Property');
|
|
59
106
|
if (props.length <= 1)
|
|
60
|
-
return '';
|
|
107
|
+
return '';
|
|
61
108
|
return props
|
|
62
109
|
.slice(1)
|
|
63
110
|
.map((p) => p.key.value)
|
|
64
111
|
.join('.');
|
|
65
112
|
};
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
return minLength;
|
|
74
|
-
};
|
|
75
|
-
const closestTranslationKey = (translationKey) => {
|
|
76
|
-
const translationKeyParts = translationKey.split('.');
|
|
77
|
-
let closestMatch = '';
|
|
78
|
-
let maxCommonParts = 0;
|
|
79
|
-
for (const path of nodesByPath.keys()) {
|
|
80
|
-
const pathParts = path.split('.');
|
|
81
|
-
const commonParts = countCommonParts(pathParts, translationKeyParts);
|
|
82
|
-
if (commonParts > maxCommonParts) {
|
|
83
|
-
maxCommonParts = commonParts;
|
|
84
|
-
closestMatch = path;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
return nodesByPath.get(closestMatch) ?? ast;
|
|
88
|
-
};
|
|
113
|
+
const jsonPaths = (json) => Object.keys(json).reduce((acc, key) => {
|
|
114
|
+
if (typeof json[key] !== 'object')
|
|
115
|
+
return acc.concat(key);
|
|
116
|
+
return acc.concat(jsonPaths(json[key]).map((p) => `${key}.${p}`));
|
|
117
|
+
}, []);
|
|
89
118
|
return {
|
|
90
119
|
async onCodePathStart() {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
120
|
+
// Aggregate ALL en translations in this scope (en.yml + en/*.yml)
|
|
121
|
+
const en = await context.getTranslationsForBase(translationBaseUri, 'en');
|
|
122
|
+
jsonPaths(en).forEach(Set.prototype.add, enTranslations);
|
|
123
|
+
if (!isPrimaryLocaleFile)
|
|
124
|
+
return;
|
|
125
|
+
// For the primary locale file: pre-compute which en keys are absent
|
|
126
|
+
// from the entire locale scope (locale.yml + locale/*.yml).
|
|
127
|
+
const localeAgg = await context.getTranslationsForBase(translationBaseUri, locale);
|
|
128
|
+
const localeKeys = new Set(jsonPaths(localeAgg));
|
|
129
|
+
for (const key of enTranslations) {
|
|
130
|
+
if (!localeKeys.has(key))
|
|
131
|
+
missingFromLocale.add(key);
|
|
132
|
+
}
|
|
96
133
|
},
|
|
97
134
|
async Property(node, ancestors) {
|
|
98
135
|
const path = objectPath(ancestors.concat(node));
|
|
99
136
|
if (!path)
|
|
100
|
-
return; // skip the root locale key (e.g. 'pt-BR')
|
|
101
|
-
nodesByPath.set(path, node);
|
|
102
|
-
if (!hasDefaultTranslations())
|
|
103
137
|
return;
|
|
138
|
+
nodesByPath.set(path, node);
|
|
104
139
|
if (isPluralizationNode(node))
|
|
105
140
|
return;
|
|
106
141
|
if (!isTerminalNode(node.value))
|
|
107
142
|
return;
|
|
108
|
-
if (
|
|
109
|
-
//
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
143
|
+
if (!enTranslations.size)
|
|
144
|
+
return; // no en reference — skip
|
|
145
|
+
if (!enTranslations.has(path)) {
|
|
146
|
+
context.report({
|
|
147
|
+
message: `A translation for '${path}' does not exist in the en locale`,
|
|
148
|
+
startIndex: node.loc.start.offset,
|
|
149
|
+
endIndex: node.loc.end.offset,
|
|
150
|
+
});
|
|
113
151
|
}
|
|
114
|
-
context.report({
|
|
115
|
-
message: `A default translation for '${path}' does not exist`,
|
|
116
|
-
startIndex: node.loc.start.offset,
|
|
117
|
-
endIndex: node.loc.end.offset,
|
|
118
|
-
});
|
|
119
152
|
},
|
|
120
153
|
async onCodePathEnd() {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
154
|
+
if (!isPrimaryLocaleFile)
|
|
155
|
+
return;
|
|
156
|
+
for (const key of missingFromLocale) {
|
|
157
|
+
if (isPluralizationPath(key))
|
|
158
|
+
continue;
|
|
159
|
+
const closest = closestTranslationKey(key);
|
|
125
160
|
context.report({
|
|
126
|
-
message: `The translation for '${
|
|
161
|
+
message: `The translation for '${key}' is missing`,
|
|
127
162
|
startIndex: closest.loc.start.offset,
|
|
128
163
|
endIndex: closest.loc.end.offset,
|
|
129
164
|
});
|
|
130
|
-
}
|
|
165
|
+
}
|
|
131
166
|
},
|
|
132
167
|
};
|
|
133
168
|
},
|