@aurelienbbn/oxlint-plugin-shopify-app

中文文档
0.1.2发布于 2026/10/14MITTypeScriptES Module构建来源已验证近 30 天下载 2431

商店应用和扩展代码的自定义克林特规则.

中文使用文档
文档目录7 节
  1. 27个规则,4个范围
  2. 服务器基线:每个应用程序,不需要决定
  3. App 家食谱:Polaris + 原生 a11y
  4. 类别选择:首先决定
  5. 其他选入
  6. 登记的合同库存
  7. 信用概念

@aurelienbn/oxlint-plugin-shopify-app (英语)

npm downloads CI license node

27 oxlint规则为 Shopify apps和扩展:App Store的静态切片,为 Shopify所建,Admin API,以及Polaris App Home的要求.

[尖叫声] Passing lint 并不能让 App Store 或为 Shopify 所建的应用程序符合条件 . 这些规则只执行静态可核查部件.

pnpm add -D @aurelienbbn/oxlint-plugin-shopify-app oxlint   # oxlint >=1.82.0 <2.0.0

没有预设, 无自定义:每个更改都意味着选择一个API,内容,布局,或运行时间策略.

27个规则,4个范围

server baseline   ███████          7   every app, server + route source
App Home recipe   █████████████   13   + 14 jsx-a11y, App Home paths only
category opt-in   ████             4   overrides on the paths the BFS category covers
other opt-in      ███              3   Function source · Polaris manifest · 1 candidate

规则从来不推断应用类别或扩展目标. 你决定,然后范围与 overrides。 。 。 .

服务器基线:每个应用程序,不需要决定

{
  "jsPlugins": ["@aurelienbbn/oxlint-plugin-shopify-app"],
  "rules": {
    "shopify-app/no-script-tag-api": "error",
    "shopify-app/require-mutation-user-errors": "error",
    "shopify-app/require-idempotent-mutations": "error",
    "shopify-app/no-swallowed-auth-response": "error",
    "shopify-app/no-hardcoded-billing-test-mode": "error",
    "shopify-app/webhook-hmac-verification-shape": "error",
    "shopify-app/no-router-redirect-in-embedded-route": "warn"
  }
}
`mutation($id: ID!, $tags: [String!]!) { tagsAdd(id: $id, tags: $tags) { node { id } } }`; // ❌ no userErrors
`mutation { tagsAdd(id: 1, tags: []) { node { id } userErrors { field message } } }`; // ✅

`mutation($input: RefundInput!) { refundCreate(input: $input) { refund { id } userErrors { message } } }`; // ❌ missingIdempotent
`mutation($input: RefundInput!) { refundCreate(input: $input) @idempotent(key: "4f5b6ebf-143c-4da5-8d0f-fb8553bfd85d") { refund { id } } }`; // ❌ literalIdempotencyKey
`mutation($input: RefundInput!, $key: String!) { refundCreate(input: $input) @idempotent(key: $key) { refund { id } } }`; // ✅

try {
  const { admin } = await authenticate.admin(request);
  return admin;
} catch (error) {
  return data({ error: "Something went wrong" }, { status: 500 });
} // ❌ swallows the Response
try {
  await authenticate.admin(request);
} catch (error) {
  if (error instanceof Response) throw error;
  return null;
} // ✅

await billing.require({ plans: [PRO], isTest: true, onFailure }); // ❌ never bills

同上:规则来源中的一个日期表. 发布2025-12-12,审查2026-09-20,要求行政API 2026-04脚本标签 停止运行于2027-03-01: 基线,不是BFS选入.

精确触发、 静态大小写、 选项
规则* 开火
no-script-tag-apiscriptTagCreate 编号 : scriptTagUpdate 变种, REST script_tags 请求,生成脚本标签文档导入
require-mutation-user-errors图形QL 字符串或模板中未选中的顶级突变字段 userErrors 编号 : *UserErrors 字段
require-idempotent-mutations17起退款、库存和地点变异之一 偶数变化日志 无 @idempotent (单位:千美元)missingIdempotent),或带有字符串-升键(literalIdempotencyKey(中文(简体) )
no-swallowed-auth-responseauthenticate.admin/webhook/flow/fulfillmentService/pos, (中文(简体) ), authenticate.public.*, (中文(简体) ), billing.require/request/cancel/updateUsageCappedAmount, (中文(简体) ), scopes.request,或一个 redirect 从 authenticate.admin内 try 职务 catch 没有 throw 也没有 instanceof Response 测试。 这些掷出 Response 作为控制流
no-hardcoded-billing-test-mode字义 isTest: true 在第一个论点中 billing.require/request/check/cancel/createUsageRecord,或字义 test: true 打开 appSubscriptionCreate 编号 : appPurchaseOneTimeCreate
webhook-hmac-verification-shape包含此选项的文件 X-Shopify-Hmac-SHA256 只有页眉名称 : .update(JSON.stringify(...)) 编号 createHmac 链; createHmac 没有 timingSafeEqual 编号 : safeCompare 标识符
no-router-redirect-in-embedded-route ⚠️ warnredirect 从 react-router 或者说 @remix-run/{node,server-runtime,cloudflare} 调用的模块中 authenticate.admin,或任何带有 https:// 或者说 shopify:// 目标。 相对重定向通常仍然有效,因此 warn
规则安静选项( 默认)
require-mutation-user-errors未知的片段,字段内的插值,无法解析的文本. 同一文件片段被跟踪ignoreMutations (单位:千美元)[]:没有球场的有效载荷. 排除非Shopify GraphQL 客户端通过 overrides
require-idempotent-mutations—— 说since (未设定): 管理员 API 版本,您标注, YYYY-01/04/07/10下图 2026-04 安静 missingIdempotent 仅限
no-hardcoded-billing-test-mode测试和固定文件—— 说
webhook-hmac-verification-shape认证到另一个文件; OAuth hmac 查询检查safeCompareNames (单位:千美元)["timingSafeEqual", "safeCompare"]页:1

需要17起变异 @idempotent数字 : refundCreate • 妇女 inventoryShipmentReceive • 妇女 inventoryAdjustQuantities • 妇女 inventoryMoveQuantities • 妇女 inventorySetQuantities • 妇女 inventorySetOnHandQuantities • 妇女 inventoryShipmentCreateInTransit • 妇女 inventoryShipmentCreate • 妇女 inventoryTransferCreate • 妇女 inventoryTransferCreateAsReadyToShip • 妇女 inventoryTransferDuplicate • 妇女 inventoryTransferSetItems • 妇女 inventorySetScheduledChanges • 妇女 inventoryActivate • 妇女 inventoryShipmentAddItems • 妇女 locationActivate • 妇女 locationDeactivate

App 家食谱:Polaris + 原生 a11y

复制已测试的 应用 家食谱在 App Home 源码上运行 :

oxlint --config app-home.oxlintrc.json app
app-home.oxlintrc.json
├── jsx-a11y (14 upstream rules)   native HTML accessibility
└── shopify-app (13 rules)         Polaris App Home v1.0 contracts
      no-nav-emoji · no-viewport-zoom-disable · s-action-slot-contract
      s-button-accessible-name · s-button-submit-no-navigation · s-clickable-accessible-name
      s-form-control-label-required · s-modal-actions-use-slots · s-modal-heading-required
      s-money-field-no-currency-symbol (warn) · s-page-aside-visible
      s-spinner-accessible-label · s-tooltip-no-interactive-content

把这个食谱放在App Home上. 离职和客户账户部分有不同的合同.

<s-button icon="edit" />                                     // ❌ s-button-accessible-name
<s-button icon="edit" accessibilityLabel="Edit product" />   // ✅

<s-text-field labelAccessibilityVisibility="exclusive" />        // ❌ hiding the label doesn't remove the need for one
<s-search-field label="Search" labelAccessibilityVisibility="exclusive" /> // ✅

<s-money-field label="Price ($)" />                              // ❌ currency formatting is component-owned

仅静态:静态诊断不能证明已形成状态.

每项规则合同和哪些静态检查缺失
规则合同
s-action-slot-contract无条件直接页面/模式儿童,包括碎片. primary-action页:1 s-button 与 variant=primary。二级槽:二级/自动按钮;页面也接受按钮组
s-modal-actions-use-slots模式动作按钮使用模式动作槽. 选项 components (单位:千美元)["s-modal"], (中文(简体) ), actionElements (单位:千美元)["s-button", "button"](中文(简体) )
s-modal-heading-required无空 heading 在模式上。 选项 components (单位:千美元)["s-modal"](中文(简体) )
s-page-aside-visible直接放在一页下,明确 inlineSize 大小( 不会渲染)
s-button-submit-no-navigation静态 href 编号 : commandFor 覆盖提交/重置行为
s-button-accessible-name, (中文(简体) ), s-clickable-accessible-name直接内容, 包含片段; 图标元素和空字符不命名动作
s-form-control-label-required字段使用 label; 切换和投放区域可能使用其文档 accessibilityLabel 换句话说 已知 null,布尔值和空值被拒绝
s-spinner-accessible-label无空 accessibilityLabel
s-tooltip-no-interactive-content无条件的固有后人; 在用户组件边界上停止
s-money-field-no-currency-symbol以字面标签/位置符表示的Unicode货币符号. 不检查翻译或财务算术
no-viewport-zoom-disablemaximum-scale 5岁以下, user-scalable=no 编号 : 0
no-nav-emoji导航标签中的emoji. 选项 navComponents (单位:千美元)["s-app-nav", "ui-nav-menu"](中文(简体) )

规则读取内在元素,静态字元,而内线对象以有效覆被相向相向相向相向.

已检查⚠️仍然需要审查或进行检查
内在元素、静态文字、内向扩展运行时表达式, 后期未知的扩展, 翻译字符串, 自定义组件输出
直接儿童和碎片有条件渲染、包装、按钮组内容、其他嵌入元素、用户组件

类别选择:首先决定

规则打开它
no-draft-order-custom-discounts在Shopify 5.5.2下建造的折扣应用自动化系统。 将商家驱动的草稿订单工作流程保留在外头
no-asset-api-theme-writes在审查了它的页面构建器、备份/存储器、 SIO、 内容锁定和开发者工具的例外之后, 创建Shopify 3.2.2下的应用程序代码
no-admin-rest-api在 GraphQL 政策下的新公共应用程序. 现有公共和定制应用程序:先作出明确的移民决定
require-fetch-abort-signal在请求取消政策时,明确退出扩展。 与运行时间截止时间证据对等: 信号不是超时

[尖叫声] 永远不要用被子瞄准 extensions/**数字 : 无法分辨出退出、客户账户、管理员、函数和主题.

管理扩展,允许 vs 报告, no-admin-rest-api 范围

保留 require-fetch-abort-signal 关闭管理员 UI 扩展名: 相对 fetch("/api/...") 给应用程序自己的域是他们的 文件自动认证路径;注销是一种离职和客户账户政策。 类别适用性和例外: 为商店化要求而建。 。 。 .

规则允许报告* 审查投入
no-draft-order-custom-discounts提及的答复选择 appliedDiscount (不是输入)应用自定义折扣的草稿-订单突变(平分突变字段)可变提供突变输入
no-asset-api-theme-writesREST 资产 API GET已识别写入方法; 主题文件突变—— 说
require-fetch-abort-signal明确的可用信号形状; 公认的 Request-自有信号fetch (直接或 window 编号 : globalThis 编号 : self无未知的选项变量和后起倒数的相差不能证明

no-admin-rest-api数字 :

报告允许需求审查
从 REST 资源导入 @shopify/shopify-api/rest/admin,动态导入,无阴影 require图QL, Storefront/Ajax API, 只类型导入SDK 实例, 包装
无阴影的全局 fetch 带有可识别的 REST 管理员 URL不相关的主机, 阴影函数动态选择的 API 版本和资源名

其他选入

functions-no-unavailable-runtime-apis 打开 仅限 JS 函数来源。 。 。 . s-known-components 在App Home的源头, 除了食谱 no-session-or-token-logging 是一个候选人,默认关闭.

<s-stak gap="base" />                           // ❌ unknown element
<s-button varient="primary">Save</s-button>     // ❌ unknown attribute
<s-button variant="primary" onClick={save}>Save</s-button> // ✅ declared attribute and event

s-known-components 从您的项目中读取其词汇, 从此软件包中读取 : 自定义元素表单 customElements 已安装的最近字段 @shopify/polaris-types (1.0.7及后). 它跟随你安装的主线. 没有包裹,或者没有 customElements 字段:规则保持沉默. 明确 manifestPath 无法读取,或者一个没有元素的表, 报告每个文件一次.

触发和选项
规则状态* 开火选项( 默认)
functions-no-unavailable-runtime-apis选入, 仅限 JS 函数来源; 所有其他表面合法使用这些 APIaync 函数, 顶级 await, (中文(简体) ), .then() 未显示的呼叫结果 Promise, (中文(简体) ), setTimeout, (中文(简体) ), setInterval, (中文(简体) ), fetch, (中文(简体) ), crypto, (中文(简体) ), URL, (中文(简体) ), URLSearchParams, (中文(简体) ), process, (中文(简体) ), Buffer, (中文(简体) ), require, (中文(简体) ), node: 进口, Date.now()零弧线 Date, (中文(简体) ), Math.random(), (中文(简体) ), performance.now()—— 说
s-known-components选入, App 主机源s-* 元素 运算表不声明;非声明属性的属性,公有字段或 on<event> 处理者。 总是允许 : key, (中文(简体) ), ref, (中文(简体) ), slot, (中文(简体) ), children, (中文(简体) ), id, (中文(简体) ), data-*. 允许要素(App Bridge导航链路)的子女保留自己的合同manifestPath (发现), allowElements (单位:千美元)["s-app-nav", "s-app-window"]页:1, allowAttributes (单位:千美元)[](中文(简体) )
no-session-or-token-logging候选人,默认关闭console 编号 : logger 编号 : log 电话曝光 session, (中文(简体) ), accessToken, (中文(简体) ), access_token, (中文(简体) ), sessionToken, (中文(简体) ), idToken (识别器,简称,终端成员,分布,模板孔, JSON.stringify),或 a payload 从 authenticate.webhookloggerObjects (单位:千美元)["console", "logger", "log"], (中文(简体) ), sensitiveNames (上文5段), webhookPayloadNames (单位:千美元)["payload"]页:1

no-session-or-token-logging 除网钩有效载荷钩外,是域中立的: 更喜欢核心机密规则 一旦存在.

超出范围,谁拥有它
关切拥有者
本地 HTML 访问上游 jsx-a11y 规则
极地财产联盟商店组件类型
对比 注意 复制质量 键盘行为 响应布局 运行时间 API行为语义审查或浏览器/运行时间证据
页面面包屑, 选择选项内容没有总括规则:Shopify的指导冲突
脚本标记范围导入范围为生成/admin源; 附带 URL 字符串不是 API 调用

每条规则独立执行 Shopify 文档概念; 源文件带有 greppable @attribution 标签; 没有执行或推销.

按审查日期分列的资料来源
已审查来源
2026-09-05 · 极地人REST 行政移徙政策, (中文(简体) ), 按钮, (中文(简体) ), 可点击, (中文(简体) ), 旋转器, (中文(简体) ), 窗体组件, (中文(简体) ), 页次, (中文(简体) ), 模式, (中文(简体) ), 工具提示, (中文(简体) ), 钱田
2026-09-20- 服务器 & API管理图形QL 引用, (中文(简体) ), 偶数变化日志, (中文(简体) ), 一能指南,控制流量 shopify-app-js, (中文(简体) ), 反应路由器应用程序模板, (中文(简体) ), 收费 API 参考, (中文(简体) ), webhook HTTPS 传送, (中文(简体) ), 函数的 JavaScript, (中文(简体) ), 函数输入/产出限制, (中文(简体) ), 受保护的客户数据, (中文(简体) ), 脚本 标记折旧更改日志
2026-09-24-极地表显示应用 家用网络组件,则 customElements 字段和图示 自定义元素外观 格式,通过 @shopify/polaris-types 1.1.0和2.0.0-rc.0(相同的标记和属性)

登记的合同库存

从软件包导出 pnpm catalog. 规则特定选项和限制在上文和源测试中都有描述.

规则/检查触发或审查范围
functions-no-unavailable-runtime-apis取消ASync 代码、定时器、获取、加密、 URL、 进程、 缓冲、 节点: 导入、 时钟或随机读取的 Shopify 函数源; 将其范围设定为带有超文本功能目录 .
no-admin-rest-api取消商店设置 管理资源导入和未遮蔽的获取呼叫以识别 REST 管理端点; 启用新的公共应用程序 .
no-asset-api-theme-writesDisallow主题文件通过资产 API 或主题文件突变来写入.
no-draft-order-custom-discounts取消使用自定义折扣的订单草稿突变.
no-hardcoded-billing-test-mode贬低字数 isTest: true * 电话和文字 test: true 在应用程序订阅Create/appPurchase OneTimeCreate 外部测试文件上,因为测试收费从来不向商家收费.
no-nav-emojiAPP导航标签内出问题 选项 navComponents 覆盖选中元素名称 .
no-router-redirect-in-embedded-route更喜欢通过认证返回的重定向帮助器. 在认证管理员请求的模块中管理路由器的再定向,并始终为https://或shookify://godes提供.
no-script-tag-apiDisallow Script Tag API,它停止了在2027-03-01上运行,有利于Web像素和主题应用扩展.
no-session-or-token-logging拒绝通过会话对象、访问或会话符号,或认证。 webhook 有效载荷呼叫控制台/调度器 选项 loggerObjects, (中文(简体) ), sensitiveNames 财务报告和审定财务报表 webhookPayloadNames 覆盖匹配的名称 .
no-swallowed-auth-responseDisallow 认证.*,计费. required/request/cancel/update Usage CappedAmount, 瞄准镜. request and independent direct helper in a trign understands who catch never redrows, 因为他们将响应作为控制流扔出.
no-viewport-zoom-disable关闭阻断缩放的视图端口标记 .
require-fetch-abort-signal需要获取呼叫( 直接或窗口/ globalThis/ 自定义) 才能通过中止信号 .
require-idempotent-mutations在17个存货上要求@idempotent(钥匙:可变美元),退款及位置变异拒绝Admin API 2026-04的通话,以及不允许的字形密钥. 选项 since 命名工程指针的API版本.
require-mutation-user-errors要求每个 GraphQL 变异字段选择用户错误(或一个 *UserErrors 字段). 选项 ignoreMutations 列出没有这种有效载荷域的变异名称.
s-action-slot-contract验证Polaris的页面/模式动作插槽元素类型、变体和单一主要特性.
s-button-accessible-name在静态无名的Polaris按钮上需要访问标签,包括只使用图标的按钮.
s-button-submit-no-navigation取消静态螺旋或命令 对于超过 Polaris 按钮提交或重设行为的值 .
s-clickable-accessible-name要求无障碍 标注在 Polaris 可点击组件上而不包含静态可读内容 .
s-form-control-label-required要求在极地形成字段上设置标签;开关和投放区可以使用其已记录的可访问性Label替代.
s-known-components否定 s-* 项目安装的元素和属性 @shopify/polaris-types 《自定义要素宣言》不宣布;在没有明确决心时保持沉默。 选项 manifestPath, (中文(简体) ), allowElements 财务报告和审定财务报表 allowAttributes。 。 。 .
s-modal-actions-use-slots要求模式动作按钮使用模式动作槽. 选项 components 财务报告和审定财务报表 actionElements 覆盖选中元素名称 .
s-modal-heading-required在模式元素上需要一个标题属性 。 选项 components 覆盖选中元素名称 .
s-money-field-no-currency-symbol以Polaris货币域标签和占位符表示的否定字面货币符号,其货币格式化为组件自有.
s-page-aside-visible当一个明显的小或大内线Size使其无法渲染时,将 s-page 忽略内容.
s-spinner-accessible-label在极地自旋器上需要非空取Label.
s-tooltip-no-interactive-content在Polaris工具提示中,断绝静态互动的内在后人;自定义组件和有条件输出需要审查.
webhook-hmac-verification-shape在读取 X-Shopify-Hmac-SHA256 标题的文件中,不允许hashing JSON.stringfy 输出并需要时间安全比较. 选项 safeCompareNames 覆盖已接受的比较标识符.

信用概念

版本与发布记录

@aurelienbbn/oxlint-plugin-shopify-app 共发布 3 个版本,首次发布于 2026/09/25;过去 12 个月发布了 3 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.1.2latest2026/10/1424 天前
0.1.12026/09/251 个月前
0.1.02026/09/251 个月前

关于 @aurelienbbn/oxlint-plugin-shopify-app 的常见问题

@aurelienbbn/oxlint-plugin-shopify-app 是什么?

商店应用和扩展代码的自定义克林特规则.

如何安装 @aurelienbbn/oxlint-plugin-shopify-app?

在项目目录运行 npm install @aurelienbbn/oxlint-plugin-shopify-app,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:oxlint(>=1.82.0 <2.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@aurelienbbn/oxlint-plugin-shopify-app 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@aurelienbbn/oxlint-plugin-shopify-app 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@aurelienbbn/oxlint-plugin-shopify-app 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js ^22.19.0 || ^24.11.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@aurelienbbn/oxlint-plugin-shopify-app 可以商用吗?

@aurelienbbn/oxlint-plugin-shopify-app 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@aurelienbbn/oxlint-plugin-shopify-app 的下载量有多少?

根据 npm 官方下载统计,@aurelienbbn/oxlint-plugin-shopify-app 在 2026/10/07 – 2026/11/05 这 30 天内被下载 2,431 次,日均约 81 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@aurelienbbn/oxlint-plugin-shopify-app 还在维护吗?

最新版本 0.1.2 发布于 2026/10/14(24 天前);至今共发布 3 个版本,其中过去 12 个月发布了 3 个;首次发布于 2026/09/25。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。