ansuko 1.3.13 → 2.0.0

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/README.ja.md CHANGED
@@ -92,14 +92,14 @@ ansukoは最小限のコア + プラグインアーキテクチャを採用し
92
92
  import _ from 'ansuko' // ~20KB
93
93
 
94
94
  // 必要に応じて日本語サポートを追加
95
- import jaPlugin from 'ansuko/plugins/ja'
96
- const extended = _.extend(jaPlugin) // +5KB
95
+ import 'ansuko/plugins/ja' // +5KB(side-effect import)
97
96
 
98
97
  // マッピングアプリ用にGIS機能を追加
99
- import geoPlugin from 'ansuko/plugins/geo'
100
- const full = extended.extend(geoPlugin) // +100KB
98
+ import 'ansuko/plugins/geo' // +100KB
101
99
  ```
102
100
 
101
+ > **v2 ノート**: プラグインは side-effect import で読み込む形式に変わりました。`import 'ansuko/plugins/<name>'` するだけで、`_` の実体と TypeScript の型 (declare module merging 経由) が同時に拡張されます。v1 で使われていた `_.extend(plugin)` API は v2 で削除されました — 後述の [v1 からの移行](#v1-からの移行) を参照。
102
+
103
103
  ## クイックスタート
104
104
 
105
105
  ### 基本的な使い方
@@ -140,39 +140,35 @@ const items = _.swallowMap([1, 2, 3], item => processItem(item), true) // エ
140
140
 
141
141
  ```typescript
142
142
  import _ from 'ansuko'
143
- import jaPlugin from 'ansuko/plugins/ja'
143
+ import 'ansuko/plugins/ja'
144
144
 
145
- const extended = _.extend(jaPlugin)
146
-
147
- extended.kanaToFull('ガギ') // 'ガギ'
148
- extended.kanaToHira('アイウ') // 'あいう'
149
- extended.toHalfWidth('ABCー123', '-') // 'ABC-123'
150
- extended.haifun('test‐data', '-') // 'test-data'
145
+ _.kanaToFull('ガギ') // 'ガギ'
146
+ _.kanaToHira('アイウ') // 'あいう'
147
+ _.toHalfWidth('ABCー123', '-') // 'ABC-123'
148
+ _.haifun('test‐data', '-') // 'test-data'
151
149
  ```
152
150
 
153
151
  #### Geoプラグイン
154
152
 
155
153
  ```typescript
156
154
  import _ from 'ansuko'
157
- import geoPlugin from 'ansuko/plugins/geo'
158
-
159
- const extended = _.extend(geoPlugin)
155
+ import 'ansuko/plugins/geo'
160
156
 
161
157
  // 様々な形式をGeoJSONに変換
162
- extended.toPointGeoJson([139.7671, 35.6812])
158
+ _.toPointGeoJson([139.7671, 35.6812])
163
159
  // => { type: 'Point', coordinates: [139.7671, 35.6812] }
164
160
 
165
- extended.toPointGeoJson({ lat: 35.6895, lng: 139.6917 })
161
+ _.toPointGeoJson({ lat: 35.6895, lng: 139.6917 })
166
162
  // => { type: 'Point', coordinates: [139.6917, 35.6895] }
167
163
 
168
164
  // 複数のポリゴンを結合
169
- const unified = extended.unionPolygon([polygon1, polygon2])
165
+ const unified = _.unionPolygon([polygon1, polygon2])
170
166
 
171
167
  // MapBoxユーティリティ
172
- extended.mZoomInterpolate({ 10: 1, 15: 5, 20: 10 })
168
+ _.mZoomInterpolate({ 10: 1, 15: 5, 20: 10 })
173
169
  // => ["interpolate", ["linear"], ["zoom"], 10, 1, 15, 5, 20, 10]
174
170
 
175
- extended.mProps({
171
+ _.mProps({
176
172
  fillColor: "#ff0000",
177
173
  sourceLayer: "buildings",
178
174
  visibility: true
@@ -183,32 +179,52 @@ extended.mProps({
183
179
  #### Prototypeプラグイン
184
180
 
185
181
  ```typescript
186
- import _ from 'ansuko'
187
- import prototypePlugin from 'ansuko/plugins/prototype'
188
-
189
- _.extend(prototypePlugin)
182
+ import 'ansuko/plugins/prototype'
190
183
 
191
184
  // Array.prototypeが拡張される
192
185
  [1, 2, 3].notMap(n => n > 1) // [true, false, false]
193
186
  [1, 2, 3].notFilter(n => n % 2) // [2](偶数)
194
187
  ```
195
188
 
196
- ### プラグインのチェーン
189
+ ### 複数プラグインの併用
197
190
 
198
191
  ```typescript
199
192
  import _ from 'ansuko'
200
- import jaPlugin from 'ansuko/plugins/ja'
201
- import geoPlugin from 'ansuko/plugins/geo'
193
+ import 'ansuko/plugins/ja'
194
+ import 'ansuko/plugins/geo'
195
+
196
+ // 日本語とGeoユーティリティの両方が `_` で使える
197
+ _.kanaToHira('アイウ')
198
+ _.toPointGeoJson([139.7, 35.6])
199
+ ```
202
200
 
203
- const extended = _
204
- .extend(jaPlugin)
205
- .extend(geoPlugin)
201
+ 各プラグインは複数ファイルから import されても登録は1回のみです(重複登録ガードを内蔵)。
206
202
 
207
- // 日本語とGeoユーティリティの両方が使える!
208
- extended.kanaToHira('アイウ')
209
- extended.toPointGeoJson([139.7, 35.6])
203
+ ## v1 からの移行
204
+
205
+ v2 では `_.extend(plugin)` を廃止し、side-effect import に統一しました。移行は機械的です:
206
+
207
+ ```typescript
208
+ // v1
209
+ import _ from 'ansuko'
210
+ import jaPlugin from 'ansuko/plugins/ja'
211
+ const ansuko = _.extend(jaPlugin)
212
+ ansuko.kanaToFull('ガ')
213
+
214
+ // v2
215
+ import _ from 'ansuko'
216
+ import 'ansuko/plugins/ja'
217
+ _.kanaToFull('ガ')
210
218
  ```
211
219
 
220
+ 変更の理由:
221
+
222
+ - **TypeScript のサジェストが本当に効くようになりました。** v1 の `_.extend()` は新しい型を返していましたが、元の `_` 自体の型は変わらないため IDE 上で `_.` を打ってもプラグインの関数が候補に出てきませんでした。v2 は `declare module` merging で `_` 自体を型レベルで拡張します。
223
+ - **Tree-shaking が正直になります。** プラグインを import しなければバンドルに含まれません。
224
+ - **lodash 型を330行手書きしていた問題を解消。** `AnsukoType` は `Omit<LoDashStatic, ...>` を継承するようになり、lodash 本来のジェネリクスもそのまま使えます。
225
+
226
+ v1 で `_.extend(a).extend(b)` のように chain していた場合は、2回の side-effect import に置き換えてください。
227
+
212
228
  ## 主な機能
213
229
 
214
230
  ### 拡張されたlodash関数
package/README.md CHANGED
@@ -171,14 +171,14 @@ This means you only pay for what you use!
171
171
  import _ from 'ansuko' // ~20KB
172
172
 
173
173
  // Add Japanese support when needed
174
- import jaPlugin from 'ansuko/plugins/ja'
175
- _.extend(jaPlugin) // +5KB
174
+ import 'ansuko/plugins/ja' // +5KB (side-effect import)
176
175
 
177
176
  // Add GIS features for mapping apps
178
- import geoPlugin from 'ansuko/plugins/geo'
179
- _.extend(geoPlugin) // +100KB
177
+ import 'ansuko/plugins/geo' // +100KB
180
178
  ```
181
179
 
180
+ > **v2 Note**: Plugins are now loaded as side-effect imports. Just `import 'ansuko/plugins/<name>'` once and `_` is automatically augmented in both runtime and type system (via TypeScript's `declare module` merging). The legacy `_.extend(plugin)` API has been removed in v2 — see [Migration from v1](#migration-from-v1) below.
181
+
182
182
  ## Quick Start
183
183
 
184
184
  ### Basic Usage
@@ -219,9 +219,7 @@ const items = _.swallowMap([1, 2, 3], item => processItem(item), true) // filte
219
219
 
220
220
  ```typescript
221
221
  import _ from 'ansuko'
222
- import jaPlugin from 'ansuko/plugins/ja'
223
-
224
- _.extend(jaPlugin)
222
+ import 'ansuko/plugins/ja'
225
223
 
226
224
  _.kanaToFull('ガギ') // 'ガギ'
227
225
  _.kanaToHira('アイウ') // 'あいう'
@@ -233,25 +231,23 @@ _.haifun('test‐data', '-') // 'test-data'
233
231
 
234
232
  ```typescript
235
233
  import _ from 'ansuko'
236
- import geoPlugin from 'ansuko/plugins/geo'
237
-
238
- const extended = _.extend(geoPlugin)
234
+ import 'ansuko/plugins/geo'
239
235
 
240
236
  // Convert various formats to GeoJSON
241
- extended.toPointGeoJson([139.7671, 35.6812])
237
+ _.toPointGeoJson([139.7671, 35.6812])
242
238
  // => { type: 'Point', coordinates: [139.7671, 35.6812] }
243
239
 
244
- extended.toPointGeoJson({ lat: 35.6895, lng: 139.6917 })
240
+ _.toPointGeoJson({ lat: 35.6895, lng: 139.6917 })
245
241
  // => { type: 'Point', coordinates: [139.6917, 35.6895] }
246
242
 
247
243
  // Union multiple polygons
248
- const unified = extended.unionPolygon([polygon1, polygon2])
244
+ const unified = _.unionPolygon([polygon1, polygon2])
249
245
 
250
246
  // MapBox utilities
251
- extended.mZoomInterpolate({ 10: 1, 15: 5, 20: 10 })
247
+ _.mZoomInterpolate({ 10: 1, 15: 5, 20: 10 })
252
248
  // => ["interpolate", ["linear"], ["zoom"], 10, 1, 15, 5, 20, 10]
253
249
 
254
- extended.mProps({
250
+ _.mProps({
255
251
  fillColor: "#ff0000",
256
252
  sourceLayer: "buildings",
257
253
  visibility: true
@@ -262,32 +258,52 @@ extended.mProps({
262
258
  #### Prototype Plugin
263
259
 
264
260
  ```typescript
265
- import _ from 'ansuko'
266
- import prototypePlugin from 'ansuko/plugins/prototype'
267
-
268
- _.extend(prototypePlugin)
261
+ import 'ansuko/plugins/prototype'
269
262
 
270
263
  // Now Array.prototype is extended
271
264
  [1, 2, 3].notMap(n => n > 1) // [true, false, false]
272
265
  [1, 2, 3].notFilter(n => n % 2) // [2] (even numbers)
273
266
  ```
274
267
 
275
- ### Chaining Plugins
268
+ ### Combining Plugins
276
269
 
277
270
  ```typescript
278
271
  import _ from 'ansuko'
279
- import jaPlugin from 'ansuko/plugins/ja'
280
- import geoPlugin from 'ansuko/plugins/geo'
272
+ import 'ansuko/plugins/ja'
273
+ import 'ansuko/plugins/geo'
274
+
275
+ // Now you have both Japanese and Geo utilities on `_`
276
+ _.kanaToHira('アイウ')
277
+ _.toPointGeoJson([139.7, 35.6])
278
+ ```
281
279
 
282
- const extended = _
283
- .extend(jaPlugin)
284
- .extend(geoPlugin)
280
+ Each plugin registers itself exactly once, even if imported from multiple files (a duplicate-registration guard is built in).
285
281
 
286
- // Now you have both Japanese and Geo utilities!
287
- extended.kanaToHira('アイウ')
288
- extended.toPointGeoJson([139.7, 35.6])
282
+ ## Migration from v1
283
+
284
+ v2 removes `_.extend(plugin)` in favor of side-effect imports. The migration is mechanical:
285
+
286
+ ```typescript
287
+ // v1
288
+ import _ from 'ansuko'
289
+ import jaPlugin from 'ansuko/plugins/ja'
290
+ const ansuko = _.extend(jaPlugin)
291
+ ansuko.kanaToFull('ガ')
292
+
293
+ // v2
294
+ import _ from 'ansuko'
295
+ import 'ansuko/plugins/ja'
296
+ _.kanaToFull('ガ')
289
297
  ```
290
298
 
299
+ Why this change:
300
+
301
+ - **TypeScript autocompletion now actually works.** v1's `_.extend()` returned a new type, but the original `_` reference's type stayed the same — so IDE suggestions never appeared on `_`. v2 uses TypeScript `declare module` merging so `_` itself is augmented at the type level.
302
+ - **Tree-shaking is honest.** Don't import a plugin = its code is not bundled.
303
+ - **No more 330-line manual lodash type list.** `AnsukoType` now extends `Omit<LoDashStatic, ...>`, so lodash's own types are reused (with proper generics).
304
+
305
+ If you previously did chained `_.extend(a).extend(b)`, replace it with two side-effect imports.
306
+
291
307
  ## Documentation
292
308
 
293
309
  For detailed information, see:
package/README.zh.md CHANGED
@@ -166,14 +166,14 @@ ansuko使用最小核心 + 插件架构来保持你的包大小小:
166
166
  import _ from 'ansuko' // ~20KB
167
167
 
168
168
  // 按需加入日文支持
169
- import jaPlugin from 'ansuko/plugins/ja'
170
- const extended = _.extend(jaPlugin) // +5KB
169
+ import 'ansuko/plugins/ja' // +5KB(副作用引入)
171
170
 
172
171
  // 地图类应用再挂载 GIS
173
- import geoPlugin from 'ansuko/plugins/geo'
174
- const full = extended.extend(geoPlugin) // +100KB
172
+ import 'ansuko/plugins/geo' // +100KB
175
173
  ```
176
174
 
175
+ > **v2 提示**:插件改为副作用引入。只需 `import 'ansuko/plugins/<name>'` 一次,`_` 在运行时和 TypeScript 类型层面(通过 `declare module` 合并)都会被自动扩展。v1 的 `_.extend(plugin)` API 已在 v2 中移除 —— 详见下方的[从 v1 迁移](#从-v1-迁移)。
176
+
177
177
  ## 快速开始
178
178
 
179
179
  ### 基本用法
@@ -214,9 +214,7 @@ const items = _.swallowMap([1, 2, 3], item => processItem(item), true) // 过
214
214
 
215
215
  ```typescript
216
216
  import _ from 'ansuko'
217
- import jaPlugin from 'ansuko/plugins/ja'
218
-
219
- _.extend(jaPlugin)
217
+ import 'ansuko/plugins/ja'
220
218
 
221
219
  _.kanaToFull('ガギ') // 'ガギ'
222
220
  _.kanaToHira('アイウ') // 'あいう'
@@ -228,25 +226,23 @@ _.haifun('test‐data', '-') // 'test-data'
228
226
 
229
227
  ```typescript
230
228
  import _ from 'ansuko'
231
- import geoPlugin from 'ansuko/plugins/geo'
232
-
233
- const extended = _.extend(geoPlugin)
229
+ import 'ansuko/plugins/geo'
234
230
 
235
231
  // 将各种格式转换为 GeoJSON
236
- extended.toPointGeoJson([139.7671, 35.6812])
232
+ _.toPointGeoJson([139.7671, 35.6812])
237
233
  // => { type: 'Point', coordinates: [139.7671, 35.6812] }
238
234
 
239
- extended.toPointGeoJson({ lat: 35.6895, lng: 139.6917 })
235
+ _.toPointGeoJson({ lat: 35.6895, lng: 139.6917 })
240
236
  // => { type: 'Point', coordinates: [139.6917, 35.6895] }
241
237
 
242
238
  // 合并多个多边形
243
- const unified = extended.unionPolygon([polygon1, polygon2])
239
+ const unified = _.unionPolygon([polygon1, polygon2])
244
240
 
245
241
  // MapBox 工具
246
- extended.mZoomInterpolate({ 10: 1, 15: 5, 20: 10 })
242
+ _.mZoomInterpolate({ 10: 1, 15: 5, 20: 10 })
247
243
  // => ["interpolate", ["linear"], ["zoom"], 10, 1, 15, 5, 20, 10]
248
244
 
249
- extended.mProps({
245
+ _.mProps({
250
246
  fillColor: "#ff0000",
251
247
  sourceLayer: "buildings",
252
248
  visibility: true
@@ -257,32 +253,52 @@ extended.mProps({
257
253
  #### 原型插件
258
254
 
259
255
  ```typescript
260
- import _ from 'ansuko'
261
- import prototypePlugin from 'ansuko/plugins/prototype'
262
-
263
- _.extend(prototypePlugin)
256
+ import 'ansuko/plugins/prototype'
264
257
 
265
258
  // 现在 Array.prototype 已扩展
266
259
  [1, 2, 3].notMap(n => n > 1) // [true, false, false]
267
260
  [1, 2, 3].notFilter(n => n % 2) // [2](偶数)
268
261
  ```
269
262
 
270
- ### 链式插件
263
+ ### 同时使用多个插件
271
264
 
272
265
  ```typescript
273
266
  import _ from 'ansuko'
274
- import jaPlugin from 'ansuko/plugins/ja'
275
- import geoPlugin from 'ansuko/plugins/geo'
267
+ import 'ansuko/plugins/ja'
268
+ import 'ansuko/plugins/geo'
269
+
270
+ // 现在 `_` 上同时拥有日文和地理工具
271
+ _.kanaToHira('アイウ')
272
+ _.toPointGeoJson([139.7, 35.6])
273
+ ```
276
274
 
277
- const extended = _
278
- .extend(jaPlugin)
279
- .extend(geoPlugin)
275
+ 每个插件即使被多个文件 import,也只会注册一次(内置了重复注册防护)。
280
276
 
281
- // 现在你同时拥有日文和地理工具!
282
- extended.kanaToHira('アイウ')
283
- extended.toPointGeoJson([139.7, 35.6])
277
+ ## 从 v1 迁移
278
+
279
+ v2 移除了 `_.extend(plugin)`,改为副作用引入。迁移非常机械:
280
+
281
+ ```typescript
282
+ // v1
283
+ import _ from 'ansuko'
284
+ import jaPlugin from 'ansuko/plugins/ja'
285
+ const ansuko = _.extend(jaPlugin)
286
+ ansuko.kanaToFull('ガ')
287
+
288
+ // v2
289
+ import _ from 'ansuko'
290
+ import 'ansuko/plugins/ja'
291
+ _.kanaToFull('ガ')
284
292
  ```
285
293
 
294
+ 变更原因:
295
+
296
+ - **TypeScript 自动补全终于真正起作用了。** v1 的 `_.extend()` 会返回新类型,但原 `_` 引用的类型不变 —— 因此在 IDE 里 `_.` 永远不会出现插件的方法提示。v2 通过 TypeScript `declare module` 合并直接扩展 `_` 自身的类型。
297
+ - **Tree-shaking 真实可靠。** 不 import 的插件不会被打包。
298
+ - **告别 330 行手写 lodash 类型列表。** `AnsukoType` 现在继承 `Omit<LoDashStatic, ...>`,lodash 自身的泛型类型也得以保留。
299
+
300
+ 如果你之前使用 `_.extend(a).extend(b)` 的链式写法,请改为两次副作用引入。
301
+
286
302
  ## 文档
287
303
 
288
304
  更多详细信息,请参阅:
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import _ from "lodash";
1
+ import lodash, { type LoDashStatic } from "lodash";
2
2
  /**
3
3
  * Checks if the value is a non-empty string. null/undefined/empty string -> false.
4
4
  * @param str - Value to check
@@ -209,21 +209,20 @@ declare const swallowMap: <T, U>(array: T[] | undefined | null, fn: (item: T, in
209
209
  * @category Array Utilities
210
210
  */
211
211
  declare const arrayDepth: (ary: unknown) => number;
212
- /**
213
- * Extends ansuko with a plugin and returns the augmented instance.
214
- * @param plugin - Plugin function
215
- * @returns Extended instance
216
- * @example const extended = _.extend(jaPlugin)
217
- * @category Core Functions
218
- */
219
- declare const extend: <T extends AnsukoType, E>(this: T, plugin: (a: T) => T & E) => T & E;
220
212
  export type ChangesOptions = {
221
213
  keyExcludes?: boolean;
222
214
  };
223
215
  type ChangesAfterCallback<T> = (value: T) => any | Promise<any>;
224
216
  type ChangesAfterFinallyCallback<T> = (value: T, res: any) => any | Promise<any>;
225
- export interface AnsukoType {
226
- extend: typeof extend;
217
+ type AnsukoOverriddenKeys = 'isEmpty' | 'toNumber' | 'castArray' | 'extend';
218
+ /**
219
+ * ansuko 本体の型。lodash の全関数 (上書き対象を除く) をそのまま継承し、
220
+ * ansuko 独自関数を追加した形になる。
221
+ *
222
+ * プラグインを読み込むと、各プラグインの d.ts に書かれた declaration merging により
223
+ * このインターフェースが自動的に拡張される。
224
+ */
225
+ export interface AnsukoType extends Omit<LoDashStatic, AnsukoOverriddenKeys> {
227
226
  isValidStr: typeof isValidStr;
228
227
  valueOr: typeof valueOr;
229
228
  emptyOr: typeof emptyOr;
@@ -242,311 +241,17 @@ export interface AnsukoType {
242
241
  isEmpty: typeof isEmpty;
243
242
  toNumber: typeof toNumber;
244
243
  castArray: typeof castArray;
245
- isEmptyOrg: typeof _.isEmpty;
246
- toNumberOrg: typeof _.toNumber;
247
- castArrayOrg: typeof _.castArray;
248
- add: typeof _.add;
249
- after: typeof _.after;
250
- ary: typeof _.ary;
251
- assign: typeof _.assign;
252
- assignIn: typeof _.assignIn;
253
- assignInWith: typeof _.assignInWith;
254
- assignWith: typeof _.assignWith;
255
- at: typeof _.at;
256
- attempt: typeof _.attempt;
257
- before: typeof _.before;
258
- bind: typeof _.bind;
259
- bindAll: typeof _.bindAll;
260
- bindKey: typeof _.bindKey;
261
- camelCase: typeof _.camelCase;
262
- capitalize: typeof _.capitalize;
263
- ceil: typeof _.ceil;
264
- chain: typeof _.chain;
265
- chunk: typeof _.chunk;
266
- clamp: typeof _.clamp;
267
- clone: typeof _.clone;
268
- cloneDeep: typeof _.cloneDeep;
269
- cloneDeepWith: typeof _.cloneDeepWith;
270
- cloneWith: typeof _.cloneWith;
271
- compact: typeof _.compact;
272
- concat: typeof _.concat;
273
- cond: typeof _.cond;
274
- conforms: typeof _.conforms;
275
- conformsTo: typeof _.conformsTo;
276
- constant: typeof _.constant;
277
- countBy: typeof _.countBy;
278
- create: typeof _.create;
279
- curry: typeof _.curry;
280
- curryRight: typeof _.curryRight;
281
- debounce: typeof _.debounce;
282
- deburr: typeof _.deburr;
283
- defaultTo: typeof _.defaultTo;
284
- defaults: typeof _.defaults;
285
- defaultsDeep: typeof _.defaultsDeep;
286
- defer: typeof _.defer;
287
- delay: typeof _.delay;
288
- difference: typeof _.difference;
289
- differenceBy: typeof _.differenceBy;
290
- differenceWith: typeof _.differenceWith;
291
- divide: typeof _.divide;
292
- drop: typeof _.drop;
293
- dropRight: typeof _.dropRight;
294
- dropRightWhile: typeof _.dropRightWhile;
295
- dropWhile: typeof _.dropWhile;
296
- each: typeof _.each;
297
- eachRight: typeof _.eachRight;
298
- endsWith: typeof _.endsWith;
299
- entries: typeof _.entries;
300
- entriesIn: typeof _.entriesIn;
301
- eq: typeof _.eq;
302
- escape: typeof _.escape;
303
- escapeRegExp: typeof _.escapeRegExp;
304
- every: typeof _.every;
305
- extendWith: typeof _.extendWith;
306
- fill: typeof _.fill;
307
- filter: typeof _.filter;
308
- find: typeof _.find;
309
- findIndex: typeof _.findIndex;
310
- findKey: typeof _.findKey;
311
- findLast: typeof _.findLast;
312
- findLastIndex: typeof _.findLastIndex;
313
- findLastKey: typeof _.findLastKey;
314
- first: typeof _.first;
315
- flatMap: typeof _.flatMap;
316
- flatMapDeep: typeof _.flatMapDeep;
317
- flatMapDepth: typeof _.flatMapDepth;
318
- flatten: typeof _.flatten;
319
- flattenDeep: typeof _.flattenDeep;
320
- flattenDepth: typeof _.flattenDepth;
321
- flip: typeof _.flip;
322
- floor: typeof _.floor;
323
- flow: typeof _.flow;
324
- flowRight: typeof _.flowRight;
325
- forEach: typeof _.forEach;
326
- forEachRight: typeof _.forEachRight;
327
- forIn: typeof _.forIn;
328
- forInRight: typeof _.forInRight;
329
- forOwn: typeof _.forOwn;
330
- forOwnRight: typeof _.forOwnRight;
331
- fromPairs: typeof _.fromPairs;
332
- functions: typeof _.functions;
333
- functionsIn: typeof _.functionsIn;
334
- get: typeof _.get;
335
- groupBy: typeof _.groupBy;
336
- gt: typeof _.gt;
337
- gte: typeof _.gte;
338
- has: typeof _.has;
339
- hasIn: typeof _.hasIn;
340
- head: typeof _.head;
341
- identity: typeof _.identity;
342
- inRange: typeof _.inRange;
343
- includes: typeof _.includes;
344
- indexOf: typeof _.indexOf;
345
- initial: typeof _.initial;
346
- intersection: typeof _.intersection;
347
- intersectionBy: typeof _.intersectionBy;
348
- intersectionWith: typeof _.intersectionWith;
349
- invert: typeof _.invert;
350
- invertBy: typeof _.invertBy;
351
- invoke: typeof _.invoke;
352
- invokeMap: typeof _.invokeMap;
353
- isArguments: typeof _.isArguments;
354
- isArray: typeof _.isArray;
355
- isArrayBuffer: typeof _.isArrayBuffer;
356
- isArrayLike: typeof _.isArrayLike;
357
- isArrayLikeObject: typeof _.isArrayLikeObject;
358
- isBoolean: typeof _.isBoolean;
359
- isBuffer: typeof _.isBuffer;
360
- isDate: typeof _.isDate;
361
- isElement: typeof _.isElement;
362
- isEqual: typeof _.isEqual;
363
- isEqualWith: typeof _.isEqualWith;
364
- isError: typeof _.isError;
365
- isFinite: typeof _.isFinite;
366
- isFunction: typeof _.isFunction;
367
- isInteger: typeof _.isInteger;
368
- isLength: typeof _.isLength;
369
- isMap: typeof _.isMap;
370
- isMatch: typeof _.isMatch;
371
- isMatchWith: typeof _.isMatchWith;
372
- isNaN: typeof _.isNaN;
373
- isNative: typeof _.isNative;
374
- isNil: typeof _.isNil;
375
- isNull: typeof _.isNull;
376
- isNumber: typeof _.isNumber;
377
- isObject: typeof _.isObject;
378
- isObjectLike: typeof _.isObjectLike;
379
- isPlainObject: typeof _.isPlainObject;
380
- isRegExp: typeof _.isRegExp;
381
- isSafeInteger: typeof _.isSafeInteger;
382
- isSet: typeof _.isSet;
383
- isString: typeof _.isString;
384
- isSymbol: typeof _.isSymbol;
385
- isTypedArray: typeof _.isTypedArray;
386
- isUndefined: typeof _.isUndefined;
387
- isWeakMap: typeof _.isWeakMap;
388
- isWeakSet: typeof _.isWeakSet;
389
- iteratee: typeof _.iteratee;
390
- join: typeof _.join;
391
- kebabCase: typeof _.kebabCase;
392
- keyBy: typeof _.keyBy;
393
- keys: typeof _.keys;
394
- keysIn: typeof _.keysIn;
395
- last: typeof _.last;
396
- lastIndexOf: typeof _.lastIndexOf;
397
- lowerCase: typeof _.lowerCase;
398
- lowerFirst: typeof _.lowerFirst;
399
- lt: typeof _.lt;
400
- lte: typeof _.lte;
401
- map: typeof _.map;
402
- mapKeys: typeof _.mapKeys;
403
- mapValues: typeof _.mapValues;
404
- matches: typeof _.matches;
405
- matchesProperty: typeof _.matchesProperty;
406
- max: typeof _.max;
407
- maxBy: typeof _.maxBy;
408
- mean: typeof _.mean;
409
- meanBy: typeof _.meanBy;
410
- memoize: typeof _.memoize;
411
- merge: typeof _.merge;
412
- mergeWith: typeof _.mergeWith;
413
- method: typeof _.method;
414
- methodOf: typeof _.methodOf;
415
- min: typeof _.min;
416
- minBy: typeof _.minBy;
417
- mixin: typeof _.mixin;
418
- multiply: typeof _.multiply;
419
- negate: typeof _.negate;
420
- noConflict: typeof _.noConflict;
421
- noop: typeof _.noop;
422
- now: typeof _.now;
423
- nth: typeof _.nth;
424
- nthArg: typeof _.nthArg;
425
- omit: typeof _.omit;
426
- omitBy: typeof _.omitBy;
427
- once: typeof _.once;
428
- orderBy: typeof _.orderBy;
429
- over: typeof _.over;
430
- overArgs: typeof _.overArgs;
431
- overEvery: typeof _.overEvery;
432
- overSome: typeof _.overSome;
433
- pad: typeof _.pad;
434
- padEnd: typeof _.padEnd;
435
- padStart: typeof _.padStart;
436
- parseInt: typeof _.parseInt;
437
- partial: typeof _.partial;
438
- partialRight: typeof _.partialRight;
439
- partition: typeof _.partition;
440
- pick: typeof _.pick;
441
- pickBy: typeof _.pickBy;
442
- property: typeof _.property;
443
- propertyOf: typeof _.propertyOf;
444
- pull: typeof _.pull;
445
- pullAll: typeof _.pullAll;
446
- pullAllBy: typeof _.pullAllBy;
447
- pullAllWith: typeof _.pullAllWith;
448
- pullAt: typeof _.pullAt;
449
- random: typeof _.random;
450
- range: typeof _.range;
451
- rangeRight: typeof _.rangeRight;
452
- rearg: typeof _.rearg;
453
- reduce: typeof _.reduce;
454
- reduceRight: typeof _.reduceRight;
455
- reject: typeof _.reject;
456
- remove: typeof _.remove;
457
- repeat: typeof _.repeat;
458
- replace: typeof _.replace;
459
- rest: typeof _.rest;
460
- result: typeof _.result;
461
- reverse: typeof _.reverse;
462
- round: typeof _.round;
463
- runInContext: typeof _.runInContext;
464
- sample: typeof _.sample;
465
- sampleSize: typeof _.sampleSize;
466
- set: typeof _.set;
467
- setWith: typeof _.setWith;
468
- shuffle: typeof _.shuffle;
469
- size: typeof _.size;
470
- slice: typeof _.slice;
471
- snakeCase: typeof _.snakeCase;
472
- some: typeof _.some;
473
- sortBy: typeof _.sortBy;
474
- sortedIndex: typeof _.sortedIndex;
475
- sortedIndexBy: typeof _.sortedIndexBy;
476
- sortedIndexOf: typeof _.sortedIndexOf;
477
- sortedLastIndex: typeof _.sortedLastIndex;
478
- sortedLastIndexBy: typeof _.sortedLastIndexBy;
479
- sortedLastIndexOf: typeof _.sortedLastIndexOf;
480
- sortedUniq: typeof _.sortedUniq;
481
- sortedUniqBy: typeof _.sortedUniqBy;
482
- split: typeof _.split;
483
- spread: typeof _.spread;
484
- startCase: typeof _.startCase;
485
- startsWith: typeof _.startsWith;
486
- stubArray: typeof _.stubArray;
487
- stubFalse: typeof _.stubFalse;
488
- stubObject: typeof _.stubObject;
489
- stubString: typeof _.stubString;
490
- stubTrue: typeof _.stubTrue;
491
- subtract: typeof _.subtract;
492
- sum: typeof _.sum;
493
- sumBy: typeof _.sumBy;
494
- tail: typeof _.tail;
495
- take: typeof _.take;
496
- takeRight: typeof _.takeRight;
497
- takeRightWhile: typeof _.takeRightWhile;
498
- takeWhile: typeof _.takeWhile;
499
- tap: typeof _.tap;
500
- template: typeof _.template;
501
- throttle: typeof _.throttle;
502
- thru: typeof _.thru;
503
- times: typeof _.times;
504
- toArray: typeof _.toArray;
505
- toFinite: typeof _.toFinite;
506
- toInteger: typeof _.toInteger;
507
- toLength: typeof _.toLength;
508
- toLower: typeof _.toLower;
509
- toPairs: typeof _.toPairs;
510
- toPairsIn: typeof _.toPairsIn;
511
- toPath: typeof _.toPath;
512
- toPlainObject: typeof _.toPlainObject;
513
- toSafeInteger: typeof _.toSafeInteger;
514
- toString: typeof _.toString;
515
- toUpper: typeof _.toUpper;
516
- transform: typeof _.transform;
517
- trim: typeof _.trim;
518
- trimEnd: typeof _.trimEnd;
519
- trimStart: typeof _.trimStart;
520
- truncate: typeof _.truncate;
521
- unary: typeof _.unary;
522
- unescape: typeof _.unescape;
523
- union: typeof _.union;
524
- unionBy: typeof _.unionBy;
525
- unionWith: typeof _.unionWith;
526
- uniq: typeof _.uniq;
527
- uniqBy: typeof _.uniqBy;
528
- uniqWith: typeof _.uniqWith;
529
- uniqueId: typeof _.uniqueId;
530
- unset: typeof _.unset;
531
- unzip: typeof _.unzip;
532
- unzipWith: typeof _.unzipWith;
533
- update: typeof _.update;
534
- updateWith: typeof _.updateWith;
535
- upperCase: typeof _.upperCase;
536
- upperFirst: typeof _.upperFirst;
537
- values: typeof _.values;
538
- valuesIn: typeof _.valuesIn;
539
- without: typeof _.without;
540
- words: typeof _.words;
541
- wrap: typeof _.wrap;
542
- xor: typeof _.xor;
543
- xorBy: typeof _.xorBy;
544
- xorWith: typeof _.xorWith;
545
- zip: typeof _.zip;
546
- zipObject: typeof _.zipObject;
547
- zipObjectDeep: typeof _.zipObjectDeep;
548
- zipWith: typeof _.zipWith;
244
+ isEmptyOrg: typeof lodash.isEmpty;
245
+ toNumberOrg: typeof lodash.toNumber;
246
+ castArrayOrg: typeof lodash.castArray;
247
+ /**
248
+ * 登録済みプラグイン名のレジストリ。
249
+ * プラグインの side-effect import 時に重複登録を防ぐために使用される。
250
+ * 通常コードから直接触らないこと。
251
+ * @internal
252
+ */
253
+ __plugins: Set<string>;
549
254
  }
550
- declare const _default: AnsukoType;
551
- export default _default;
255
+ declare const _: AnsukoType;
256
+ export default _;
552
257
  export { isEmpty, toNumber, boolIf, isValidStr, valueOr, equalsOr, waited, parseJSON, jsonStringify, castArray, changes, strWrap, swallow, swallowMap, arrayDepth, };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import _ from "lodash";
1
+ import lodash from "lodash";
2
2
  import JSON5 from "json5";
3
3
  import { toHalfWidth } from "./util.js";
4
4
  /**
@@ -10,10 +10,10 @@ import { toHalfWidth } from "./util.js";
10
10
  * @category Type Guards
11
11
  */
12
12
  const isValidStr = (str) => {
13
- if (_.isNil(str)) {
13
+ if (lodash.isNil(str)) {
14
14
  return false;
15
15
  }
16
- if (_.isEmpty(str)) {
16
+ if (lodash.isEmpty(str)) {
17
17
  return false;
18
18
  }
19
19
  return typeof str === "string";
@@ -26,7 +26,7 @@ const valueOr = (value, els) => {
26
26
  // Promiseかチェック
27
27
  if (resolvedValue instanceof Promise) {
28
28
  return Promise.resolve(resolvedValue).then(res => {
29
- if (_.isNil(res) || isEmpty(res)) {
29
+ if (lodash.isNil(res) || isEmpty(res)) {
30
30
  if (typeof els === "function") {
31
31
  return els();
32
32
  }
@@ -35,7 +35,7 @@ const valueOr = (value, els) => {
35
35
  return res;
36
36
  });
37
37
  }
38
- if (!_.isNil(resolvedValue) && !isEmpty(resolvedValue)) {
38
+ if (!lodash.isNil(resolvedValue) && !isEmpty(resolvedValue)) {
39
39
  return resolvedValue;
40
40
  }
41
41
  if (typeof els === "function") {
@@ -51,7 +51,7 @@ const emptyOr = (value, els) => {
51
51
  // Promiseかチェック
52
52
  if (resolvedValue instanceof Promise) {
53
53
  return Promise.resolve(resolvedValue).then(res => {
54
- if (_.isNil(res) || isEmpty(res)) {
54
+ if (lodash.isNil(res) || isEmpty(res)) {
55
55
  return null;
56
56
  }
57
57
  if (typeof els === "function") {
@@ -60,7 +60,7 @@ const emptyOr = (value, els) => {
60
60
  return els;
61
61
  });
62
62
  }
63
- if (_.isNil(resolvedValue) || isEmpty(resolvedValue)) {
63
+ if (lodash.isNil(resolvedValue) || isEmpty(resolvedValue)) {
64
64
  return null;
65
65
  }
66
66
  if (typeof els === "function") {
@@ -87,9 +87,9 @@ const hasOr = (value, paths, els) => {
87
87
  const pathArray = Array.isArray(paths) ? paths : [paths];
88
88
  // パスが全て存在するかチェック
89
89
  const checkPaths = (val) => {
90
- if (_.isNil(val) || isEmpty(val))
90
+ if (lodash.isNil(val) || isEmpty(val))
91
91
  return false;
92
- return pathArray.every(path => _.has(val, path));
92
+ return pathArray.every(path => lodash.has(val, path));
93
93
  };
94
94
  // Promiseかチェック
95
95
  if (resolvedValue instanceof Promise) {
@@ -120,16 +120,16 @@ const hasOr = (value, paths, els) => {
120
120
  * @category Core Functions
121
121
  */
122
122
  const isEmpty = (value) => {
123
- if (_.isNil(value)) {
123
+ if (lodash.isNil(value)) {
124
124
  return true;
125
125
  }
126
- if (_.isNumber(value)) {
126
+ if (lodash.isNumber(value)) {
127
127
  return false;
128
128
  }
129
- if (_.isBoolean(value)) {
129
+ if (lodash.isBoolean(value)) {
130
130
  return false;
131
131
  }
132
- return _.isEmpty(value);
132
+ return lodash.isEmpty(value);
133
133
  };
134
134
  /**
135
135
  * Converts a value to number (full-width and comma aware). Returns null when invalid.
@@ -144,10 +144,10 @@ const isEmpty = (value) => {
144
144
  * @category Core Functions
145
145
  */
146
146
  const toNumber = (value, toFixed) => {
147
- if (_.isNil(value)) {
147
+ if (lodash.isNil(value)) {
148
148
  return null;
149
149
  }
150
- if (_.isNumber(value)) {
150
+ if (lodash.isNumber(value)) {
151
151
  return value;
152
152
  }
153
153
  if (isEmpty(value)) {
@@ -155,16 +155,16 @@ const toNumber = (value, toFixed) => {
155
155
  }
156
156
  let v = toHalfWidth(value);
157
157
  if (typeof v === "string" && v.trim().match(/^[0-9][0-9,.]*$/)) {
158
- v = _.toNumber(v.trim().replace(/,/g, ""));
158
+ v = lodash.toNumber(v.trim().replace(/,/g, ""));
159
159
  }
160
160
  else {
161
- v = _.toNumber(v);
161
+ v = lodash.toNumber(v);
162
162
  }
163
- if (!_.isNaN(v) && !_.isNil(toFixed)) {
164
- const f = _.toNumber(toFixed);
163
+ if (!lodash.isNaN(v) && !lodash.isNil(toFixed)) {
164
+ const f = lodash.toNumber(toFixed);
165
165
  v = parseFloat(v.toFixed(f));
166
166
  }
167
- if (_.isNaN(v)) {
167
+ if (lodash.isNaN(v)) {
168
168
  return null;
169
169
  }
170
170
  return v;
@@ -180,16 +180,16 @@ const toNumber = (value, toFixed) => {
180
180
  * @category Core Functions
181
181
  */
182
182
  const toBool = (value, undetected = null) => {
183
- if (_.isNil(value)) {
183
+ if (lodash.isNil(value)) {
184
184
  return false;
185
185
  }
186
186
  if (isEmpty(value)) {
187
187
  return false;
188
188
  }
189
- if (_.isBoolean(value)) {
189
+ if (lodash.isBoolean(value)) {
190
190
  return value;
191
191
  }
192
- if (_.isNumber(value)) {
192
+ if (lodash.isNumber(value)) {
193
193
  return value !== 0;
194
194
  }
195
195
  const n = toNumber(value);
@@ -231,10 +231,10 @@ const toBool = (value, undetected = null) => {
231
231
  * @category Core Functions
232
232
  */
233
233
  const boolIf = (value, defaultValue = false) => {
234
- if (_.isBoolean(value)) {
234
+ if (lodash.isBoolean(value)) {
235
235
  return value;
236
236
  }
237
- if (_.isNumber(value)) {
237
+ if (lodash.isNumber(value)) {
238
238
  return !!value;
239
239
  }
240
240
  return defaultValue;
@@ -286,10 +286,10 @@ const equalsOr = (...args) => {
286
286
  Promise.resolve(p1),
287
287
  Promise.resolve(p2)
288
288
  ]).then(([v1, v2]) => {
289
- if (_.isNil(v1) && _.isNil(v2)) {
289
+ if (lodash.isNil(v1) && lodash.isNil(v2)) {
290
290
  return null;
291
291
  }
292
- if (_.isEqual(v1, v2)) {
292
+ if (lodash.isEqual(v1, v2)) {
293
293
  return v1;
294
294
  }
295
295
  // elsの解決
@@ -301,10 +301,10 @@ const equalsOr = (...args) => {
301
301
  }
302
302
  else {
303
303
  // 同期処理ブランチ
304
- if (_.isNil(p1) && _.isNil(p2)) {
304
+ if (lodash.isNil(p1) && lodash.isNil(p2)) {
305
305
  return null;
306
306
  }
307
- if (_.isEqual(p1, p2)) {
307
+ if (lodash.isEqual(p1, p2)) {
308
308
  return p1;
309
309
  }
310
310
  // elsの解決
@@ -323,7 +323,7 @@ const equalsOr = (...args) => {
323
323
  * @category Conversion
324
324
  */
325
325
  const parseJSON = (str) => {
326
- if (_.isNil(str)) {
326
+ if (lodash.isNil(str)) {
327
327
  return null;
328
328
  }
329
329
  if (typeof str === "object") {
@@ -347,7 +347,7 @@ const parseJSON = (str) => {
347
347
  * @category Conversion
348
348
  */
349
349
  const jsonStringify = (obj, replacer, space) => {
350
- if (_.isNil(obj)) {
350
+ if (lodash.isNil(obj)) {
351
351
  return null;
352
352
  }
353
353
  if (typeof obj === "string") {
@@ -378,10 +378,10 @@ const jsonStringify = (obj, replacer, space) => {
378
378
  * @category Array Utilities
379
379
  */
380
380
  const castArray = (value) => {
381
- if (_.isNil(value)) {
381
+ if (lodash.isNil(value)) {
382
382
  return [];
383
383
  }
384
- return _.castArray(value);
384
+ return lodash.castArray(value);
385
385
  };
386
386
  /**
387
387
  * Computes differences between two objects. Supports deep paths. When `keyExcludes` is true,
@@ -405,7 +405,7 @@ const castArray = (value) => {
405
405
  */
406
406
  const changes = (sourceValue, currentValue, keys, options, finallyCallback, notEmptyCallback) => {
407
407
  const diff = {};
408
- if (_.isEmpty(keys)) {
408
+ if (lodash.isEmpty(keys)) {
409
409
  keys = [];
410
410
  options = { ...options, keyExcludes: true };
411
411
  }
@@ -418,28 +418,28 @@ const changes = (sourceValue, currentValue, keys, options, finallyCallback, notE
418
418
  }
419
419
  }
420
420
  const targetKeys = options?.keyExcludes === true
421
- ? _.difference(_.uniq([...Object.keys(sourceValue), ...Object.keys(currentValue)]), keys)
421
+ ? lodash.difference(lodash.uniq([...Object.keys(sourceValue), ...Object.keys(currentValue)]), keys)
422
422
  : keys;
423
423
  for (const key of targetKeys) {
424
- const v1 = options?.keyExcludes === true ? sourceValue[key] : _.get(sourceValue, key);
425
- const v2 = options?.keyExcludes === true ? currentValue[key] : _.get(currentValue, key);
426
- if (_.isNil(v1) && _.isNil(v2))
424
+ const v1 = options?.keyExcludes === true ? sourceValue[key] : lodash.get(sourceValue, key);
425
+ const v2 = options?.keyExcludes === true ? currentValue[key] : lodash.get(currentValue, key);
426
+ if (lodash.isNil(v1) && lodash.isNil(v2))
427
427
  continue;
428
- if (_.isNil(v1) || _.isNil(v2)) {
428
+ if (lodash.isNil(v1) || lodash.isNil(v2)) {
429
429
  if (options?.keyExcludes === true) {
430
430
  diff[key] = v2 ?? null;
431
431
  }
432
432
  else {
433
- _.set(diff, key, v2 ?? null);
433
+ lodash.set(diff, key, v2 ?? null);
434
434
  }
435
435
  continue;
436
436
  }
437
- if (!_.isEqual(v1, v2)) {
437
+ if (!lodash.isEqual(v1, v2)) {
438
438
  if (options?.keyExcludes === true) {
439
439
  diff[key] = v2 ?? null;
440
440
  }
441
441
  else {
442
- _.set(diff, key, v2 ?? null);
442
+ lodash.set(diff, key, v2 ?? null);
443
443
  }
444
444
  }
445
445
  }
@@ -559,31 +559,17 @@ const arrayDepth = (ary) => {
559
559
  if (!Array.isArray(ary)) {
560
560
  return 0;
561
561
  }
562
- if (_.size(ary) === 0) {
562
+ if (lodash.size(ary) === 0) {
563
563
  return 1;
564
564
  }
565
565
  return 1 + Math.min(...ary.map(arrayDepth));
566
566
  };
567
- /**
568
- * Extends ansuko with a plugin and returns the augmented instance.
569
- * @param plugin - Plugin function
570
- * @returns Extended instance
571
- * @example const extended = _.extend(jaPlugin)
572
- * @category Core Functions
573
- */
574
- const extend = function (plugin) {
575
- if (typeof plugin === 'function') {
576
- return plugin(this); // プラグインの戻り値をそのまま返す
577
- }
578
- return this;
579
- };
580
- // Ansuko型へのキャストを外し、より安全な unknown as LoDashStatic に変更
581
- export default {
582
- ..._,
583
- extend,
584
- isEmptyOrg: _.isEmpty,
585
- toNumberOrg: _.toNumber,
586
- castArrayOrg: _.castArray,
567
+ // 変数名を _ にすることで、VS Code の auto import 候補が `_` として表示される
568
+ const _ = {
569
+ ...lodash,
570
+ isEmptyOrg: lodash.isEmpty,
571
+ toNumberOrg: lodash.toNumber,
572
+ castArrayOrg: lodash.castArray,
587
573
  strWrap,
588
574
  isEmpty,
589
575
  toNumber,
@@ -602,6 +588,8 @@ export default {
602
588
  swallow,
603
589
  swallowMap,
604
590
  arrayDepth,
591
+ __plugins: new Set(),
605
592
  };
593
+ export default _;
606
594
  // 個別エクスポートはそのまま
607
595
  export { isEmpty, toNumber, boolIf, isValidStr, valueOr, equalsOr, waited, parseJSON, jsonStringify, castArray, changes, strWrap, swallow, swallowMap, arrayDepth, };
@@ -1,5 +1,4 @@
1
- import GeoJSON from "geojson";
2
- import { type AnsukoType } from "../index.js";
1
+ import GeoJSON, { Geometry } from "geojson";
3
2
  /**
4
3
  * Geometry type selector for conversions. Use `auto` to try higher dimensions first.
5
4
  */
@@ -12,8 +11,15 @@ export declare enum GeomType {
12
11
  multiLineString = 5,
13
12
  auto = "auto"
14
13
  }
14
+ /**
15
+ * geo プラグインが ansuko に追加するメソッド群。
16
+ *
17
+ * このインターフェースは下記の `declare module` ブロックで `AnsukoType` に merge され、
18
+ * `import "ansuko/plugins/geo"` するだけで `_` の型が自動的に拡張される。
19
+ */
15
20
  export interface AnsukoGeoPluginExtension {
16
21
  toLngLatArray: (coord: any, digit?: number) => [lng: number, lat: number] | null;
22
+ toGeoJson: (geo: any, type?: GeomType, digit?: number) => Geometry | null;
17
23
  toPointGeoJson: (geo: any, digit?: number) => GeoJSON.Point | null;
18
24
  toPolygonGeoJson: (geo: any, digit?: number) => GeoJSON.Polygon | null;
19
25
  toLineStringGeoJson: (geo: any, digit?: number) => GeoJSON.LineString | null;
@@ -21,8 +27,12 @@ export interface AnsukoGeoPluginExtension {
21
27
  toMultiPolygonGeoJson: (geo: any, digit?: number) => GeoJSON.MultiPolygon | null;
22
28
  toMultiLineStringGeoJson: (geo: any, digit?: number) => GeoJSON.MultiLineString | null;
23
29
  unionPolygon: (geo: any, digit?: number) => GeoJSON.Polygon | GeoJSON.MultiPolygon | null;
30
+ parseToTerraDraw: (geo: any) => GeoJSON.Feature[];
24
31
  mZoomInterpolate: (zoomValues: Record<number, number>, type?: string) => any;
25
32
  mProps: (properties: Record<string, any>, excludeKeys?: string[]) => Record<string, any>;
26
33
  }
27
- declare const ansukoGeoPlugin: <T extends AnsukoType>(ansuko: T) => T & AnsukoGeoPluginExtension;
28
- export default ansukoGeoPlugin;
34
+ declare module "../index.js" {
35
+ interface AnsukoType extends AnsukoGeoPluginExtension {
36
+ }
37
+ }
38
+ export {};
@@ -1,4 +1,5 @@
1
1
  import * as turf from "@turf/turf";
2
+ import _ from "../index.js";
2
3
  /**
3
4
  * Geometry type selector for conversions. Use `auto` to try higher dimensions first.
4
5
  */
@@ -12,8 +13,9 @@ export var GeomType;
12
13
  GeomType[GeomType["multiLineString"] = 5] = "multiLineString";
13
14
  GeomType["auto"] = "auto";
14
15
  })(GeomType || (GeomType = {}));
15
- const ansukoGeoPlugin = (ansuko) => {
16
- const _ = ansuko;
16
+ const PLUGIN_NAME = "geo";
17
+ if (!_.__plugins.has(PLUGIN_NAME)) {
18
+ _.__plugins.add(PLUGIN_NAME);
17
19
  /**
18
20
  * Converts a coordinate-like value to a [lng, lat] tuple, optionally rounding digits.
19
21
  * Swaps order if lat/lng appear to be inverted. Returns null when invalid.
@@ -653,7 +655,7 @@ const ansukoGeoPlugin = (ansuko) => {
653
655
  }
654
656
  return properties;
655
657
  };
656
- const a = ansuko;
658
+ const a = _;
657
659
  a.toLngLatArray = toLngLatArray;
658
660
  a.toGeoJson = toGeoJson;
659
661
  a.toPointGeoJson = toPointGeoJson;
@@ -666,6 +668,4 @@ const ansukoGeoPlugin = (ansuko) => {
666
668
  a.parseToTerraDraw = parseToTerraDraw;
667
669
  a.mZoomInterpolate = mZoomInterpolate;
668
670
  a.mProps = mProps;
669
- return ansuko;
670
- };
671
- export default ansukoGeoPlugin;
671
+ }
@@ -1,13 +1,21 @@
1
- import { type AnsukoType } from "../index.js";
2
- import { toHalfWidth, haifun } from "../util.js";
1
+ import { toHalfWidth as utilToHalfWidth, haifun } from "../util.js";
2
+ /**
3
+ * ja プラグインが ansuko に追加するメソッド群。
4
+ *
5
+ * このインターフェースは下記の `declare module` ブロックで `AnsukoType` に merge され、
6
+ * `import "ansuko/plugins/ja"` するだけで `_` の型が自動的に拡張される。
7
+ */
3
8
  export interface AnsukoJaExtension {
4
9
  kanaToFull: (str: unknown) => string | null;
5
10
  kanaToHalf: (str: unknown) => string | null;
6
11
  kanaToHira: (str: unknown) => string | null;
7
12
  hiraToKana: (str: unknown) => string | null;
8
- toHalfWidth: typeof toHalfWidth;
13
+ toHalfWidth: typeof utilToHalfWidth;
9
14
  toFullWidth: (value: unknown, withHaifun?: string) => string | null;
10
15
  haifun: typeof haifun;
11
16
  }
12
- declare const ansukoJaPlugin: <T extends AnsukoType>(ansuko: T) => T & AnsukoJaExtension;
13
- export default ansukoJaPlugin;
17
+ declare module "../index.js" {
18
+ interface AnsukoType extends AnsukoJaExtension {
19
+ }
20
+ }
21
+ export {};
@@ -1,6 +1,8 @@
1
+ import _ from "../index.js";
1
2
  import { haifun } from "../util.js";
2
- const ansukoJaPlugin = (ansuko) => {
3
- const _ = ansuko;
3
+ const PLUGIN_NAME = "ja";
4
+ if (!_.__plugins.has(PLUGIN_NAME)) {
5
+ _.__plugins.add(PLUGIN_NAME);
4
6
  const kanaMap = {
5
7
  'ガ': 'ガ', 'ギ': 'ギ', 'グ': 'グ', 'ゲ': 'ゲ', 'ゴ': 'ゴ',
6
8
  'ザ': 'ザ', 'ジ': 'ジ', 'ズ': 'ズ', 'ゼ': 'ゼ', 'ゾ': 'ゾ',
@@ -64,7 +66,7 @@ const ansukoJaPlugin = (ansuko) => {
64
66
  if (!_.isValidStr(str)) {
65
67
  return null;
66
68
  }
67
- return kanaToFull(str)?.replace(/[\u30a1-\u30f6]/g, s => String.fromCharCode(s.charCodeAt(0) - 0x60)) ?? null;
69
+ return kanaToFull(str)?.replace(/[ァ-ヶ]/g, s => String.fromCharCode(s.charCodeAt(0) - 0x60)) ?? null;
68
70
  };
69
71
  /**
70
72
  * Converts hiragana to katakana.
@@ -77,7 +79,7 @@ const ansukoJaPlugin = (ansuko) => {
77
79
  if (!_.isValidStr(str)) {
78
80
  return null;
79
81
  }
80
- return str.replace(/[\u3041-\u3096]/g, s => String.fromCharCode(s.charCodeAt(0) + 0x60)) ?? null;
82
+ return str.replace(/[ぁ-ゖ]/g, s => String.fromCharCode(s.charCodeAt(0) + 0x60)) ?? null;
81
83
  };
82
84
  /**
83
85
  * Converts half-width characters to full-width; optionally normalizes hyphens.
@@ -99,7 +101,7 @@ const ansukoJaPlugin = (ansuko) => {
99
101
  const code = char.charCodeAt(0);
100
102
  // スペース
101
103
  if (code === 0x0020) {
102
- return '\u3000'; // 全角スペース
104
+ return ' '; // 全角スペース
103
105
  }
104
106
  // 全角は0x0021~0x007E、半角は0xFF01~0xFF5E
105
107
  if (code >= 0x0021 && code <= 0x007E) {
@@ -126,7 +128,7 @@ const ansukoJaPlugin = (ansuko) => {
126
128
  const code = char.charCodeAt(0);
127
129
  // スペース
128
130
  if (code === 0x3000) {
129
- return '\u0020'; // 半角スペース
131
+ return ' '; // 半角スペース
130
132
  }
131
133
  // 全角は0xFF01~0xFF5E、半角は0x0021~0x007E
132
134
  if (code >= 0xFF01 && code <= 0xFF5E) {
@@ -136,7 +138,7 @@ const ansukoJaPlugin = (ansuko) => {
136
138
  }).join('');
137
139
  return withHaifun ? haifun(str, withHaifun) : str;
138
140
  };
139
- const a = ansuko;
141
+ const a = _;
140
142
  a.kanaToFull = kanaToFull;
141
143
  a.kanaToHalf = kanaToHalf;
142
144
  a.kanaToHira = kanaToHira;
@@ -144,6 +146,4 @@ const ansukoJaPlugin = (ansuko) => {
144
146
  a.toHalfWidth = toHalfWidth;
145
147
  a.toFullWidth = toFullWidth;
146
148
  a.haifun = haifun;
147
- return ansuko;
148
- };
149
- export default ansukoJaPlugin;
149
+ }
@@ -18,5 +18,4 @@ declare global {
18
18
  notFilter(predicate: (item: T) => boolean): T[];
19
19
  }
20
20
  }
21
- declare const ansukoPrototypePlugin: (ansuko: any) => void;
22
- export default ansukoPrototypePlugin;
21
+ export {};
@@ -1,9 +1,11 @@
1
- const ansukoPrototypePlugin = (ansuko) => {
1
+ import _ from "../index.js";
2
+ const PLUGIN_NAME = "prototype";
3
+ if (!_.__plugins.has(PLUGIN_NAME)) {
4
+ _.__plugins.add(PLUGIN_NAME);
2
5
  Array.prototype.notMap = function (predicate) {
3
- return this.map(ansuko.negate(predicate));
6
+ return this.map(_.negate(predicate));
4
7
  };
5
8
  Array.prototype.notFilter = function (predicate) {
6
- return this.filter(ansuko.negate(predicate));
9
+ return this.filter(_.negate(predicate));
7
10
  };
8
- };
9
- export default ansukoPrototypePlugin;
11
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ansuko",
3
- "version": "1.3.13",
3
+ "version": "2.0.0",
4
4
  "description": "A modern JavaScript/TypeScript utility library that extends lodash with practical, intuitive behaviors. Fixes lodash quirks, adds Promise support, Japanese text processing, and GeoJSON utilities.",
5
5
  "keywords": [
6
6
  "lodash",