@platformos/platformos-check-common 0.0.17 → 0.0.19

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 (54) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/checks/index.d.ts +1 -1
  3. package/dist/checks/index.js +6 -2
  4. package/dist/checks/index.js.map +1 -1
  5. package/dist/checks/json-literal-quote-style/index.d.ts +2 -0
  6. package/dist/checks/json-literal-quote-style/index.js +42 -0
  7. package/dist/checks/json-literal-quote-style/index.js.map +1 -0
  8. package/dist/checks/liquid-html-syntax-error/checks/InvalidAssignSyntax.d.ts +32 -0
  9. package/dist/checks/liquid-html-syntax-error/checks/InvalidAssignSyntax.js +93 -0
  10. package/dist/checks/liquid-html-syntax-error/checks/InvalidAssignSyntax.js.map +1 -0
  11. package/dist/checks/liquid-html-syntax-error/checks/InvalidOutputPush.d.ts +17 -0
  12. package/dist/checks/liquid-html-syntax-error/checks/InvalidOutputPush.js +37 -0
  13. package/dist/checks/liquid-html-syntax-error/checks/InvalidOutputPush.js.map +1 -0
  14. package/dist/checks/liquid-html-syntax-error/checks/InvalidTagSyntax.js +1 -1
  15. package/dist/checks/liquid-html-syntax-error/index.js +25 -0
  16. package/dist/checks/liquid-html-syntax-error/index.js.map +1 -1
  17. package/dist/checks/partial-call-arguments/extract-undefined-variables.d.ts +14 -0
  18. package/dist/checks/partial-call-arguments/extract-undefined-variables.js +234 -0
  19. package/dist/checks/partial-call-arguments/extract-undefined-variables.js.map +1 -0
  20. package/dist/checks/partial-call-arguments/index.d.ts +2 -0
  21. package/dist/checks/partial-call-arguments/index.js +117 -0
  22. package/dist/checks/partial-call-arguments/index.js.map +1 -0
  23. package/dist/checks/unused-assign/index.js +17 -0
  24. package/dist/checks/unused-assign/index.js.map +1 -1
  25. package/dist/checks/valid-frontmatter/index.d.ts +2 -0
  26. package/dist/checks/valid-frontmatter/index.js +279 -0
  27. package/dist/checks/valid-frontmatter/index.js.map +1 -0
  28. package/dist/frontmatter/index.d.ts +1 -59
  29. package/dist/frontmatter/index.js +6 -298
  30. package/dist/frontmatter/index.js.map +1 -1
  31. package/dist/tsconfig.tsbuildinfo +1 -1
  32. package/package.json +2 -2
  33. package/src/checks/index.ts +6 -2
  34. package/src/checks/json-literal-quote-style/index.spec.ts +129 -0
  35. package/src/checks/json-literal-quote-style/index.ts +45 -0
  36. package/src/checks/liquid-html-syntax-error/checks/InvalidAssignSyntax.spec.ts +471 -0
  37. package/src/checks/liquid-html-syntax-error/checks/InvalidAssignSyntax.ts +97 -0
  38. package/src/checks/liquid-html-syntax-error/checks/InvalidOutputPush.spec.ts +104 -0
  39. package/src/checks/liquid-html-syntax-error/checks/InvalidOutputPush.ts +39 -0
  40. package/src/checks/liquid-html-syntax-error/checks/InvalidTagSyntax.spec.ts +86 -2
  41. package/src/checks/liquid-html-syntax-error/checks/InvalidTagSyntax.ts +1 -1
  42. package/src/checks/liquid-html-syntax-error/index.ts +30 -0
  43. package/src/checks/partial-call-arguments/extract-undefined-variables.spec.ts +218 -0
  44. package/src/checks/{metadata-params → partial-call-arguments}/extract-undefined-variables.ts +31 -6
  45. package/src/checks/partial-call-arguments/index.spec.ts +436 -0
  46. package/src/checks/{metadata-params → partial-call-arguments}/index.ts +18 -11
  47. package/src/checks/undefined-object/index.spec.ts +101 -0
  48. package/src/checks/unused-assign/index.spec.ts +48 -0
  49. package/src/checks/unused-assign/index.ts +15 -0
  50. package/src/checks/valid-frontmatter/index.spec.ts +666 -0
  51. package/src/checks/valid-frontmatter/index.ts +344 -0
  52. package/src/frontmatter/index.ts +9 -344
  53. package/src/checks/metadata-params/extract-undefined-variables.spec.ts +0 -115
  54. package/src/checks/metadata-params/index.spec.ts +0 -257
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platformos/platformos-check-common",
3
- "version": "0.0.17",
3
+ "version": "0.0.19",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -26,7 +26,7 @@
26
26
  "type-check": "tsc --noEmit"
27
27
  },
28
28
  "dependencies": {
29
- "@platformos/liquid-html-parser": "0.0.15",
29
+ "@platformos/liquid-html-parser": "0.0.17",
30
30
  "graphql": "^16.12.0",
31
31
  "js-yaml": "^4.1.1",
32
32
  "jsonc-parser": "^3.3.1",
@@ -30,7 +30,7 @@ import { ValidJSON } from './valid-json';
30
30
  import { ValidDocParamTypes } from './valid-doc-param-types';
31
31
  import { ValidRenderPartialArgumentTypes } from './valid-render-partial-argument-types';
32
32
  import { VariableName } from './variable-name';
33
- import { MetadataParamsCheck } from './metadata-params';
33
+ import { PartialCallArguments } from './partial-call-arguments';
34
34
  import { GraphQLVariablesCheck } from './graphql-variables';
35
35
  import { GraphQLCheck } from './graphql';
36
36
  import { UnknownProperty } from './unknown-property';
@@ -39,6 +39,8 @@ import { DuplicateFunctionArguments } from './duplicate-function-arguments';
39
39
  import { MissingRenderPartialArguments } from './missing-render-partial-arguments';
40
40
  import { NestedGraphQLQuery } from './nested-graphql-query';
41
41
  import { MissingPage } from './missing-page';
42
+ import { ValidFrontmatter } from './valid-frontmatter';
43
+ import { JsonLiteralQuoteStyle } from './json-literal-quote-style';
42
44
 
43
45
  export const allChecks: (
44
46
  | LiquidCheckDefinition
@@ -71,7 +73,7 @@ export const allChecks: (
71
73
  ValidDocParamTypes,
72
74
  ValidRenderPartialArgumentTypes,
73
75
  VariableName,
74
- MetadataParamsCheck,
76
+ PartialCallArguments,
75
77
  GraphQLVariablesCheck,
76
78
  GraphQLCheck,
77
79
  UnknownProperty,
@@ -79,6 +81,8 @@ export const allChecks: (
79
81
  MissingRenderPartialArguments,
80
82
  NestedGraphQLQuery,
81
83
  MissingPage,
84
+ ValidFrontmatter,
85
+ JsonLiteralQuoteStyle,
82
86
  ];
83
87
 
84
88
  /**
@@ -0,0 +1,129 @@
1
+ import { expect, describe, it } from 'vitest';
2
+ import { JsonLiteralQuoteStyle } from './index';
3
+ import { applyFix, runLiquidCheck } from '../../test';
4
+
5
+ describe('Module: JsonLiteralQuoteStyle', () => {
6
+ it('should report single-quoted keys in an inline hash literal', async () => {
7
+ const sourceCode = `{% assign a = {'a': 5} %}`;
8
+
9
+ const offenses = await runLiquidCheck(JsonLiteralQuoteStyle, sourceCode);
10
+
11
+ expect(offenses).to.have.length(1);
12
+ expect(offenses[0].message).to.equal(
13
+ 'Use double quotes for string literals inside object/array literals (e.g. \'{"key": "value"}\', not "{\'key\': \'value\'}").',
14
+ );
15
+ });
16
+
17
+ it('should report single-quoted string values in an inline hash literal', async () => {
18
+ const sourceCode = `{% assign a = {"key": 'value'} %}`;
19
+
20
+ const offenses = await runLiquidCheck(JsonLiteralQuoteStyle, sourceCode);
21
+
22
+ expect(offenses).to.have.length(1);
23
+ });
24
+
25
+ it('should report both single-quoted keys and values', async () => {
26
+ const sourceCode = `{% assign a = {'a': 'b', 'c': 'd'} %}`;
27
+
28
+ const offenses = await runLiquidCheck(JsonLiteralQuoteStyle, sourceCode);
29
+
30
+ expect(offenses).to.have.length(4);
31
+ });
32
+
33
+ it('should report single-quoted strings in nested hash literals', async () => {
34
+ const sourceCode = `{% assign a = {"outer": {'inner': 1}} %}`;
35
+
36
+ const offenses = await runLiquidCheck(JsonLiteralQuoteStyle, sourceCode);
37
+
38
+ expect(offenses).to.have.length(1);
39
+ });
40
+
41
+ it('should report single-quoted strings inside array literals', async () => {
42
+ const sourceCode = `{% assign a = ['x', 'y'] %}`;
43
+
44
+ const offenses = await runLiquidCheck(JsonLiteralQuoteStyle, sourceCode);
45
+
46
+ expect(offenses).to.have.length(2);
47
+ });
48
+
49
+ it('should not report double-quoted strings in object literals', async () => {
50
+ const sourceCode = `{% assign a = {"a": "b", "c": [1, "d"]} %}`;
51
+
52
+ const offenses = await runLiquidCheck(JsonLiteralQuoteStyle, sourceCode);
53
+
54
+ expect(offenses).to.be.empty;
55
+ });
56
+
57
+ it('should not report bare keys in object literals', async () => {
58
+ const sourceCode = `{% assign a = {a: 2} %}`;
59
+
60
+ const offenses = await runLiquidCheck(JsonLiteralQuoteStyle, sourceCode);
61
+
62
+ expect(offenses).to.be.empty;
63
+ });
64
+
65
+ it('should not report single-quoted strings outside of inline JSON literals', async () => {
66
+ const sourceCode = `
67
+ {% assign a = 'plain string' %}
68
+ {% assign b = 'pass' | upcase %}
69
+ {{ 'hello' }}
70
+ `;
71
+
72
+ const offenses = await runLiquidCheck(JsonLiteralQuoteStyle, sourceCode);
73
+
74
+ expect(offenses).to.be.empty;
75
+ });
76
+
77
+ it('should not report parse_json style JSON-in-a-string', async () => {
78
+ const sourceCode = `{% assign a = '{"a": 5}' | parse_json %}`;
79
+
80
+ const offenses = await runLiquidCheck(JsonLiteralQuoteStyle, sourceCode);
81
+
82
+ expect(offenses).to.be.empty;
83
+ });
84
+
85
+ it('should fix single-quoted keys to double-quoted keys', async () => {
86
+ const sourceCode = `{% assign a = {'a': 5} %}`;
87
+
88
+ const offenses = await runLiquidCheck(JsonLiteralQuoteStyle, sourceCode);
89
+ const fixed = applyFix(sourceCode, offenses[0]);
90
+
91
+ expect(fixed).to.equal(`{% assign a = {"a": 5} %}`);
92
+ });
93
+
94
+ it('should fix single-quoted string values to double-quoted values', async () => {
95
+ const sourceCode = `{% assign a = {"key": 'value'} %}`;
96
+
97
+ const offenses = await runLiquidCheck(JsonLiteralQuoteStyle, sourceCode);
98
+ const fixed = applyFix(sourceCode, offenses[0]);
99
+
100
+ expect(fixed).to.equal(`{% assign a = {"key": "value"} %}`);
101
+ });
102
+
103
+ it('should properly escape embedded double quotes when fixing', async () => {
104
+ const sourceCode = `{% assign a = {'msg': 'she said "hi"'} %}`;
105
+
106
+ const offenses = await runLiquidCheck(JsonLiteralQuoteStyle, sourceCode);
107
+ expect(offenses).to.have.length(2);
108
+
109
+ const valueOffense = offenses.find((o) =>
110
+ sourceCode.slice(o.start.index, o.end.index).includes('she said'),
111
+ );
112
+ expect(valueOffense).to.not.be.undefined;
113
+
114
+ const fixedValue = applyFix(sourceCode, valueOffense!);
115
+ expect(fixedValue).to.equal(`{% assign a = {'msg': "she said \\"hi\\""} %}`);
116
+ });
117
+
118
+ it('should report single-quoted strings in function return literals', async () => {
119
+ const sourceCode = `
120
+ {% function result = my_func %}
121
+ {% return {'a': 5} %}
122
+ {% endfunction %}
123
+ `;
124
+
125
+ const offenses = await runLiquidCheck(JsonLiteralQuoteStyle, sourceCode);
126
+
127
+ expect(offenses).to.have.length(1);
128
+ });
129
+ });
@@ -0,0 +1,45 @@
1
+ import { NodeTypes } from '@platformos/liquid-html-parser';
2
+ import { LiquidCheckDefinition, Severity, SourceCodeType } from '../../types';
3
+
4
+ export const JsonLiteralQuoteStyle: LiquidCheckDefinition = {
5
+ meta: {
6
+ code: 'JsonLiteralQuoteStyle',
7
+ name: 'Use double quotes in JSON literals',
8
+ docs: {
9
+ description:
10
+ 'Enforces double-quoted string literals inside inline object/array literals (e.g. {% assign a = {"a": 5} %}). Single-quoted strings inside these literals are not valid JSON.',
11
+ recommended: true,
12
+ url: undefined,
13
+ },
14
+ type: SourceCodeType.LiquidHtml,
15
+ severity: Severity.ERROR,
16
+ schema: {},
17
+ targets: [],
18
+ },
19
+
20
+ create(context) {
21
+ return {
22
+ async String(node, ancestors) {
23
+ if (!node.single) return;
24
+
25
+ // Only flag strings that are inside an inline object/array literal.
26
+ const insideJsonLiteral = ancestors.some(
27
+ (ancestor) =>
28
+ ancestor.type === NodeTypes.JsonHashLiteral ||
29
+ ancestor.type === NodeTypes.JsonArrayLiteral,
30
+ );
31
+ if (!insideJsonLiteral) return;
32
+
33
+ context.report({
34
+ message:
35
+ 'Use double quotes for string literals inside object/array literals (e.g. \'{"key": "value"}\', not "{\'key\': \'value\'}").',
36
+ startIndex: node.position.start,
37
+ endIndex: node.position.end,
38
+ fix: (corrector) => {
39
+ corrector.replace(node.position.start, node.position.end, JSON.stringify(node.value));
40
+ },
41
+ });
42
+ },
43
+ };
44
+ },
45
+ };