@wix/origami-lint 1.34.8 → 1.34.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.
@@ -63,7 +63,7 @@ function checkComponentBindings(at) {
63
63
  if (!rulesApi.hasDataAttributes(node))
64
64
  return;
65
65
  boundPropOnce(at);
66
- for (const [name, , value] of boundAttributes(node))
66
+ for (const [name, , value] of boundAttributes(node, at.input.rulesApi))
67
67
  prop(at, name, value, true);
68
68
  }
69
69
  /** One elementProps entry: its `bindings`, and the keys it binds. */
@@ -80,19 +80,48 @@ function checkEntryBindings(at, entry) {
80
80
  if (className)
81
81
  classNameConditions(entryAt, className, '`className`');
82
82
  entryPropBoundOnce(entryAt, object);
83
- for (const [key, property] of boundEntryKeys(object))
83
+ for (const [key, property] of boundEntryKeys(object, at.input.rulesApi))
84
84
  prop(entryAt, key, property.value, true);
85
85
  }
86
86
  /** A builder call in a structure attribute: it is imported, and so are the names it uses. */
87
87
  function checkCallExpressionImports(input) {
88
88
  if (input.node.callee.type !== 'Identifier' || !isInStructureAttribute(input.node))
89
89
  return;
90
+ if (isSvgCall(input.node, input.rulesApi))
91
+ return checkSvgArguments(input);
90
92
  if (!isBuilderImported(input, input.node.callee))
91
93
  return;
92
94
  const ctxHook = bindingNameImported(input, input.node.callee.name);
93
95
  if (ctxHook)
94
96
  ctxSourceHasName(input, ctxHook);
95
97
  }
98
+ function isSvgCall(node, rulesApi) {
99
+ if (node.callee.type !== 'Identifier')
100
+ return false;
101
+ const found = rulesApi.getImport(node.callee);
102
+ return found?.kind === 'runtime' && found.imported === 'svg';
103
+ }
104
+ function checkSvgArguments({ node, rulesApi, report }) {
105
+ const [url, uri] = node.arguments;
106
+ if (node.arguments.length === 2 && uri.type === 'Literal' && typeof uri.value === 'string' &&
107
+ url.type === 'MemberExpression' && !url.computed && url.property.type === 'Identifier' && url.property.name === 'url') {
108
+ const call = url.object;
109
+ if (call.type === 'CallExpression' && call.arguments.length === 1 &&
110
+ call.callee.type === 'MemberExpression' && !call.callee.computed &&
111
+ call.callee.property.type === 'Identifier' && call.callee.property.name === 'getShapeUrl' &&
112
+ call.callee.object.type === 'Identifier') {
113
+ const media = rulesApi.getImport(call.callee.object);
114
+ const [identifier] = call.arguments;
115
+ if (media?.kind === 'sdk' && media.imported === 'media' &&
116
+ identifier.type === 'Literal' && identifier.value === `wix:image://v1/${uri.value}`)
117
+ return;
118
+ }
119
+ }
120
+ report({
121
+ loc: node.loc,
122
+ message: tracked("An SVG media expression must be `svg(media.getShapeUrl('wix:image://v1/<uri>').url, '<uri>')`, with matching URI strings, svg imported from '@wix/origami-runtime' and media from '@wix/sdk'.", 'CONV-vectorArtExpression.ts:44'),
123
+ });
124
+ }
96
125
  /** Each builder's own row: the shape of its call, a key written twice in it. */
97
126
  const ROW_OF_BUILDER = { all: 'CONV-decode.ts:196', callback: 'CONV-astValue.ts:287', ctx: 'CONV-astValue.ts:276', fn: 'CONV-astValue.ts:287', is: 'CONV-decode.ts:172', raw: 'CONV-decode.ts:28' };
98
127
  const tracked = (message, row) => `${message.slice(0, -1)} (tracker ${row}).`;
@@ -152,7 +181,7 @@ function boundPropOnce(at) {
152
181
  const props = getBindingsProps(bindings && getExpression(bindings), rulesApi);
153
182
  if (!props)
154
183
  return;
155
- for (const [name, attribute] of boundAttributes(node)) {
184
+ for (const [name, attribute] of boundAttributes(node, rulesApi)) {
156
185
  const where = props.raw ? `bindings={raw({ properties: { ${name} } })}` : `bindings={{ props: { ${name} } }}`;
157
186
  if (props.names.has(name))
158
187
  say(at, attribute, `${at.owner} binds \`${name}\` twice: in \`${name}={…}\` and in \`${where}\`. Keep one.`, 'CONV-parseJsx.ts:753');
@@ -162,7 +191,7 @@ function entryPropBoundOnce(at, entry) {
162
191
  const props = getBindingsProps(getProperty(entry, 'bindings')?.value, at.input.rulesApi);
163
192
  if (!props)
164
193
  return;
165
- for (const [key, property] of boundEntryKeys(entry)) {
194
+ for (const [key, property] of boundEntryKeys(entry, at.input.rulesApi)) {
166
195
  const where = props.raw ? `bindings: raw({ properties: { ${key} } })` : `bindings.props.${key}`;
167
196
  if (props.names.has(key))
168
197
  say(at, property, `${at.owner} binds \`${key}\` twice: in \`${key}: …\` and in its \`${where}\`. Keep one.`, 'CONV-parseJsx.ts:753');
@@ -646,19 +675,19 @@ function runsAtRender(at, node) {
646
675
  return isInvoke(node) || getParamReadKind(node) ? describeIn(at, node) : null;
647
676
  }
648
677
  /** The data attributes bound to a value the import reads as a binding; not an `on…` attribute, which it doesn't read at all (OUR-031 reports it). */
649
- function boundAttributes(element) {
678
+ function boundAttributes(element, rulesApi) {
650
679
  return element.openingElement.attributes.flatMap((attribute) => {
651
680
  if (attribute.type !== 'JSXAttribute' || isReservedAttribute(getName(attribute)) || EVENT_ATTRIBUTE.test(getName(attribute)))
652
681
  return [];
653
682
  const value = getExpression(attribute);
654
- return isBound(value) ? [[getName(attribute), attribute, value]] : [];
683
+ return isBound(value) && !(value.type === 'CallExpression' && isSvgCall(value, rulesApi)) ? [[getName(attribute), attribute, value]] : [];
655
684
  });
656
685
  }
657
- function boundEntryKeys(entry) {
686
+ function boundEntryKeys(entry, rulesApi) {
658
687
  return getProperties(entry).flatMap((property) => {
659
688
  const key = getKey(property);
660
689
  const value = bare(property.value);
661
- return key !== null && !RESERVED_ENTRY_KEYS.includes(key) && isBound(value) ? [[key, property]] : [];
690
+ return key !== null && !RESERVED_ENTRY_KEYS.includes(key) && isBound(value) && !(value.type === 'CallExpression' && isSvgCall(value, rulesApi)) ? [[key, property]] : [];
662
691
  });
663
692
  }
664
693
  function getBindingsProps(node, rulesApi) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/origami-lint",
3
- "version": "1.34.8",
3
+ "version": "1.34.10",
4
4
  "description": "Offline lint for an exported Origami site: lints the pages that changed since the last passing run",
5
5
  "type": "module",
6
6
  "bin": {
@@ -21,7 +21,7 @@
21
21
  "test": "node --test 'test/*.test.ts'"
22
22
  },
23
23
  "dependencies": {
24
- "@wix/origami-fonts": "1.0.2",
24
+ "@wix/origami-fonts": "1.0.3",
25
25
  "oxc-parser": "^0.151.0",
26
26
  "oxlint": "^1.39.0",
27
27
  "postcss": "^8.5.3",
@@ -52,5 +52,5 @@
52
52
  ]
53
53
  }
54
54
  },
55
- "falconPackageHash": "e568b814f70d3d18688209f5f49e3d9ab28d65fae5881beef484717f"
55
+ "falconPackageHash": "df5ca3b838244854a52ae4013469c645c6bd6d3e1651ee3702545903"
56
56
  }