@platformos/platformos-check-common 0.0.16 → 0.0.18
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 +14 -0
- package/dist/checks/index.d.ts +1 -1
- package/dist/checks/index.js +6 -2
- package/dist/checks/index.js.map +1 -1
- package/dist/checks/json-literal-quote-style/index.d.ts +2 -0
- package/dist/checks/json-literal-quote-style/index.js +42 -0
- package/dist/checks/json-literal-quote-style/index.js.map +1 -0
- package/dist/checks/liquid-html-syntax-error/checks/InvalidAssignSyntax.d.ts +21 -0
- package/dist/checks/liquid-html-syntax-error/checks/InvalidAssignSyntax.js +60 -0
- package/dist/checks/liquid-html-syntax-error/checks/InvalidAssignSyntax.js.map +1 -0
- package/dist/checks/liquid-html-syntax-error/checks/InvalidOutputPush.d.ts +17 -0
- package/dist/checks/liquid-html-syntax-error/checks/InvalidOutputPush.js +37 -0
- package/dist/checks/liquid-html-syntax-error/checks/InvalidOutputPush.js.map +1 -0
- package/dist/checks/liquid-html-syntax-error/checks/InvalidTagSyntax.js +1 -1
- package/dist/checks/liquid-html-syntax-error/index.js +17 -0
- package/dist/checks/liquid-html-syntax-error/index.js.map +1 -1
- package/dist/checks/partial-call-arguments/extract-undefined-variables.d.ts +14 -0
- package/dist/checks/partial-call-arguments/extract-undefined-variables.js +234 -0
- package/dist/checks/partial-call-arguments/extract-undefined-variables.js.map +1 -0
- package/dist/checks/partial-call-arguments/index.d.ts +2 -0
- package/dist/checks/partial-call-arguments/index.js +117 -0
- package/dist/checks/partial-call-arguments/index.js.map +1 -0
- package/dist/checks/unknown-property/index.js +22 -2
- package/dist/checks/unknown-property/index.js.map +1 -1
- package/dist/checks/valid-frontmatter/index.d.ts +2 -0
- package/dist/checks/valid-frontmatter/index.js +279 -0
- package/dist/checks/valid-frontmatter/index.js.map +1 -0
- package/dist/frontmatter/index.d.ts +1 -59
- package/dist/frontmatter/index.js +6 -298
- package/dist/frontmatter/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/checks/index.ts +6 -2
- package/src/checks/json-literal-quote-style/index.spec.ts +129 -0
- package/src/checks/json-literal-quote-style/index.ts +45 -0
- package/src/checks/liquid-html-syntax-error/checks/InvalidAssignSyntax.spec.ts +422 -0
- package/src/checks/liquid-html-syntax-error/checks/InvalidAssignSyntax.ts +63 -0
- package/src/checks/liquid-html-syntax-error/checks/InvalidOutputPush.spec.ts +104 -0
- package/src/checks/liquid-html-syntax-error/checks/InvalidOutputPush.ts +39 -0
- package/src/checks/liquid-html-syntax-error/checks/InvalidTagSyntax.spec.ts +86 -2
- package/src/checks/liquid-html-syntax-error/checks/InvalidTagSyntax.ts +1 -1
- package/src/checks/liquid-html-syntax-error/index.ts +19 -0
- package/src/checks/partial-call-arguments/extract-undefined-variables.spec.ts +218 -0
- package/src/checks/{metadata-params → partial-call-arguments}/extract-undefined-variables.ts +31 -6
- package/src/checks/partial-call-arguments/index.spec.ts +436 -0
- package/src/checks/{metadata-params → partial-call-arguments}/index.ts +18 -11
- package/src/checks/undefined-object/index.spec.ts +101 -0
- package/src/checks/unknown-property/index.spec.ts +42 -0
- package/src/checks/unknown-property/index.ts +24 -2
- package/src/checks/valid-frontmatter/index.spec.ts +666 -0
- package/src/checks/valid-frontmatter/index.ts +344 -0
- package/src/frontmatter/index.ts +9 -344
- package/src/checks/metadata-params/extract-undefined-variables.spec.ts +0 -115
- package/src/checks/metadata-params/index.spec.ts +0 -257
|
@@ -401,6 +401,27 @@ query {
|
|
|
401
401
|
expect(offenses[0].message).toEqual("Unknown property 'asd' on 'a'.");
|
|
402
402
|
});
|
|
403
403
|
|
|
404
|
+
it('should handle hash literals with quoted string keys', async () => {
|
|
405
|
+
const sourceCode = `{% assign c = { "errors": {}, "valid": true } %}{{ c.valid }}{{ c.errors }}{{ c.missing }}`;
|
|
406
|
+
const offenses = await runLiquidCheck(UnknownProperty, sourceCode);
|
|
407
|
+
expect(offenses).toHaveLength(1);
|
|
408
|
+
expect(offenses[0].message).toEqual("Unknown property 'missing' on 'c'.");
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
it('should handle hash literals with mixed bare and quoted keys', async () => {
|
|
412
|
+
const sourceCode = `{% assign a = {x: 5, "y": 10} %}{{ a.x }}{{ a.y }}{{ a.z }}`;
|
|
413
|
+
const offenses = await runLiquidCheck(UnknownProperty, sourceCode);
|
|
414
|
+
expect(offenses).toHaveLength(1);
|
|
415
|
+
expect(offenses[0].message).toEqual("Unknown property 'z' on 'a'.");
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
it('should handle nested hash literals with quoted keys', async () => {
|
|
419
|
+
const sourceCode = `{% assign a = { "outer": { "inner": 1 } } %}{{ a.outer.inner }}{{ a.outer.missing }}`;
|
|
420
|
+
const offenses = await runLiquidCheck(UnknownProperty, sourceCode);
|
|
421
|
+
expect(offenses).toHaveLength(1);
|
|
422
|
+
expect(offenses[0].message).toEqual("Unknown property 'missing' on 'a.outer'.");
|
|
423
|
+
});
|
|
424
|
+
|
|
404
425
|
it('should report unknown property on hash literal assigned via another variable', async () => {
|
|
405
426
|
const sourceCode = `{% assign a = {a: 5} %}{% assign b = a.b %}`;
|
|
406
427
|
const offenses = await runLiquidCheck(UnknownProperty, sourceCode);
|
|
@@ -409,6 +430,27 @@ query {
|
|
|
409
430
|
});
|
|
410
431
|
});
|
|
411
432
|
|
|
433
|
+
describe('function tag reassignment', () => {
|
|
434
|
+
it('should not report unknown property after function tag reassigns a variable', async () => {
|
|
435
|
+
const sourceCode = `{% assign object = { "valid": true, "id": id, "role": role } %}
|
|
436
|
+
{% function object = 'modules/core/commands/execute', object: object, mutation_name: 'some_mutation' %}
|
|
437
|
+
{% if object.errors == blank %}
|
|
438
|
+
{{ object.valid }}
|
|
439
|
+
{% endif %}`;
|
|
440
|
+
const offenses = await runLiquidCheck(UnknownProperty, sourceCode);
|
|
441
|
+
expect(offenses).toHaveLength(0);
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
it('should still report unknown property before function tag reassignment', async () => {
|
|
445
|
+
const sourceCode = `{% assign object = { "valid": true, "id": "123" } %}
|
|
446
|
+
{{ object.missing }}
|
|
447
|
+
{% function object = 'modules/core/commands/execute', object: object %}`;
|
|
448
|
+
const offenses = await runLiquidCheck(UnknownProperty, sourceCode);
|
|
449
|
+
expect(offenses).toHaveLength(1);
|
|
450
|
+
expect(offenses[0].message).toEqual("Unknown property 'missing' on 'object'.");
|
|
451
|
+
});
|
|
452
|
+
});
|
|
453
|
+
|
|
412
454
|
describe('error message formatting', () => {
|
|
413
455
|
it('should include variable name in error message', async () => {
|
|
414
456
|
const sourceCode = `{% assign myVar = '{"a": 1}' | parse_json %}
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
TextNode,
|
|
12
12
|
GraphQLMarkup,
|
|
13
13
|
GraphQLInlineMarkup,
|
|
14
|
+
FunctionMarkup,
|
|
14
15
|
HashAssignMarkup,
|
|
15
16
|
JsonHashLiteral,
|
|
16
17
|
JsonArrayLiteral,
|
|
@@ -263,6 +264,17 @@ export const UnknownProperty: LiquidCheckDefinition = {
|
|
|
263
264
|
}
|
|
264
265
|
}
|
|
265
266
|
|
|
267
|
+
// {% function object = 'partial_name', arg: value %}
|
|
268
|
+
// The function tag reassigns the variable to the return value of the partial,
|
|
269
|
+
// which has an unknown shape. Close any tracked shape so we don't false-positive.
|
|
270
|
+
if (isLiquidTagFunction(node)) {
|
|
271
|
+
const markup = node.markup;
|
|
272
|
+
const variableName = markup.name.name;
|
|
273
|
+
if (variableName) {
|
|
274
|
+
closeShapeRange(variableName, node.position.start);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
266
278
|
// {% hash_assign x["key"] = value %} or {% hash_assign x["a"]["b"] = value %}
|
|
267
279
|
if (isLiquidTagHashAssign(node)) {
|
|
268
280
|
const markup = node.markup;
|
|
@@ -531,6 +543,10 @@ function isLiquidTagGraphQL(
|
|
|
531
543
|
return node.name === NamedTags.graphql && typeof node.markup !== 'string';
|
|
532
544
|
}
|
|
533
545
|
|
|
546
|
+
function isLiquidTagFunction(node: LiquidTag): node is LiquidTag & { markup: FunctionMarkup } {
|
|
547
|
+
return node.name === NamedTags.function && typeof node.markup !== 'string';
|
|
548
|
+
}
|
|
549
|
+
|
|
534
550
|
function isLiquidTagHashAssign(node: LiquidTag): node is LiquidTag & { markup: HashAssignMarkup } {
|
|
535
551
|
return node.name === NamedTags.hash_assign && typeof node.markup !== 'string';
|
|
536
552
|
}
|
|
@@ -578,10 +594,16 @@ function inferShapeFromLiteralNode(
|
|
|
578
594
|
if (node.type === NodeTypes.JsonHashLiteral) {
|
|
579
595
|
const properties = new Map<string, PropertyShape>();
|
|
580
596
|
for (const entry of node.entries) {
|
|
581
|
-
// Keys
|
|
597
|
+
// Keys can be VariableLookup nodes (bare keys) or String nodes (quoted keys)
|
|
598
|
+
let keyName: string | undefined;
|
|
582
599
|
if (entry.key.type === NodeTypes.VariableLookup && entry.key.name) {
|
|
600
|
+
keyName = entry.key.name;
|
|
601
|
+
} else if (entry.key.type === NodeTypes.String) {
|
|
602
|
+
keyName = entry.key.value;
|
|
603
|
+
}
|
|
604
|
+
if (keyName) {
|
|
583
605
|
const valueShape = inferShapeFromExpressionNode(entry.value);
|
|
584
|
-
properties.set(
|
|
606
|
+
properties.set(keyName, valueShape ?? { kind: 'primitive' });
|
|
585
607
|
}
|
|
586
608
|
}
|
|
587
609
|
return { kind: 'object', properties };
|