copy_tuner_client 2.1.0 → 2.1.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a3c816e1f12e5715861194284864c00ab5d18428d3c56b6a3140cfe9db9cd360
4
- data.tar.gz: d9a8cd76caf12860c0a981a840655254a5aab64665745d16f4524ded77821771
3
+ metadata.gz: 34fcab16da8e238f416a8d4be1c68212818ae95afb7f82112391517e901fbb8f
4
+ data.tar.gz: dc9a727af71a83e39cb4d4c4aa41a8d1e982244936f294462da8e44b0b57d9fc
5
5
  SHA512:
6
- metadata.gz: 1538da853220ee8f4bfc4942023e1afcfd55dc4f719a89b3c965d8719acb57ec5bd418d8821e72eee8adbb5b59ca2f23b462d8894b9239734ff68a30b8a0a074
7
- data.tar.gz: '091eee7aae91c30f88fb294716bd9a139d55d7ac90d982602e14305d2c43203360dc81b98092e17dd931dcce1885940af27a47f0031e374e9724eaf4898934d5'
6
+ metadata.gz: aed1f966e3c35e5d25f82fc96c56ff5532dd0b8d651be0a275f7f6f85f10a0bc58efe6b414ef004140306be70c2c2294c8c1054a112530a32e21070b098f4557
7
+ data.tar.gz: 9179c177ecbc48104ea0b17db2e6adc1f88e8aa4a5dac4eb0366e171543d2f83bc03e160d7f6cadf65ccb4e8664280904b0c06eca2260d222c9463a51449ff04
@@ -19,7 +19,10 @@ module CopyTunerClient
19
19
  # NOTE: 戻り値は [html, skipped]。skipped は data-copyray-key を付与できなかったことを表す
20
20
  # (巨大DOMでのスキップ・Nokogiri 例外の双方で true)。ミドルウェアがこれを JS に伝え、
21
21
  # オーバーレイ非対応である旨をツールバーで案内する。
22
- def rewrite(html)
22
+ # NOTE: fragment: true は turbo stream など body に差し込む HTML 断片向け。
23
+ # Nokogiri::HTML だと html/body/DOCTYPE ラッパが付いて断片が壊れるため、
24
+ # fragment パーサでラッパを付けずに走査・除去する。
25
+ def rewrite(html, fragment: false)
23
26
  # NOTE: ボディが ASCII-8BIT に転落していると UTF-8 の Marker::PREFIX との include? 比較が
24
27
  # Encoding::CompatibilityError を投げる(ミドルウェアのボディ連結で非ASCIIバイトを含む
25
28
  # ASCII-8BIT チャンクが混じると発生)。実バイト列は本来 UTF-8 なので判定用に UTF-8 とみなす。
@@ -35,7 +38,7 @@ module CopyTunerClient
35
38
  # NOTE: 閾値超は Nokogiri を通さず可視トークン除去のみ。skipped=true で編集導線を諦めた旨を伝える。
36
39
  return [strip_markers(scannable), true] if scannable.bytesize > MAX_REWRITE_BYTESIZE
37
40
 
38
- [rewrite_with_nokogiri(scannable), false]
41
+ [rewrite_with_nokogiri(scannable, fragment: fragment), false]
39
42
  rescue StandardError => e
40
43
  # NOTE: Copyray は開発支援機能なので、壊れた HTML 等で Nokogiri 処理が落ちても
41
44
  # ページを 500 にしない。data-copyray-key 付与(編集導線)は諦め、最低限可視トークンだけ除去する。
@@ -51,8 +54,8 @@ module CopyTunerClient
51
54
  scannable.gsub(Marker::SCAN_REGEXP, '')
52
55
  end
53
56
 
54
- def rewrite_with_nokogiri(scannable)
55
- doc = Nokogiri::HTML(scannable)
57
+ def rewrite_with_nokogiri(scannable, fragment: false)
58
+ doc = fragment ? Nokogiri::HTML.fragment(scannable) : Nokogiri::HTML(scannable)
56
59
 
57
60
  doc.traverse do |node|
58
61
  if node.text?
@@ -11,18 +11,22 @@ module CopyTunerClient
11
11
  def call(env)
12
12
  CopyTunerClient::TranslationLog.clear
13
13
  status, headers, response = @app.call(env)
14
- if html_headers?(status, headers) && body = response_body(response)
14
+ if rewritable?(status, headers) && body = response_body(response)
15
15
  csp_nonce = env['action_dispatch.content_security_policy_nonce'] || env['secure_headers_content_security_policy_nonce']
16
16
  # NOTE: CSS/JS 挿入の前に Rewriter を通す。serialize 後も </body> は必ず出力されるので
17
17
  # append_to_html_body の rindex は機能し、CSS/JS タグはトークン非含有なので二重処理も起きない。
18
18
  # NOTE: skipped は data-copyray-key を付与できなかったこと(巨大DOM/Nokogiri例外)を表す。
19
19
  # JS にこれを伝え、オーバーレイ非対応である旨をツールバーで案内させる。
20
- body, skipped = CopyTunerClient::Copyray::Rewriter.rewrite(body)
21
- body = append_js(body, csp_nonce, skipped: skipped)
20
+ # NOTE: turbo stream はページ断片なので fragment パーサで走査する(html/body ラッパを付けない)。
21
+ turbo_stream = turbo_stream?(headers)
22
+ body, skipped = CopyTunerClient::Copyray::Rewriter.rewrite(body, fragment: turbo_stream)
23
+ # NOTE: ブートストラップ JS はフルページ読み込み時に一度だけ挿入すればよい。turbo stream 断片には
24
+ # 挿入先の </body> も無く、既に初期化済みのページへマージされるだけなので挿入しない。
25
+ body = append_js(body, csp_nonce, skipped: skipped) unless turbo_stream
22
26
  content_length = body.bytesize.to_s
23
27
  headers['Content-Length'] = content_length
24
28
  # maintains compatibility with other middlewares
25
- if defined?(ActionDispatch::Response::RackBody) && ActionDispatch::Response::RackBody === response
29
+ if defined?(ActionDispatch::Response::RackBody) && response.is_a?(ActionDispatch::Response::RackBody)
26
30
  ActionDispatch::Response.new(status, headers, [body]).to_a
27
31
  else
28
32
  [status, headers, [body]]
@@ -65,14 +69,19 @@ module CopyTunerClient
65
69
  end
66
70
 
67
71
  def file?(headers)
68
- headers["Content-Transfer-Encoding"] == 'binary'
72
+ headers['Content-Transfer-Encoding'] == 'binary'
69
73
  end
70
74
 
71
- def html_headers?(status, headers)
75
+ def rewritable?(status, headers)
72
76
  [200, 422].include?(status) &&
77
+ headers['Content-Type'] &&
78
+ (headers['Content-Type'].include?('text/html') || turbo_stream?(headers)) &&
79
+ !file?(headers)
80
+ end
81
+
82
+ def turbo_stream?(headers)
73
83
  headers['Content-Type'] &&
74
- headers['Content-Type'].include?('text/html') &&
75
- !file?(headers)
84
+ headers['Content-Type'].include?('text/vnd.turbo-stream.html')
76
85
  end
77
86
 
78
87
  def response_body(response)
@@ -1,6 +1,6 @@
1
1
  module CopyTunerClient
2
2
  # Client version
3
- VERSION = '2.1.0'.freeze
3
+ VERSION = '2.1.2'.freeze
4
4
 
5
5
  # API version being used to communicate with the server
6
6
  API_VERSION = '2.0'.freeze
@@ -3,8 +3,9 @@ name: copy-tuner-to-t-migrate
3
3
  description: >-
4
4
  copy_tuner_client v2.0.0 への移行で、削除された独自ヘルパー tt の呼び出しを Rails 標準の t(translate)へ
5
5
  置換するスキル。tt は PR #122 で存在理由を失い gem から削除されたため、残った tt(...) は NoMethodError に
6
- なる。大半は機械的に tt( → t( で済むが、訳文を文字列加工している箇所だけは t ではなく I18n.t へ移す必要があり
7
- (開発環境のマーカートークン混入バグ対策)、そこは 1 件ずつ確認する。対象は app 配下の .rb / .haml / .erb。
6
+ なる。大半は機械的に tt( → t( で済むが、訳文を文字列加工している箇所(→ I18n.t へ)と label 系ヘルパーの
7
+ 第一引数に渡している箇所(→ 引数構造を分離)だけは別扱いで、開発環境のマーカートークン残留バグを避けるため
8
+ 1 件ずつ確認する。対象は app 配下の .rb / .haml / .erb。
8
9
  disable-model-invocation: true
9
10
  license: MIT
10
11
  ---
@@ -36,13 +37,46 @@ middleware 自体が無いので再現しない=開発環境だけ壊れる)
36
37
  `t` にすると、`tt` がもともと潰していたバグをそのまま復活させてしまう。そこは middleware のラッパーを通らない
37
38
  **`I18n.t`(絶対キー)** へ移すのが正解で、機械的には決められないため 1 件ずつ確認する。
38
39
 
40
+ ## もう一つの罠: label の第一引数に渡す
41
+
42
+ 文字列加工していなくても危険な経路がもう一つある。`t(...)` の戻り値を **`label` 系ヘルパーの第一引数**
43
+ (form builder の `f.label` / `label_tag` / 素の `label`)に渡しているケース:
44
+
45
+ ```haml
46
+ = f.label t('activerecord.attributes.field.keywords'), class: 'form-label'
47
+ ```
48
+
49
+ `f.label` の**第一引数は「ラベルテキスト」ではなく method 名**(`for` 属性・`id`・ラベル文字列の元)として
50
+ 扱われる。そのため development では次の連鎖でマーカーが消せない位置に残る:
51
+
52
+ 1. `t(...)` が `⟦CT:activerecord.attributes.field.keywords⟧分類` を返す。
53
+ 2. `f.label` がこれを method 名と解釈し、**ラベルテキスト**と **`for` 属性**の 2 か所に展開する。
54
+ 3. ラベルテキスト側は Rails の `humanize` で**小文字化**され `⟦ct:…⟧` になる。
55
+ 4. Rewriter のマーカー検出プレフィックスは **大文字 `⟦CT:` 固定**(`lib/copy_tuner_client/copyray/marker.rb`
56
+ の `PREFIX`)。小文字化された `⟦ct:` は一致せず、除去されないまま画面に残る。
57
+
58
+ これも v1.x では `tt`(マーカー無し版)だったため表面化せず、**`tt → t` 一括置換で初めて顕在化する回帰**。
59
+
60
+ **重要: このケースは `I18n.t` 化では直らない。** マーカーを消しても、`t`/`I18n.t` の戻り値(訳文文字列)を
61
+ `label` の第一引数に渡す構造自体が `humanize` / `for` 属性の挙動として不適切だからだ。正しい修正は
62
+ **method 名を第一引数・表示テキストを第二引数に分離**すること:
63
+
64
+ ```haml
65
+ = f.label :keywords_cont, t('activerecord.attributes.field.keywords'), class: 'form-label'
66
+ ```
67
+
68
+ `for` 属性が変わるので、ラベルクリックでフィールドにフォーカスが当たることを実機で確認する。
69
+ スクリプトはこのパターンを suspicious のサブ種別 `label_arg` として抽出する(`label:` オプションに渡す
70
+ simple_form の `f.input :x, label: tt('k')` も同様に拾う)。
71
+
39
72
  ## 変換の 3 分類
40
73
 
41
- | 分類 | 例 | 扱い |
42
- |---|---|---|
43
- | **safe** | `tt('views.foo')` / `= tt '.title'` / `tt(key, default: x)` | `tt(` → `t(` に決定論的一括変換 |
44
- | **suspicious** | `truncate(tt('k'))` / `tt('k').length` / `tt('k')[0..n]` / `tt('k') =~ /re/` / `tt('k').gsub(...)` 等 | `I18n.t('絶対キー')` へ。**1 件ずつ確認**。スクリプトは触らない |
45
- | **other** | `def tt` / `alias tt`(定義側)/ app 外(`lib/` 等)/ `tt` を含む別識別子の誤検出 | 最後にまとめて提示。自動変換しない |
74
+ | 分類 | サブ種別 | 例 | 扱い |
75
+ |---|---|---|---|
76
+ | **safe** | — | `tt('views.foo')` / `= tt '.title'` / `tt(key, default: x)` / `f.label :method, tt('k')`(第二引数) | `tt(` → `t(` に決定論的一括変換 |
77
+ | **suspicious** | `string_manipulation` | `truncate(tt('k'))` / `tt('k').length` / `tt('k')[0..n]` / `tt('k') =~ /re/` / `tt('k').gsub(...)` 等 | `I18n.t('絶対キー')` へ。**1 件ずつ確認**。スクリプトは触らない |
78
+ | **suspicious** | `label_arg` | `= f.label tt('k')` / `label_tag tt('k')` / `f.input :x, label: tt('k')`(label 系の**第一引数 / label: オプション**) | **`f.label :method, t('k')` へ構造を直す**(method 名を第一引数・表示テキストを第二引数に)。**`I18n.t` 化では直らない**。1 件ずつ確認 |
79
+ | **other** | — | `def tt` / `alias tt`(定義側)/ app 外(`lib/` 等)/ `tt` を含む別識別子の誤検出 | 最後にまとめて提示。自動変換しない |
46
80
 
47
81
  **重要(定義側の罠):** アプリが v2.0.0 を待つ間の後方互換として `ApplicationHelper` に `def tt(key, **) = t(key, **)`
48
82
  のような **`tt` の定義**を生やしていることがある。これは「呼び出し」ではないので `t(` へ機械置換すると Rails の `t`
@@ -80,11 +114,21 @@ suspicious / other の行は**一切触らない**(行番号で限定してい
80
114
 
81
115
  ### 3. suspicious な箇所を 1 件ずつ確認
82
116
 
83
- ここが人間の判断が要る核心。手順 1 の suspicious 各件について、次を 1 件ずつ提示して確認を取る:
117
+ ここが人間の判断が要る核心。手順 1 の suspicious 各件について、次を 1 件ずつ提示して確認を取る。
118
+ **suspicious はサブ種別(`[label_arg]` / `[string_manipulation]`)で修正方法が異なる**ので、種別で分岐する:
84
119
 
120
+ **`[string_manipulation]`(戻り値を文字列加工している):**
85
121
  - 該当コード(`ファイル:行`)と、なぜ怪しいか(戻り値を文字列加工している=マーカー混入の危険)
86
122
  - 提案する置換: `t(...)` ではなく **`I18n.t('絶対キー')`**(`I18n` モジュール直呼びはラッパーを通らずマーカーが付かない)
87
123
 
124
+ **`[label_arg]`(label 系の第一引数 / label: オプションに渡している):**
125
+ - なぜ怪しいか(`humanize` で小文字化された `⟦ct:…⟧` が大文字 `⟦CT:` 固定の Rewriter をすり抜け残る。「もう一つの罠」参照)
126
+ - 提案する置換: **`I18n.t` 化ではなく引数構造を直す。** `= f.label t('views.foo.bar'), class: …` →
127
+ `= f.label :method_name, t('views.foo.bar'), class: …`。第一引数の method 名(`for` 属性に使うシンボル)は
128
+ ユーザに確認するか、対応する入力フィールド(`f.text_field :keywords_cont` 等)から推定する。
129
+ `label:` オプション(`f.input :x, label: tt('k')`)の場合は引数構造はそのままで `t('k')` でよいことが多いが、
130
+ そのフィールドのラベルが `humanize` を経るかは入力次第なので 1 件ずつ確認する。
131
+
88
132
  注意点:
89
133
  - **たとえユーザが「全部まとめて I18n.t にして」と言っても、suspicious は必ず 1 件ずつ提示する。** 相対キーを含む件は絶対キーをユーザと確認しないと置換できないためで、省略すると誤ったキーを書き込む危険がある。
90
134
  - **相対キー(先頭ドット `tt('.foo')`)は `I18n.t` では解決できない。** 絶対キー(`I18n.t('views.foo.bar')`)へ
@@ -94,6 +138,8 @@ suspicious / other の行は**一切触らない**(行番号で限定してい
94
138
  調べて基点キーを特定するか、ユーザに直接絶対キーを確認する。絶対キーが不明なときは
95
139
  `grep -r "キー末尾部分" config/locales/` でロケールファイルを検索して候補を絞り込む。
96
140
  - 本当に文字列加工していない(誤検出)なら、その場合は `t(...)` でよい。ユーザの判断に従う。
141
+ - **行をまたぐ変数経由(`txt = t('k')` → 別行で `f.label txt` や `truncate(txt)`)はスクリプトの行単位
142
+ スキャンでは拾えない**(構造的限界)。最終防波堤は手順 5 の「実画面に小文字マーカー `⟦ct:…⟧` が出ないか目視」。
97
143
 
98
144
  確認が取れた箇所だけ Edit で個別に置換する(スクリプトでは変換しない)。
99
145
 
@@ -118,6 +164,9 @@ git grep -nwI tt -- app # -I でバイナリ(画像等)の誤マッチを
118
164
  (safe は 0 件、`I18n.t` 化した suspicious も `tt` としては消える)。
119
165
  - 対象アプリで `bundle exec rspec`(または該当アプリのテスト)を回し、`NoMethodError` が出ないこと。
120
166
  - development で実画面を開き、文字列加工していた箇所にマーカートークン(`⟦CT:...⟧`)が混入していないこと。
167
+ - **label を含む画面で、小文字マーカー `⟦ct:...⟧`(小文字 ct)が残っていないこと。** Rewriter は大文字
168
+ `⟦CT:` しか除去しないため、`humanize` で小文字化された取りこぼしは**この目視が最終防波堤**になる
169
+ (label 第一引数の罠・行をまたぐ変数経由はここで初めて顕在化することがある)。
121
170
 
122
171
  ## スクリプトの責務(決定論的な範囲のみ)
123
172
 
@@ -81,6 +81,18 @@ STRING_METHOD_RE = /\btt\b\s*(?:\([^\n]*?\)|['":@][^\n,]*)\s*(?:\.\s*(?:#{STRING
81
81
  # 先頭ドットの相対キー tt('.foo') は I18n.t では解決できず絶対キー化が要る → 強調表示用。
82
82
  RELATIVE_KEY_RE = /\btt\b\s*(?:\(\s*)?['":]\s*\./
83
83
 
84
+ # label 系ヘルパーの第一引数 / label: オプションに tt(t) を渡すパターン。
85
+ # t 化すると戻り値(⟦CT:..⟧) が method 名扱いされ、humanize で小文字化された ⟦ct:..⟧ が
86
+ # Rewriter(大文字 ⟦CT: 固定)の除去網をすり抜け画面に残る。I18n.t 化では直らない。
87
+ # 正しい修正は method 名を第一引数・表示テキストを第二引数へ分離すること。
88
+ LABEL_FIRST_ARG_RE = /
89
+ (?: (?<![\w.])\w+\.label\b | \blabel_tag\b | (?<![\w.])label(?![\w]) )
90
+ \s*\(?\s*
91
+ tt\b (?=\s*[("':@])
92
+ /x
93
+ # simple_form 等の label: オプションに渡すケース(f.input :x, label: tt('k'))
94
+ LABEL_OPTION_RE = /\blabel:\s*tt\b/
95
+
84
96
  def relative(path)
85
97
  path.sub("#{ROOT}/", '')
86
98
  end
@@ -117,8 +129,19 @@ def classify_line(line, entry, in_app:)
117
129
  return [:other, entry]
118
130
  end
119
131
 
132
+ # label の第一引数 / label: オプションに渡すケースは文字列加工が無いので、safe 確定より前に拾う。
133
+ # 修正方法が文字列加工系(I18n.t 化)と異なるためサブ種別 :label_arg で区別する。
134
+ if line.match?(LABEL_FIRST_ARG_RE) || line.match?(LABEL_OPTION_RE)
135
+ entry[:kind] = :label_arg
136
+ entry[:hint] = 'label の引数に渡している。t 化すると humanize で小文字化された ⟦ct:..⟧ が ' \
137
+ 'Rewriter(大文字 ⟦CT: のみ除去)をすり抜け画面に残る。I18n.t 化では直らない。' \
138
+ 'method 名を第一引数・表示テキストを第二引数に分離: f.label :method, t(...)'
139
+ return [:suspicious, entry]
140
+ end
141
+
120
142
  return [:safe, entry] unless line.match?(STRING_HELPER_RE) || line.match?(STRING_METHOD_RE)
121
143
 
144
+ entry[:kind] = :string_manipulation
122
145
  entry[:relative_key] = line.match?(RELATIVE_KEY_RE)
123
146
  entry[:hint] = if entry[:relative_key]
124
147
  'I18n.t へ。相対キー(.foo)は絶対キーへ書き換えが必要'
@@ -147,10 +170,14 @@ end
147
170
  def print_section(title, entries)
148
171
  puts "\n== #{title} (#{entries.size}) =="
149
172
  entries.each do |e|
173
+ # hint があれば必ず kind も付く(classify_line で対で設定)ので素直に出す。
174
+ # suspicious 内のサブ種別(label_arg / string_manipulation)を可視化する。
150
175
  suffix = if e[:hint]
151
- " # #{e[:hint]}"
176
+ " # [#{e[:kind]}] #{e[:hint]}"
177
+ elsif e[:reason]
178
+ " # #{e[:reason]}"
152
179
  else
153
- (e[:reason] ? " # #{e[:reason]}" : '')
180
+ ''
154
181
  end
155
182
  puts "#{e[:file]}:#{e[:lineno]}: #{e[:code].strip}#{suffix}"
156
183
  end
@@ -202,6 +202,22 @@ describe CopyTunerClient::Copyray::Rewriter do
202
202
  end
203
203
  end
204
204
 
205
+ context 'fragment: true(turbo stream などの HTML 断片)' do
206
+ let(:html) { %(<turbo-stream action="replace" target="x"><template><p>#{marker('a.b')}Hello</p></template></turbo-stream>) }
207
+ subject(:result) { described_class.rewrite(html, fragment: true).first }
208
+
209
+ it 'html/body ラッパを足さず断片のまま返す' do
210
+ expect(result).not_to include('<html>')
211
+ expect(result).not_to include('<body>')
212
+ expect(result).to start_with('<turbo-stream')
213
+ end
214
+
215
+ it 'template 内の要素に data-copyray-key を付与しトークンを除去する' do
216
+ expect(result).to include('data-copyray-key="a.b"')
217
+ expect(result).not_to match CopyTunerClient::Copyray::Marker::SCAN_REGEXP
218
+ end
219
+ end
220
+
205
221
  context '出力にマーカートークンが一切残らない' do
206
222
  let(:html) do
207
223
  "<html><head><title>#{marker('t')}T</title></head>" \
@@ -41,6 +41,40 @@ describe CopyTunerClient::CopyrayMiddleware do
41
41
  end
42
42
  end
43
43
 
44
+ context 'turbo stream レスポンスのとき' do
45
+ let(:headers) { { 'Content-Type' => 'text/vnd.turbo-stream.html' } }
46
+ let(:body) { %(<turbo-stream action="replace" target="x"><template><p>#{marker('a.b')}Hello</p></template></turbo-stream>) }
47
+
48
+ before do
49
+ # NOTE: append_js のトップレベル no-op スタブを外し、turbo stream では JS を挿入しないことを検証する。
50
+ allow(middleware).to receive(:append_js).and_call_original
51
+ end
52
+
53
+ it 'マーカーを data-copyray-key 属性に書き換え、トークンを除去する' do
54
+ _status, _headers, response = middleware.call({})
55
+ result = response.join
56
+
57
+ expect(result).to include('data-copyray-key="a.b"')
58
+ expect(result).not_to match CopyTunerClient::Copyray::Marker::SCAN_REGEXP
59
+ end
60
+
61
+ it 'html/body ラッパを付けず turbo-stream 断片のまま返す' do
62
+ _status, _headers, response = middleware.call({})
63
+ result = response.join
64
+
65
+ expect(result).to start_with('<turbo-stream')
66
+ expect(result).not_to include('<body>')
67
+ end
68
+
69
+ it 'ブートストラップ JS を挿入しない(断片なので)' do
70
+ _status, _headers, response = middleware.call({})
71
+ result = response.join
72
+
73
+ expect(result).not_to include('window.CopyTuner')
74
+ expect(result).not_to include('copytuner')
75
+ end
76
+ end
77
+
44
78
  context 'HTML 以外のレスポンスのとき' do
45
79
  let(:headers) { { 'Content-Type' => 'application/json' } }
46
80
  let(:body) { "{\"x\":\"#{marker('a.b')}\"}" }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: copy_tuner_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - SonicGarden
@@ -182,7 +182,6 @@ executables: []
182
182
  extensions: []
183
183
  extra_rdoc_files: []
184
184
  files:
185
- - ".babelrc"
186
185
  - ".gitattributes"
187
186
  - ".github/dependabot.yml"
188
187
  - ".github/workflows/rspec.yml"
@@ -302,7 +301,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
302
301
  - !ruby/object:Gem::Version
303
302
  version: '0'
304
303
  requirements: []
305
- rubygems_version: 4.0.10
304
+ rubygems_version: 4.0.15
306
305
  specification_version: 4
307
306
  summary: Client for the CopyTuner copy management service
308
307
  test_files: []
data/.babelrc DELETED
@@ -1,18 +0,0 @@
1
- {
2
- "presets": [
3
- [
4
- "env",
5
- {
6
- "modules": false,
7
- "targets": {
8
- "browsers": "> 1%",
9
- "uglify": true,
10
- },
11
- "useBuiltIns": true,
12
- },
13
- ],
14
- ],
15
- "plugins": [
16
- "external-helpers"
17
- ]
18
- }