deep-case-crafter 3.5.0 → 3.7.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/dist/index.d.cts +86 -5
- package/dist/index.d.mts +86 -5
- package/dist/index.d.ts +86 -5
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +5 -4
- package/readme.md +96 -20
package/dist/index.d.cts
CHANGED
|
@@ -44,9 +44,10 @@ interface TransformKeyOptions {
|
|
|
44
44
|
targetCase?: StringCase | undefined;
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
47
|
-
* Options for the
|
|
47
|
+
* Options for the transformTo function, which takes the target case as an argument of
|
|
48
|
+
* its own. The transform function takes them as well.
|
|
48
49
|
*/
|
|
49
|
-
interface
|
|
50
|
+
interface TransformToOptions {
|
|
50
51
|
/**
|
|
51
52
|
* How many nesting levels to transform: `1` transforms only the top-level keys, `2`
|
|
52
53
|
* also the keys one level down, and so on. The values of objects, Maps and Sets are one
|
|
@@ -92,6 +93,11 @@ interface TransformOptions extends TransformKeyOptions {
|
|
|
92
93
|
* @default true
|
|
93
94
|
*/
|
|
94
95
|
keepReferences?: boolean | undefined;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Options for the transform function
|
|
99
|
+
*/
|
|
100
|
+
interface TransformOptions extends TransformKeyOptions, TransformToOptions {
|
|
95
101
|
/**
|
|
96
102
|
* @deprecated Has no effect. Every key's case is detected from the key itself, both at
|
|
97
103
|
* runtime and in the result type, so there is nothing to declare.
|
|
@@ -142,7 +148,7 @@ type DepthOf<Options> = 'depth' extends keyof Options ? Options['depth'] : undef
|
|
|
142
148
|
type ExcludeOf<Options> = 'exclude' extends keyof Options ? Options['exclude'] : undefined;
|
|
143
149
|
|
|
144
150
|
/**
|
|
145
|
-
* Type-level mirror of the `exclude` matching (`
|
|
151
|
+
* Type-level mirror of the `exclude` matching (`transform/exclude`).
|
|
146
152
|
*
|
|
147
153
|
* The paths that still match at a level are a union of strings: the rest of each
|
|
148
154
|
* `exclude` path below the keys that lead there. `'users_by_id.*' | 'metadata.*'` at the
|
|
@@ -507,6 +513,33 @@ type TransformResultForExcluding<T, Options> = ExcludeOf<Options> extends infer
|
|
|
507
513
|
* result: `unknown`.
|
|
508
514
|
*/
|
|
509
515
|
type TransformResultFor<T, Options> = IsAny<Options> extends true ? unknown : Options extends unknown ? IsAnyOption<Options, 'targetCase'> extends true ? unknown : IsAnyOption<Options, 'depth'> extends true ? unknown : 'exclude' extends keyof Options ? TransformResultForExcluding<T, Options> : TransformResultForOne<T, Options> : never;
|
|
516
|
+
/**
|
|
517
|
+
* Each member of a union of options objects with the target case `To`, which
|
|
518
|
+
* `transformTo` takes as an argument of its own: a member with `targetCase: undefined`
|
|
519
|
+
* keeps its result, which an intersection with `{ targetCase: To }` would drop as `never`.
|
|
520
|
+
*/
|
|
521
|
+
type WithTargetCase<Options, To> = Options extends unknown ? Omit<Options, 'targetCase'> & {
|
|
522
|
+
targetCase: To;
|
|
523
|
+
} : never;
|
|
524
|
+
/**
|
|
525
|
+
* The function `transformTo` returns. It transforms the keys of its argument to `To`
|
|
526
|
+
* (`'camel'` for `undefined`) with the `Options` passed to `transformTo`, and its result
|
|
527
|
+
* type is the one `transform` gives for the same options.
|
|
528
|
+
*
|
|
529
|
+
* It has a single call signature, generic in the data, so TypeScript can infer the data
|
|
530
|
+
* where it is passed by name, as in `.then(transformTo('camel'))`. Declaration files of
|
|
531
|
+
* code that stores one refer to it by name.
|
|
532
|
+
*
|
|
533
|
+
* A function for one target case can be passed where a `TransformTo<StringCase>` is
|
|
534
|
+
* expected, or a `<T>(data: T) => unknown`.
|
|
535
|
+
*/
|
|
536
|
+
interface TransformTo<To extends StringCase | undefined, Options = {}> {
|
|
537
|
+
/**
|
|
538
|
+
* Transforms the keys of `data`, as `transform` does with the target case and options
|
|
539
|
+
* passed to `transformTo`. Only the first argument is used, so callbacks can pass more.
|
|
540
|
+
*/
|
|
541
|
+
<T>(data: T): TransformResultFor<T, WithTargetCase<Options, To>>;
|
|
542
|
+
}
|
|
510
543
|
/**
|
|
511
544
|
* The key type `transformKey` returns for an options object. Each member of a union of
|
|
512
545
|
* options objects gives its own key, and an optional `targetCase` may also be omitted,
|
|
@@ -586,6 +619,54 @@ declare function transform<T, From extends StringCase, To extends StringCase>(da
|
|
|
586
619
|
*/
|
|
587
620
|
declare function transform<T, K>(data: T, options?: Omit<TransformOptions, 'sourceCase'>): K;
|
|
588
621
|
|
|
622
|
+
/**
|
|
623
|
+
* Makes a function that transforms the keys of its argument to `targetCase`, at every
|
|
624
|
+
* nesting level, as `transform(data, { targetCase })` does. The function uses only its
|
|
625
|
+
* first argument, so it can be passed as a callback, and its result type is exact there
|
|
626
|
+
* too: `fetchUser().then(transformTo('camel'))`, `items.map(transformTo('snake'))`.
|
|
627
|
+
*
|
|
628
|
+
* As for `transform`, an `undefined` target case means `'camel'`.
|
|
629
|
+
*/
|
|
630
|
+
declare function transformTo<To extends StringCase | undefined>(targetCase: To, options?: undefined): TransformTo<To>;
|
|
631
|
+
/**
|
|
632
|
+
* Makes a function that transforms the keys of its argument to `targetCase`, at every
|
|
633
|
+
* nesting level unless `depth` is set, except the keys at the `exclude` paths, as
|
|
634
|
+
* `transform` does with the same options. The function uses only its first argument, so
|
|
635
|
+
* it can be passed as a callback, and its result type is exact there too.
|
|
636
|
+
*
|
|
637
|
+
* The options are checked and read here, once: changing the options object or the
|
|
638
|
+
* `exclude` array afterwards does not change the function.
|
|
639
|
+
*
|
|
640
|
+
* As in `transform`, `Depth` captures a literal `depth`, and `Options` the options object
|
|
641
|
+
* as a whole, with an inline `exclude` array as a tuple of string literals. Options typed
|
|
642
|
+
* loosely, such as `TransformToOptions` itself, match too, and give results typed
|
|
643
|
+
* `unknown`, as they do for `transform`.
|
|
644
|
+
*
|
|
645
|
+
* `NoUnknownOptions` rejects unknown option names, `targetCase` included, which is the
|
|
646
|
+
* first argument. It sees only the names every member of a union has, so `targetCase?:
|
|
647
|
+
* undefined` rejects a target case in any member as well, and `length?: never` rejects
|
|
648
|
+
* arrays and functions, which `object` and an empty `NoUnknownOptions` would let through.
|
|
649
|
+
* An options object that may itself be `undefined` does not match this overload, and gets
|
|
650
|
+
* results typed `unknown` from the last one.
|
|
651
|
+
*/
|
|
652
|
+
declare function transformTo<To extends StringCase | undefined, Depth extends number | undefined = number | undefined, Options extends TransformToOptions & {
|
|
653
|
+
exclude?: readonly [...Paths] | readonly [string?] | readonly string[] | undefined;
|
|
654
|
+
} = TransformToOptions, Paths extends readonly string[] = readonly string[]>(targetCase: To, options: Options & {
|
|
655
|
+
depth?: Depth;
|
|
656
|
+
targetCase?: undefined;
|
|
657
|
+
length?: never;
|
|
658
|
+
} & NoUnknownOptions<Options, TransformToOptions> & object): TransformTo<To, Options>;
|
|
659
|
+
/**
|
|
660
|
+
* Makes a function that transforms the keys of its argument to `targetCase`, as
|
|
661
|
+
* `transform` does with the same options, for options that are not known exactly: an
|
|
662
|
+
* options object that may be `undefined`, or one with properties that are not options.
|
|
663
|
+
* The function's results are typed `unknown`. A `targetCase` among the options is
|
|
664
|
+
* rejected here too, as it is at runtime.
|
|
665
|
+
*/
|
|
666
|
+
declare function transformTo<To extends StringCase | undefined>(targetCase: To, options?: TransformToOptions & {
|
|
667
|
+
targetCase?: undefined;
|
|
668
|
+
}): TransformTo<To, TransformToOptions>;
|
|
669
|
+
|
|
589
670
|
/**
|
|
590
671
|
* Transforms one key to camelCase, the way `transform` transforms every key. A string
|
|
591
672
|
* that is not a camelCase, PascalCase, snake_case or kebab-case key, such as
|
|
@@ -621,5 +702,5 @@ declare function transformKey<K extends string, Options extends TransformKeyOpti
|
|
|
621
702
|
*/
|
|
622
703
|
declare function transformKey(key: string, options?: TransformKeyOptions): string;
|
|
623
704
|
|
|
624
|
-
export { transform, transformKey };
|
|
625
|
-
export type { CaseOrDefault, PlainCase, StringCase, TransformKey, TransformKeyOptions, TransformKeyToEach, TransformOptions, TransformResult, TransformResultFor, TransformResultForExcluding, TransformValue, TransformValueExcluding };
|
|
705
|
+
export { transform, transformKey, transformTo };
|
|
706
|
+
export type { CaseOrDefault, PlainCase, StringCase, TransformKey, TransformKeyOptions, TransformKeyToEach, TransformOptions, TransformResult, TransformResultFor, TransformResultForExcluding, TransformTo, TransformToOptions, TransformValue, TransformValueExcluding };
|
package/dist/index.d.mts
CHANGED
|
@@ -44,9 +44,10 @@ interface TransformKeyOptions {
|
|
|
44
44
|
targetCase?: StringCase | undefined;
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
47
|
-
* Options for the
|
|
47
|
+
* Options for the transformTo function, which takes the target case as an argument of
|
|
48
|
+
* its own. The transform function takes them as well.
|
|
48
49
|
*/
|
|
49
|
-
interface
|
|
50
|
+
interface TransformToOptions {
|
|
50
51
|
/**
|
|
51
52
|
* How many nesting levels to transform: `1` transforms only the top-level keys, `2`
|
|
52
53
|
* also the keys one level down, and so on. The values of objects, Maps and Sets are one
|
|
@@ -92,6 +93,11 @@ interface TransformOptions extends TransformKeyOptions {
|
|
|
92
93
|
* @default true
|
|
93
94
|
*/
|
|
94
95
|
keepReferences?: boolean | undefined;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Options for the transform function
|
|
99
|
+
*/
|
|
100
|
+
interface TransformOptions extends TransformKeyOptions, TransformToOptions {
|
|
95
101
|
/**
|
|
96
102
|
* @deprecated Has no effect. Every key's case is detected from the key itself, both at
|
|
97
103
|
* runtime and in the result type, so there is nothing to declare.
|
|
@@ -142,7 +148,7 @@ type DepthOf<Options> = 'depth' extends keyof Options ? Options['depth'] : undef
|
|
|
142
148
|
type ExcludeOf<Options> = 'exclude' extends keyof Options ? Options['exclude'] : undefined;
|
|
143
149
|
|
|
144
150
|
/**
|
|
145
|
-
* Type-level mirror of the `exclude` matching (`
|
|
151
|
+
* Type-level mirror of the `exclude` matching (`transform/exclude`).
|
|
146
152
|
*
|
|
147
153
|
* The paths that still match at a level are a union of strings: the rest of each
|
|
148
154
|
* `exclude` path below the keys that lead there. `'users_by_id.*' | 'metadata.*'` at the
|
|
@@ -507,6 +513,33 @@ type TransformResultForExcluding<T, Options> = ExcludeOf<Options> extends infer
|
|
|
507
513
|
* result: `unknown`.
|
|
508
514
|
*/
|
|
509
515
|
type TransformResultFor<T, Options> = IsAny<Options> extends true ? unknown : Options extends unknown ? IsAnyOption<Options, 'targetCase'> extends true ? unknown : IsAnyOption<Options, 'depth'> extends true ? unknown : 'exclude' extends keyof Options ? TransformResultForExcluding<T, Options> : TransformResultForOne<T, Options> : never;
|
|
516
|
+
/**
|
|
517
|
+
* Each member of a union of options objects with the target case `To`, which
|
|
518
|
+
* `transformTo` takes as an argument of its own: a member with `targetCase: undefined`
|
|
519
|
+
* keeps its result, which an intersection with `{ targetCase: To }` would drop as `never`.
|
|
520
|
+
*/
|
|
521
|
+
type WithTargetCase<Options, To> = Options extends unknown ? Omit<Options, 'targetCase'> & {
|
|
522
|
+
targetCase: To;
|
|
523
|
+
} : never;
|
|
524
|
+
/**
|
|
525
|
+
* The function `transformTo` returns. It transforms the keys of its argument to `To`
|
|
526
|
+
* (`'camel'` for `undefined`) with the `Options` passed to `transformTo`, and its result
|
|
527
|
+
* type is the one `transform` gives for the same options.
|
|
528
|
+
*
|
|
529
|
+
* It has a single call signature, generic in the data, so TypeScript can infer the data
|
|
530
|
+
* where it is passed by name, as in `.then(transformTo('camel'))`. Declaration files of
|
|
531
|
+
* code that stores one refer to it by name.
|
|
532
|
+
*
|
|
533
|
+
* A function for one target case can be passed where a `TransformTo<StringCase>` is
|
|
534
|
+
* expected, or a `<T>(data: T) => unknown`.
|
|
535
|
+
*/
|
|
536
|
+
interface TransformTo<To extends StringCase | undefined, Options = {}> {
|
|
537
|
+
/**
|
|
538
|
+
* Transforms the keys of `data`, as `transform` does with the target case and options
|
|
539
|
+
* passed to `transformTo`. Only the first argument is used, so callbacks can pass more.
|
|
540
|
+
*/
|
|
541
|
+
<T>(data: T): TransformResultFor<T, WithTargetCase<Options, To>>;
|
|
542
|
+
}
|
|
510
543
|
/**
|
|
511
544
|
* The key type `transformKey` returns for an options object. Each member of a union of
|
|
512
545
|
* options objects gives its own key, and an optional `targetCase` may also be omitted,
|
|
@@ -586,6 +619,54 @@ declare function transform<T, From extends StringCase, To extends StringCase>(da
|
|
|
586
619
|
*/
|
|
587
620
|
declare function transform<T, K>(data: T, options?: Omit<TransformOptions, 'sourceCase'>): K;
|
|
588
621
|
|
|
622
|
+
/**
|
|
623
|
+
* Makes a function that transforms the keys of its argument to `targetCase`, at every
|
|
624
|
+
* nesting level, as `transform(data, { targetCase })` does. The function uses only its
|
|
625
|
+
* first argument, so it can be passed as a callback, and its result type is exact there
|
|
626
|
+
* too: `fetchUser().then(transformTo('camel'))`, `items.map(transformTo('snake'))`.
|
|
627
|
+
*
|
|
628
|
+
* As for `transform`, an `undefined` target case means `'camel'`.
|
|
629
|
+
*/
|
|
630
|
+
declare function transformTo<To extends StringCase | undefined>(targetCase: To, options?: undefined): TransformTo<To>;
|
|
631
|
+
/**
|
|
632
|
+
* Makes a function that transforms the keys of its argument to `targetCase`, at every
|
|
633
|
+
* nesting level unless `depth` is set, except the keys at the `exclude` paths, as
|
|
634
|
+
* `transform` does with the same options. The function uses only its first argument, so
|
|
635
|
+
* it can be passed as a callback, and its result type is exact there too.
|
|
636
|
+
*
|
|
637
|
+
* The options are checked and read here, once: changing the options object or the
|
|
638
|
+
* `exclude` array afterwards does not change the function.
|
|
639
|
+
*
|
|
640
|
+
* As in `transform`, `Depth` captures a literal `depth`, and `Options` the options object
|
|
641
|
+
* as a whole, with an inline `exclude` array as a tuple of string literals. Options typed
|
|
642
|
+
* loosely, such as `TransformToOptions` itself, match too, and give results typed
|
|
643
|
+
* `unknown`, as they do for `transform`.
|
|
644
|
+
*
|
|
645
|
+
* `NoUnknownOptions` rejects unknown option names, `targetCase` included, which is the
|
|
646
|
+
* first argument. It sees only the names every member of a union has, so `targetCase?:
|
|
647
|
+
* undefined` rejects a target case in any member as well, and `length?: never` rejects
|
|
648
|
+
* arrays and functions, which `object` and an empty `NoUnknownOptions` would let through.
|
|
649
|
+
* An options object that may itself be `undefined` does not match this overload, and gets
|
|
650
|
+
* results typed `unknown` from the last one.
|
|
651
|
+
*/
|
|
652
|
+
declare function transformTo<To extends StringCase | undefined, Depth extends number | undefined = number | undefined, Options extends TransformToOptions & {
|
|
653
|
+
exclude?: readonly [...Paths] | readonly [string?] | readonly string[] | undefined;
|
|
654
|
+
} = TransformToOptions, Paths extends readonly string[] = readonly string[]>(targetCase: To, options: Options & {
|
|
655
|
+
depth?: Depth;
|
|
656
|
+
targetCase?: undefined;
|
|
657
|
+
length?: never;
|
|
658
|
+
} & NoUnknownOptions<Options, TransformToOptions> & object): TransformTo<To, Options>;
|
|
659
|
+
/**
|
|
660
|
+
* Makes a function that transforms the keys of its argument to `targetCase`, as
|
|
661
|
+
* `transform` does with the same options, for options that are not known exactly: an
|
|
662
|
+
* options object that may be `undefined`, or one with properties that are not options.
|
|
663
|
+
* The function's results are typed `unknown`. A `targetCase` among the options is
|
|
664
|
+
* rejected here too, as it is at runtime.
|
|
665
|
+
*/
|
|
666
|
+
declare function transformTo<To extends StringCase | undefined>(targetCase: To, options?: TransformToOptions & {
|
|
667
|
+
targetCase?: undefined;
|
|
668
|
+
}): TransformTo<To, TransformToOptions>;
|
|
669
|
+
|
|
589
670
|
/**
|
|
590
671
|
* Transforms one key to camelCase, the way `transform` transforms every key. A string
|
|
591
672
|
* that is not a camelCase, PascalCase, snake_case or kebab-case key, such as
|
|
@@ -621,5 +702,5 @@ declare function transformKey<K extends string, Options extends TransformKeyOpti
|
|
|
621
702
|
*/
|
|
622
703
|
declare function transformKey(key: string, options?: TransformKeyOptions): string;
|
|
623
704
|
|
|
624
|
-
export { transform, transformKey };
|
|
625
|
-
export type { CaseOrDefault, PlainCase, StringCase, TransformKey, TransformKeyOptions, TransformKeyToEach, TransformOptions, TransformResult, TransformResultFor, TransformResultForExcluding, TransformValue, TransformValueExcluding };
|
|
705
|
+
export { transform, transformKey, transformTo };
|
|
706
|
+
export type { CaseOrDefault, PlainCase, StringCase, TransformKey, TransformKeyOptions, TransformKeyToEach, TransformOptions, TransformResult, TransformResultFor, TransformResultForExcluding, TransformTo, TransformToOptions, TransformValue, TransformValueExcluding };
|
package/dist/index.d.ts
CHANGED
|
@@ -44,9 +44,10 @@ interface TransformKeyOptions {
|
|
|
44
44
|
targetCase?: StringCase | undefined;
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
47
|
-
* Options for the
|
|
47
|
+
* Options for the transformTo function, which takes the target case as an argument of
|
|
48
|
+
* its own. The transform function takes them as well.
|
|
48
49
|
*/
|
|
49
|
-
interface
|
|
50
|
+
interface TransformToOptions {
|
|
50
51
|
/**
|
|
51
52
|
* How many nesting levels to transform: `1` transforms only the top-level keys, `2`
|
|
52
53
|
* also the keys one level down, and so on. The values of objects, Maps and Sets are one
|
|
@@ -92,6 +93,11 @@ interface TransformOptions extends TransformKeyOptions {
|
|
|
92
93
|
* @default true
|
|
93
94
|
*/
|
|
94
95
|
keepReferences?: boolean | undefined;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Options for the transform function
|
|
99
|
+
*/
|
|
100
|
+
interface TransformOptions extends TransformKeyOptions, TransformToOptions {
|
|
95
101
|
/**
|
|
96
102
|
* @deprecated Has no effect. Every key's case is detected from the key itself, both at
|
|
97
103
|
* runtime and in the result type, so there is nothing to declare.
|
|
@@ -142,7 +148,7 @@ type DepthOf<Options> = 'depth' extends keyof Options ? Options['depth'] : undef
|
|
|
142
148
|
type ExcludeOf<Options> = 'exclude' extends keyof Options ? Options['exclude'] : undefined;
|
|
143
149
|
|
|
144
150
|
/**
|
|
145
|
-
* Type-level mirror of the `exclude` matching (`
|
|
151
|
+
* Type-level mirror of the `exclude` matching (`transform/exclude`).
|
|
146
152
|
*
|
|
147
153
|
* The paths that still match at a level are a union of strings: the rest of each
|
|
148
154
|
* `exclude` path below the keys that lead there. `'users_by_id.*' | 'metadata.*'` at the
|
|
@@ -507,6 +513,33 @@ type TransformResultForExcluding<T, Options> = ExcludeOf<Options> extends infer
|
|
|
507
513
|
* result: `unknown`.
|
|
508
514
|
*/
|
|
509
515
|
type TransformResultFor<T, Options> = IsAny<Options> extends true ? unknown : Options extends unknown ? IsAnyOption<Options, 'targetCase'> extends true ? unknown : IsAnyOption<Options, 'depth'> extends true ? unknown : 'exclude' extends keyof Options ? TransformResultForExcluding<T, Options> : TransformResultForOne<T, Options> : never;
|
|
516
|
+
/**
|
|
517
|
+
* Each member of a union of options objects with the target case `To`, which
|
|
518
|
+
* `transformTo` takes as an argument of its own: a member with `targetCase: undefined`
|
|
519
|
+
* keeps its result, which an intersection with `{ targetCase: To }` would drop as `never`.
|
|
520
|
+
*/
|
|
521
|
+
type WithTargetCase<Options, To> = Options extends unknown ? Omit<Options, 'targetCase'> & {
|
|
522
|
+
targetCase: To;
|
|
523
|
+
} : never;
|
|
524
|
+
/**
|
|
525
|
+
* The function `transformTo` returns. It transforms the keys of its argument to `To`
|
|
526
|
+
* (`'camel'` for `undefined`) with the `Options` passed to `transformTo`, and its result
|
|
527
|
+
* type is the one `transform` gives for the same options.
|
|
528
|
+
*
|
|
529
|
+
* It has a single call signature, generic in the data, so TypeScript can infer the data
|
|
530
|
+
* where it is passed by name, as in `.then(transformTo('camel'))`. Declaration files of
|
|
531
|
+
* code that stores one refer to it by name.
|
|
532
|
+
*
|
|
533
|
+
* A function for one target case can be passed where a `TransformTo<StringCase>` is
|
|
534
|
+
* expected, or a `<T>(data: T) => unknown`.
|
|
535
|
+
*/
|
|
536
|
+
interface TransformTo<To extends StringCase | undefined, Options = {}> {
|
|
537
|
+
/**
|
|
538
|
+
* Transforms the keys of `data`, as `transform` does with the target case and options
|
|
539
|
+
* passed to `transformTo`. Only the first argument is used, so callbacks can pass more.
|
|
540
|
+
*/
|
|
541
|
+
<T>(data: T): TransformResultFor<T, WithTargetCase<Options, To>>;
|
|
542
|
+
}
|
|
510
543
|
/**
|
|
511
544
|
* The key type `transformKey` returns for an options object. Each member of a union of
|
|
512
545
|
* options objects gives its own key, and an optional `targetCase` may also be omitted,
|
|
@@ -586,6 +619,54 @@ declare function transform<T, From extends StringCase, To extends StringCase>(da
|
|
|
586
619
|
*/
|
|
587
620
|
declare function transform<T, K>(data: T, options?: Omit<TransformOptions, 'sourceCase'>): K;
|
|
588
621
|
|
|
622
|
+
/**
|
|
623
|
+
* Makes a function that transforms the keys of its argument to `targetCase`, at every
|
|
624
|
+
* nesting level, as `transform(data, { targetCase })` does. The function uses only its
|
|
625
|
+
* first argument, so it can be passed as a callback, and its result type is exact there
|
|
626
|
+
* too: `fetchUser().then(transformTo('camel'))`, `items.map(transformTo('snake'))`.
|
|
627
|
+
*
|
|
628
|
+
* As for `transform`, an `undefined` target case means `'camel'`.
|
|
629
|
+
*/
|
|
630
|
+
declare function transformTo<To extends StringCase | undefined>(targetCase: To, options?: undefined): TransformTo<To>;
|
|
631
|
+
/**
|
|
632
|
+
* Makes a function that transforms the keys of its argument to `targetCase`, at every
|
|
633
|
+
* nesting level unless `depth` is set, except the keys at the `exclude` paths, as
|
|
634
|
+
* `transform` does with the same options. The function uses only its first argument, so
|
|
635
|
+
* it can be passed as a callback, and its result type is exact there too.
|
|
636
|
+
*
|
|
637
|
+
* The options are checked and read here, once: changing the options object or the
|
|
638
|
+
* `exclude` array afterwards does not change the function.
|
|
639
|
+
*
|
|
640
|
+
* As in `transform`, `Depth` captures a literal `depth`, and `Options` the options object
|
|
641
|
+
* as a whole, with an inline `exclude` array as a tuple of string literals. Options typed
|
|
642
|
+
* loosely, such as `TransformToOptions` itself, match too, and give results typed
|
|
643
|
+
* `unknown`, as they do for `transform`.
|
|
644
|
+
*
|
|
645
|
+
* `NoUnknownOptions` rejects unknown option names, `targetCase` included, which is the
|
|
646
|
+
* first argument. It sees only the names every member of a union has, so `targetCase?:
|
|
647
|
+
* undefined` rejects a target case in any member as well, and `length?: never` rejects
|
|
648
|
+
* arrays and functions, which `object` and an empty `NoUnknownOptions` would let through.
|
|
649
|
+
* An options object that may itself be `undefined` does not match this overload, and gets
|
|
650
|
+
* results typed `unknown` from the last one.
|
|
651
|
+
*/
|
|
652
|
+
declare function transformTo<To extends StringCase | undefined, Depth extends number | undefined = number | undefined, Options extends TransformToOptions & {
|
|
653
|
+
exclude?: readonly [...Paths] | readonly [string?] | readonly string[] | undefined;
|
|
654
|
+
} = TransformToOptions, Paths extends readonly string[] = readonly string[]>(targetCase: To, options: Options & {
|
|
655
|
+
depth?: Depth;
|
|
656
|
+
targetCase?: undefined;
|
|
657
|
+
length?: never;
|
|
658
|
+
} & NoUnknownOptions<Options, TransformToOptions> & object): TransformTo<To, Options>;
|
|
659
|
+
/**
|
|
660
|
+
* Makes a function that transforms the keys of its argument to `targetCase`, as
|
|
661
|
+
* `transform` does with the same options, for options that are not known exactly: an
|
|
662
|
+
* options object that may be `undefined`, or one with properties that are not options.
|
|
663
|
+
* The function's results are typed `unknown`. A `targetCase` among the options is
|
|
664
|
+
* rejected here too, as it is at runtime.
|
|
665
|
+
*/
|
|
666
|
+
declare function transformTo<To extends StringCase | undefined>(targetCase: To, options?: TransformToOptions & {
|
|
667
|
+
targetCase?: undefined;
|
|
668
|
+
}): TransformTo<To, TransformToOptions>;
|
|
669
|
+
|
|
589
670
|
/**
|
|
590
671
|
* Transforms one key to camelCase, the way `transform` transforms every key. A string
|
|
591
672
|
* that is not a camelCase, PascalCase, snake_case or kebab-case key, such as
|
|
@@ -621,5 +702,5 @@ declare function transformKey<K extends string, Options extends TransformKeyOpti
|
|
|
621
702
|
*/
|
|
622
703
|
declare function transformKey(key: string, options?: TransformKeyOptions): string;
|
|
623
704
|
|
|
624
|
-
export { transform, transformKey };
|
|
625
|
-
export type { CaseOrDefault, PlainCase, StringCase, TransformKey, TransformKeyOptions, TransformKeyToEach, TransformOptions, TransformResult, TransformResultFor, TransformResultForExcluding, TransformValue, TransformValueExcluding };
|
|
705
|
+
export { transform, transformKey, transformTo };
|
|
706
|
+
export type { CaseOrDefault, PlainCase, StringCase, TransformKey, TransformKeyOptions, TransformKeyToEach, TransformOptions, TransformResult, TransformResultFor, TransformResultForExcluding, TransformTo, TransformToOptions, TransformValue, TransformValueExcluding };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const e=/^[^.]+(?:\.[^.]+)*$/;function t(e){if("string"==typeof e)return JSON.stringify(e);if("bigint"==typeof e)return`${e}n`;if(null===e)return"null";if("object"==typeof e||"function"==typeof e)try{return Object.prototype.toString.call(e)}catch(e){return"an object"}return String(e)}function n(e){const t=e.indexOf(".");return-1===t?[e]:[e.slice(0,t),e.slice(t+1)]}const r=[];function o(e){let t,n=!1;for(const r of e)void 0===r?n=!0:(null!=t?t:t=[]).push(r);return{keepKey:n,pathsBelow:t?s(t):r,scope:void 0}}function s(e){return 1===e.length?e:[...new Set(e)].sort()}function c(e,t){const r=[];let s;for(const t of e){const[e,o]=n(t);if("*"===e)r.push(o);else{null!=s||(s=new Map);const t=s.get(e);t?t.push(o):s.set(e,[o])}}const c=new Map;for(const[e,t]of null!=s?s:[])c.set(e,o(r.length?[...t,...r]:t));const{targetCase:u,depth:i,keepReferences:a}=t.plain.options,f={targetCase:u,depth:i,keepReferences:a,exclude:null},l={options:f,visitedRefs:[],named:c,other:o(r),root:t};return f.exclude=l,l}function u(e,t){const n=JSON.stringify(e);let r=t.states.get(n);return r||(r=c(e,t),t.states.set(n,r)),r}function i(n,r){if(null==n)return null;if(!Array.isArray(n))throw new TypeError(`Unsupported exclude ${t(n)}. Use an array of paths, such as ["metadata.*"].`);for(const r of n)if("string"!=typeof r||!e.test(r))throw new TypeError(`Unsupported exclude path ${t(r)}. Use non-empty keys joined with dots, such as "metadata.*".`);if(0===n.length)return null;const o={plain:{options:r,visitedRefs:[]},states:new Map};return c(s(n),o)}function a(e,t){const n="string"==typeof t?e.named.get(t):void 0;return null!=n?n:e.other}function f(e,t){var n;return null!==(n=t.scope)&&void 0!==n?n:t.scope=0===t.pathsBelow.length?e.root.plain:u(t.pathsBelow,e.root)}const l="[object Object]";function p(e){try{return Object.prototype.toString.call(e)}catch(e){return l}}function d(e,t){if(!(e instanceof Map)&&"[object Map]"!==t)return!1;try{return Map.prototype.has.call(e,void 0),!0}catch(e){return!1}}function h(e,t){if(!(e instanceof Set)&&"[object Set]"!==t)return!1;try{return Set.prototype.has.call(e,void 0),!0}catch(e){return!1}}function y(e,t,n){"__proto__"===t?Object.defineProperty(e,t,{value:n,enumerable:!0,writable:!0,configurable:!0}):e[t]=n}const g={};let w=!1;function b(e,t){const n=e.get(t);if(void 0!==n||!w)return n;let r=e.get(g);for(;void 0!==r;){const e=r.get(t);if(void 0!==e)return e;r=r.get(g)}}function v(e,t,n,r){let o=e[t];o.size>=16e6&&(w=!0,o=e[t]=new Map([[g,o]])),o.set(n,r)}function C(e){return e>=48&&e<=57}function U(e){return e>=97&&e<=122}function m(e){return e>=65&&e<=90}function k(e){if(36!==e.length)return!1;for(let t=0;t<36;t++){const n=e.charCodeAt(t);if(8===t||13===t||18===t||23===t){if(45!==n)return!1}else if(!(C(n)||n>=97&&n<=102||n>=65&&n<=70))return!1}return!0}const j="s".charCodeAt(0);function x(e,t){if(!m(e.charCodeAt(t)))return!1;const n=e.charCodeAt(t-1);if(U(n)||C(n))return!0;const r=e.charCodeAt(t+1);return!(!m(n)||!U(r))&&(r!==j||U(e.charCodeAt(t+2)))}function O(e){let t=1;for(;t<e.length&&!x(e,t);)t++;return e.slice(0,t).toLowerCase()+e.slice(t)}function M(e,t,n){return e.split(t).join(n)}function A(e,t,n){let r=n?e[0].toUpperCase():e[0],o=1,s=e.indexOf(t,1);for(;-1!==s;)r+=e.slice(o,s)+e[s+1].toUpperCase(),o=s+2,s=e.indexOf(t,o);return r+e.slice(o)}function _(e,t){const n=m(e.charCodeAt(0));switch(t){case"pascal":return n?e:e[0].toUpperCase()+e.slice(1);case"camel":return n?e[0].toLowerCase()+e.slice(1):e;case"constant":return e.toUpperCase();default:return n?e.toLowerCase():e}}function R(e,t,n){let r="",o=0;for(let n=1;n<e.length;n++)x(e,n)&&(r+=e.slice(o,n)+t,o=n);return r+=e.slice(o),n?r.toUpperCase():r.toLowerCase()}function $(e,t){const n=e.length;if(0===n)return e;let r=e.charCodeAt(0);const o=m(r);if(!o&&!U(r))return e;let s=o?1:0,c=!o,u=0,i=0,a=!1,f=r;for(let t=1;t<n;t++){if(r=e.charCodeAt(t),U(r))c=!0;else if(m(r))s++;else if(95===r)u++,95===f&&(a=!0);else if(45===r)i++,45===f&&(a=!0);else if(!C(r))return e;f=r}if(95===f||45===f)return e;if(0===u&&0===i){if(0===s||1===s&&o)return _(e,t);if(!o)switch(t){case"snake":return R(e,"_",!1);case"kebab":return R(e,"-",!1);case"pascal":return e[0].toUpperCase()+e.slice(1);case"constant":return R(e,"_",!0);default:return e}if(!c)return e;switch(t){case"snake":return R(e,"_",!1);case"kebab":return R(e,"-",!1);case"camel":return O(e);case"constant":return R(e,"_",!0);default:return e}}if(s>0||a||u>0&&i>0)return e;if(u>0)switch(t){case"camel":return A(e,"_",!1);case"pascal":return A(e,"_",!0);case"kebab":return M(e,"_","-");case"constant":return e.toUpperCase();default:return e}if(k(e))return e;switch(t){case"camel":return A(e,"-",!1);case"pascal":return A(e,"-",!0);case"snake":return M(e,"-","_");case"constant":return M(e,"-","_").toUpperCase();default:return e}}const S=new Map;let E,T={current:new Map,previous:new Map},N=0;function K(e,t){if(e.length>100)return $(e,t);if(t!==E){let e=S.get(t);e||(e={current:new Map,previous:new Map},S.set(t,e)),E=t,T=e}const n=T;let r=n.current.get(e);if(void 0!==r)return N=0,r;if(r=n.previous.get(e),void 0===r){if(r=$(e,t),++N>256&&N%8!=0)return r}else N=0;return n.current.size>=1e3&&(n.previous=n.current,n.current=new Map),n.current.set(e,r),r}const L={reason:"nesting limit reached"};function P(e,t,n=[],r=0,o=0){var s;if(null===e||"object"!=typeof e)return e;if(r>=t.depth)return e;const c=t.depth===1/0?0:r,u=t.keepReferences;if(u){const t=b(null!==(s=n[c])&&void 0!==s?s:n[c]=new Map,e);if(void 0!==t)return t}else if(o>=256)throw L;if(Array.isArray(e)){const s=[];return u&&v(n,c,e,s),B(e,s,t,n,r,o),s}const i=r+1,a=p(e);if(d(e,a)){const r=new Map;return u&&v(n,c,e,r),null===t.exclude?z(e,r,t,n,i,o):q(e,r,t.exclude,i,o),r}if(h(e,a)){const r=new Set;return u&&v(n,c,e,r),J(e,r,t,n,i,o),r}if(a===l){const r=e,s={};if(u&&v(n,c,e,s),null===t.exclude){for(const e in r)if(Object.prototype.hasOwnProperty.call(r,e)){const c=K(e,t.targetCase),u=r[e];if("object"!=typeof u||null===u){y(s,c,u);continue}y(s,c,P(u,t,n,i,o+1))}}else I(r,s,t.exclude,i,o);for(const e of Object.getOwnPropertySymbols(r))Object.prototype.propertyIsEnumerable.call(r,e)&&(s[e]=r[e]);return s}return e}function B(e,t,n,r,o,s){for(const c of e)"object"==typeof c&&null!==c?t.push(P(c,n,r,o,s+1)):t.push(c)}function z(e,t,n,r,o,s){for(const[c,u]of e)t.set("string"==typeof c?$(c,n.targetCase):c,P(u,n,r,o,s+1))}function J(e,t,n,r,o,s){for(const c of e)t.add(P(c,n,r,o,s+1))}function I(e,t,n,r,o){for(const s in e)if(Object.prototype.hasOwnProperty.call(e,s)){const c=a(n,s),u=f(n,c);y(t,c.keepKey?s:K(s,n.options.targetCase),P(e[s],u.options,u.visitedRefs,r,o+1))}}function q(e,t,n,r,o){for(const[s,c]of e){const e=a(n,s),u=f(n,e);t.set("string"!=typeof s||e.keepKey?s:$(s,n.options.targetCase),P(c,u.options,u.visitedRefs,r,o+1))}}const D=["camel","snake","pascal","kebab","constant"];function F(e){return D.includes(e)}function G(e){if("string"!=typeof e)return;const n=t(e);throw new TypeError(F(e)?`Unsupported options ${n}. Use an options object: { targetCase: ${n} }.`:`Unsupported options ${n}. Use an options object, such as { targetCase: "snake" }. To pass the function as a callback, wrap it so that it gets only its first argument.`)}function H(e){const n=e||"camel";if(!F(n))throw new TypeError(`Unsupported targetCase ${t(n)}. Use one of: ${D.join(", ")}.`);return n}function Q(e,t,n){const r=void 0===n?null:i(n,t);return null===r?P(e,t):P(e,r.options,r.visitedRefs)}exports.transform=function(e,n){var r,o;G(n);const s=null==n?void 0:n.targetCase,c=null!==(r=null==n?void 0:n.depth)&&void 0!==r?r:1/0,u=H(s);if("number"!=typeof c||Number.isNaN(c))throw new TypeError(`Unsupported depth ${t(c)}. Use a number, or omit depth to transform every level.`);const i=null==n?void 0:n.exclude,a=null===(o=null==n?void 0:n.keepReferences)||void 0===o||o;if("boolean"!=typeof a)throw new TypeError(`Unsupported keepReferences ${t(a)}. Use true or false.`);if(!a)try{return Q(e,{targetCase:u,depth:c,keepReferences:a,exclude:null},i)}catch(e){if(e!==L)throw e}return Q(e,{targetCase:u,depth:c,keepReferences:!0,exclude:null},i)},exports.transformKey=function(e,n){if("string"!=typeof e)throw new TypeError(`Unsupported key ${t(e)}. Use a string.`);return G(n),$(e,H(null==n?void 0:n.targetCase))};
|
|
1
|
+
"use strict";const e={},t={reason:"nesting limit reached"};function n(e){return{done:!1,replaced:!1,seenWidths:[],seenKeys:[],seenResults:[],nextSeen:0,seenAgain:[],fastWidths:[],fastKeys:[],fastObjects:[],fastKeyLists:[],checked:[],checks:[],toForget:e,listed:!1}}function r(e,t){const r=JSON.stringify(t);let o=e.byPaths.get(r);return o||(o=n(e.toForget),e.byPaths.set(r,o)),o}function o(e){return 1===e.length?e:[...new Set(e)].sort()}const s=[];function c(e){let t,n=!1;for(const r of e)void 0===r?n=!0:(null!=t?t:t=[]).push(r);return{keepKey:n,pathsBelow:t?o(t):s,scope:void 0}}function u(e){const t=e.indexOf(".");return-1===t?[e]:[e.slice(0,t),e.slice(t+1)]}function i(e,t){const n=[];let o;for(const t of e){const[e,r]=u(t);if("*"===e)n.push(r);else{null!=o||(o=new Map);const t=o.get(e);t?t.push(r):o.set(e,[r])}}const s=new Map;for(const[e,t]of null!=o?o:[])s.set(e,c(n.length?[...t,...n]:t));const{targetCase:i,depth:l,keepReferences:a}=t.plain.options,f={targetCase:i,depth:l,keepReferences:a,exclude:null,layouts:null===t.store?null:r(t.store,e)},p={options:f,visitedRefs:[],named:s,other:c(n),root:t};return f.exclude=p,p}function l(e,t,n){return i(e,{plain:{options:t,visitedRefs:[]},states:new Map,store:n})}const a={},f="[object Object]";function p(e){try{return Object.prototype.toString.call(e)}catch(e){return f}}function d(e,t){if(!(e instanceof Map)&&"[object Map]"!==t)return!1;try{return Map.prototype.has.call(e,void 0),!0}catch(e){return!1}}function h(e,t){if(!(e instanceof Set)&&"[object Set]"!==t)return!1;try{return Set.prototype.has.call(e,void 0),!0}catch(e){return!1}}function y(e,t,n){"__proto__"===t?Object.defineProperty(e,t,{value:n,enumerable:!0,writable:!0,configurable:!0}):e[t]=n}function g(e,t){let n=0;for(const r of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,r)&&(t[r]=e[r],n++);return n}let w=!1;function b(t,n,r,o){let s=t[n];s.size>=16e6&&(w=!0,s=t[n]=new Map([[e,s]])),s.set(r,o)}function v(t,n){const r=t.get(n);if(void 0!==r||!w)return r;let o=t.get(e);for(;void 0!==o;){const t=o.get(n);if(void 0!==t)return t;o=o.get(e)}}function C(e,t){let n,r;if(Array.isArray(e)?(n=e,r="symbol"==typeof n[n.length-1]?Reflect.ownKeys(t):Object.keys(t)):(n=Object.keys(e),r=Object.keys(t)),n.length!==r.length)return!1;for(let e=0;e<n.length;e++)if(n[e]!==r[e])return!1;return!0}function k(e){const t={...e};for(const e of Reflect.ownKeys(t))t[e]=a;return t}function j(e,t,n,r){const o=e.fastWidths.length;if(null===e.toForget)e.fastObjects[o]={...t};else{const n=k(t);e.fastObjects[o]=n,e.fastKeyLists[o]=Reflect.ownKeys(n),e.checked[o]=!0,e.checks[o]=0}e.fastKeys[o]=r,e.fastWidths[o]=n,o+1===16&&(null===e.toForget?e.done=!0:e.replaced=!0)}function m(e,t,n){return e.checked[t]=!0,C(e.fastKeyLists[t],n)?(++e.checks[t]%100==0&&(e.fastObjects[t]=k(n)),!0):(e.replaced=!0,!1)}function A(e){null===e.toForget||e.listed||(e.toForget.push(e),e.listed=!0)}function U(e){const t=n(null),{seenWidths:r,seenKeys:o,seenResults:s}=e,c=s.length;for(let n=0;n<c;n++){const u=(e.nextSeen+n)%c,i=s[u];null===i||Array.isArray(i)||(t.seenWidths.push(r[u]),t.seenKeys.push(o[u]),t.seenResults.push(i),t.seenAgain.push(!1))}return t.nextSeen=t.seenWidths.length%16,t}function x(e,t,r,o){var s;if(r>200)return;let c=null!==(s=e.layouts)&&void 0!==s?s:e.layouts=n(null);if(c.replaced&&(c=e.layouts=U(c)),c.done)return;A(c);const{fastWidths:u,fastKeys:i}=c;for(let n=0;n<u.length;n++)if(u[n]===r&&i[n]===o)return void(null===c.toForget||c.checked[n]||m(c,n,t)||x(e,t,r,o));const{seenWidths:l,seenKeys:a,seenResults:f}=c;for(let n=0;n<l.length;n++){if(l[n]!==r||a[n]!==o)continue;const s=f[n];return void(null===s?(f[n]=t,c.seenAgain[n]=!0):C(s,t)?j(c,t,r,o):Array.isArray(s)?(c.replaced=!0,x(e,t,r,o)):c.done=!0)}l[c.nextSeen]=r,a[c.nextSeen]=o,f[c.nextSeen]=t,c.seenAgain[c.nextSeen]=!1,c.nextSeen=(c.nextSeen+1)%16}function O(e){return e>=48&&e<=57}function R(e){return e>=97&&e<=122}function S(e){return e>=65&&e<=90}function K(e){if(36!==e.length)return!1;for(let t=0;t<36;t++){const n=e.charCodeAt(t);if(8===t||13===t||18===t||23===t){if(45!==n)return!1}else if(!(O(n)||n>=97&&n<=102||n>=65&&n<=70))return!1}return!0}const M="s".charCodeAt(0);function T(e,t){if(!S(e.charCodeAt(t)))return!1;const n=e.charCodeAt(t-1);if(R(n)||O(n))return!0;const r=e.charCodeAt(t+1);return!(!S(n)||!R(r))&&(r!==M||R(e.charCodeAt(t+2)))}function $(e){let t=1;for(;t<e.length&&!T(e,t);)t++;return e.slice(0,t).toLowerCase()+e.slice(t)}function _(e,t,n){return e.split(t).join(n)}function E(e,t,n){let r=n?e[0].toUpperCase():e[0],o=1,s=e.indexOf(t,1);for(;-1!==s;)r+=e.slice(o,s)+e[s+1].toUpperCase(),o=s+2,s=e.indexOf(t,o);return r+e.slice(o)}function F(e,t){const n=S(e.charCodeAt(0));switch(t){case"pascal":return n?e:e[0].toUpperCase()+e.slice(1);case"camel":return n?e[0].toLowerCase()+e.slice(1):e;case"constant":return e.toUpperCase();default:return n?e.toLowerCase():e}}function P(e,t,n){let r="",o=0;for(let n=1;n<e.length;n++)T(e,n)&&(r+=e.slice(o,n)+t,o=n);return r+=e.slice(o),n?r.toUpperCase():r.toLowerCase()}function W(e,t){const n=e.length;if(0===n)return e;let r=e.charCodeAt(0);const o=S(r);if(!o&&!R(r))return e;let s=o?1:0,c=!o,u=0,i=0,l=!1,a=r;for(let t=1;t<n;t++){if(r=e.charCodeAt(t),R(r))c=!0;else if(S(r))s++;else if(95===r)u++,95===a&&(l=!0);else if(45===r)i++,45===a&&(l=!0);else if(!O(r))return e;a=r}if(95===a||45===a)return e;if(0===u&&0===i){if(0===s||1===s&&o)return F(e,t);if(!o)switch(t){case"snake":return P(e,"_",!1);case"kebab":return P(e,"-",!1);case"pascal":return e[0].toUpperCase()+e.slice(1);case"constant":return P(e,"_",!0);default:return e}if(!c)return e;switch(t){case"snake":return P(e,"_",!1);case"kebab":return P(e,"-",!1);case"camel":return $(e);case"constant":return P(e,"_",!0);default:return e}}if(s>0||l||u>0&&i>0)return e;if(u>0)switch(t){case"camel":return E(e,"_",!1);case"pascal":return E(e,"_",!0);case"kebab":return _(e,"_","-");case"constant":return e.toUpperCase();default:return e}if(K(e))return e;switch(t){case"camel":return E(e,"-",!1);case"pascal":return E(e,"-",!0);case"snake":return _(e,"-","_");case"constant":return _(e,"-","_").toUpperCase();default:return e}}const L=new Map;let N,B={current:new Map,previous:new Map},J=0;function z(e,t){if(e.length>100)return W(e,t);if(t!==N){let e=L.get(t);e||(e={current:new Map,previous:new Map},L.set(t,e)),N=t,B=e}const n=B;let r=n.current.get(e);if(void 0!==r)return J=0,r;if(r=n.previous.get(e),void 0===r){if(r=W(e,t),++J>256&&J%8!=0)return r}else J=0;return n.current.size>=1e3&&(n.previous=n.current,n.current=new Map),n.current.set(e,r),r}function I(e,t,n,r,o,s){for(const[c,u]of e)t.set("string"==typeof c?W(c,n.targetCase):c,Y(u,n,r,o,s+1))}function q(e,t){const n="string"==typeof t?e.named.get(t):void 0;return null!=n?n:e.other}function D(e,t){const n=JSON.stringify(e);let r=t.states.get(n);return r||(r=i(e,t),t.states.set(n,r)),r}function G(e,t){var n;return null!==(n=t.scope)&&void 0!==n?n:t.scope=0===t.pathsBelow.length?e.root.plain:D(t.pathsBelow,e.root)}function H(e,t,n,r,o){for(const[s,c]of e){const e=q(n,s),u=G(n,e);t.set("string"!=typeof s||e.keepKey?s:W(s,n.options.targetCase),Y(c,u.options,u.visitedRefs,r,o+1))}}function Q(e,t,n,r,o){let s=0,c="";for(const u in e)if(Object.prototype.hasOwnProperty.call(e,u)){const i=q(n,u),l=G(n,i);c=i.keepKey?u:z(u,n.options.targetCase),s++,y(t,c,Y(e[u],l.options,l.visitedRefs,r,o+1))}s+=g(e,t),s>=20&&x(n.options,t,s,c)}function V(e,t,n,r,o,s){for(const c of e)"object"==typeof c&&null!==c?t.push(Y(c,n,r,o,s+1)):t.push(c)}function X(e,t,n,r,o,s){for(const c of e)t.add(Y(c,n,r,o,s+1))}function Y(e,n,r=[],o=0,s=0){var c;if(null===e||"object"!=typeof e)return e;if(o>=n.depth)return e;const u=n.depth===1/0?0:o,i=n.keepReferences;if(i){const t=v(null!==(c=r[u])&&void 0!==c?c:r[u]=new Map,e);if(void 0!==t)return t}else if(s>=256)throw t;if(Array.isArray(e)){const t=[];return i&&b(r,u,e,t),V(e,t,n,r,o,s),t}const l=o+1,a=p(e);if(d(e,a)){const t=new Map;return i&&b(r,u,e,t),null===n.exclude?I(e,t,n,r,l,s):H(e,t,n.exclude,l,s),t}if(h(e,a)){const t=new Set;return i&&b(r,u,e,t),X(e,t,n,r,l,s),t}if(a===f){const t=e,o={};if(i&&b(r,u,e,o),null!==n.exclude)return Q(t,o,n.exclude,l,s),o;let c=0,a="";for(const e in t)if(Object.prototype.hasOwnProperty.call(t,e)){a=z(e,n.targetCase),c++;const u=t[e];if("object"!=typeof u||null===u){y(o,a,u);continue}y(o,a,Y(u,n,r,l,s+1))}return c+=g(t,o),c>=20&&(null===n.layouts||!n.layouts.done)&&x(n,o,c,a),o}return e}function Z(e,n,r,o,s,c){let u=o,i=c;for(;;){const o={targetCase:n,depth:r,keepReferences:u,exclude:null,layouts:null===i?null:i.plain},c=null===s?null:l(s,o,i);try{return null===c?Y(e,o):Y(e,c.options,c.visitedRefs)}catch(e){if(u||e!==t)throw e;u=!0,i=null}}}const ee=/^[^.]+(?:\.[^.]+)*$/;function te(e){if("string"==typeof e)return JSON.stringify(e);if("bigint"==typeof e)return`${e}n`;if(null===e)return"null";if("object"==typeof e||"function"==typeof e)try{return Object.prototype.toString.call(e)}catch(e){return"an object"}return String(e)}function ne(e){if(null==e)return null;if(!Array.isArray(e))throw new TypeError(`Unsupported exclude ${te(e)}. Use an array of paths, such as ["metadata.*"].`);for(const t of e)if("string"!=typeof t||!ee.test(t))throw new TypeError(`Unsupported exclude path ${te(t)}. Use non-empty keys joined with dots, such as "metadata.*".`);return 0===e.length?null:o(e)}const re=["camel","snake","pascal","kebab","constant"];function oe(e){return re.includes(e)}function se(e){if("string"!=typeof e)return;const t=te(e);throw new TypeError(oe(e)?`Unsupported options ${t}. Use an options object: { targetCase: ${t} }.`:`Unsupported options ${t}. Use an options object, such as { targetCase: "snake" }. To pass the function as a callback, wrap it so that it gets only its first argument.`)}function ce(e){const t=null!=e?e:1/0;if("number"!=typeof t||Number.isNaN(t))throw new TypeError(`Unsupported depth ${te(t)}. Use a number, or omit depth to transform every level.`);return t}function ue(e){const t=null==e||e;if("boolean"!=typeof t)throw new TypeError(`Unsupported keepReferences ${te(t)}. Use true or false.`);return t}function ie(e){const t=e||"camel";if(!oe(t))throw new TypeError(`Unsupported targetCase ${te(t)}. Use one of: ${re.join(", ")}.`);return t}function le(){const e=[];return{plain:n(e),byPaths:new Map,toForget:e}}function ae(e){let t=!1;for(const n of e){const{seenResults:e,seenAgain:r}=n;for(let t=0;t<e.length;t++){const n=e[t];null===n||Array.isArray(n)||(e[t]=r[t]?Reflect.ownKeys(n):null,r[t]=!1)}n.checked.fill(!1),n.listed=!1,(n.done||n.replaced)&&(t=!0)}return e.length=0,t}function fe(e,t){if("object"==typeof e&&null!==e)throw new TypeError(`Unsupported targetCase ${te(e)}. Pass the target case first, then the options: transformTo("snake", { depth: 1 }).`);if(null==t||"number"==typeof t)return;if("object"!=typeof t||Array.isArray(t))throw new TypeError(`Unsupported options ${te(t)}. Use an options object, such as { depth: 1 }, after the target case: transformTo("snake", { depth: 1 }).`);const{targetCase:n}=t;if(null!=n)throw new TypeError(`Unsupported option targetCase ${te(n)}. Pass the target case as the first argument of transformTo instead.`)}exports.transform=function(e,t){return se(t),Z(e,ie(null==t?void 0:t.targetCase),ce(null==t?void 0:t.depth),ue(null==t?void 0:t.keepReferences),ne(null==t?void 0:t.exclude),null)},exports.transformKey=function(e,t){if("string"!=typeof e)throw new TypeError(`Unsupported key ${te(e)}. Use a string.`);return se(t),W(e,ie(null==t?void 0:t.targetCase))},exports.transformTo=function(e,t){fe(e,t);const n=ie(e),r=ce(null==t?void 0:t.depth),o=ue(null==t?void 0:t.keepReferences),s=null==t?void 0:t.exclude,c=ne(Array.isArray(s)?[...s]:s),u=le();let i=!0,l=!1,a=!1;const f=()=>{l=!1,0!==u.toForget.length&&ae(u.toForget)&&(i=!1)};return e=>{if(!i||l)return l&&!a&&(a=!0,Promise.resolve().then(()=>{a=!1,l&&f()})),Z(e,n,r,o,c,null);l=!0;try{return Z(e,n,r,o,c,u)}finally{f()}}};
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=/^[^.]+(?:\.[^.]+)*$/;function t(e){if("string"==typeof e)return JSON.stringify(e);if("bigint"==typeof e)return`${e}n`;if(null===e)return"null";if("object"==typeof e||"function"==typeof e)try{return Object.prototype.toString.call(e)}catch(e){return"an object"}return String(e)}function n(e){const t=e.indexOf(".");return-1===t?[e]:[e.slice(0,t),e.slice(t+1)]}const r=[];function o(e){let t,n=!1;for(const r of e)void 0===r?n=!0:(null!=t?t:t=[]).push(r);return{keepKey:n,pathsBelow:t?s(t):r,scope:void 0}}function s(e){return 1===e.length?e:[...new Set(e)].sort()}function c(e,t){const r=[];let s;for(const t of e){const[e,o]=n(t);if("*"===e)r.push(o);else{null!=s||(s=new Map);const t=s.get(e);t?t.push(o):s.set(e,[o])}}const c=new Map;for(const[e,t]of null!=s?s:[])c.set(e,o(r.length?[...t,...r]:t));const{targetCase:u,depth:i,keepReferences:a}=t.plain.options,f={targetCase:u,depth:i,keepReferences:a,exclude:null},l={options:f,visitedRefs:[],named:c,other:o(r),root:t};return f.exclude=l,l}function u(e,t){const n=JSON.stringify(e);let r=t.states.get(n);return r||(r=c(e,t),t.states.set(n,r)),r}function i(n,r){if(null==n)return null;if(!Array.isArray(n))throw new TypeError(`Unsupported exclude ${t(n)}. Use an array of paths, such as ["metadata.*"].`);for(const r of n)if("string"!=typeof r||!e.test(r))throw new TypeError(`Unsupported exclude path ${t(r)}. Use non-empty keys joined with dots, such as "metadata.*".`);if(0===n.length)return null;const o={plain:{options:r,visitedRefs:[]},states:new Map};return c(s(n),o)}function a(e,t){const n="string"==typeof t?e.named.get(t):void 0;return null!=n?n:e.other}function f(e,t){var n;return null!==(n=t.scope)&&void 0!==n?n:t.scope=0===t.pathsBelow.length?e.root.plain:u(t.pathsBelow,e.root)}const l="[object Object]";function p(e){try{return Object.prototype.toString.call(e)}catch(e){return l}}function d(e,t){if(!(e instanceof Map)&&"[object Map]"!==t)return!1;try{return Map.prototype.has.call(e,void 0),!0}catch(e){return!1}}function h(e,t){if(!(e instanceof Set)&&"[object Set]"!==t)return!1;try{return Set.prototype.has.call(e,void 0),!0}catch(e){return!1}}function y(e,t,n){"__proto__"===t?Object.defineProperty(e,t,{value:n,enumerable:!0,writable:!0,configurable:!0}):e[t]=n}const g={};let w=!1;function b(e,t){const n=e.get(t);if(void 0!==n||!w)return n;let r=e.get(g);for(;void 0!==r;){const e=r.get(t);if(void 0!==e)return e;r=r.get(g)}}function v(e,t,n,r){let o=e[t];o.size>=16e6&&(w=!0,o=e[t]=new Map([[g,o]])),o.set(n,r)}function C(e){return e>=48&&e<=57}function U(e){return e>=97&&e<=122}function k(e){return e>=65&&e<=90}function j(e){if(36!==e.length)return!1;for(let t=0;t<36;t++){const n=e.charCodeAt(t);if(8===t||13===t||18===t||23===t){if(45!==n)return!1}else if(!(C(n)||n>=97&&n<=102||n>=65&&n<=70))return!1}return!0}const m="s".charCodeAt(0);function O(e,t){if(!k(e.charCodeAt(t)))return!1;const n=e.charCodeAt(t-1);if(U(n)||C(n))return!0;const r=e.charCodeAt(t+1);return!(!k(n)||!U(r))&&(r!==m||U(e.charCodeAt(t+2)))}function x(e){let t=1;for(;t<e.length&&!O(e,t);)t++;return e.slice(0,t).toLowerCase()+e.slice(t)}function M(e,t,n){return e.split(t).join(n)}function A(e,t,n){let r=n?e[0].toUpperCase():e[0],o=1,s=e.indexOf(t,1);for(;-1!==s;)r+=e.slice(o,s)+e[s+1].toUpperCase(),o=s+2,s=e.indexOf(t,o);return r+e.slice(o)}function _(e,t){const n=k(e.charCodeAt(0));switch(t){case"pascal":return n?e:e[0].toUpperCase()+e.slice(1);case"camel":return n?e[0].toLowerCase()+e.slice(1):e;case"constant":return e.toUpperCase();default:return n?e.toLowerCase():e}}function R(e,t,n){let r="",o=0;for(let n=1;n<e.length;n++)O(e,n)&&(r+=e.slice(o,n)+t,o=n);return r+=e.slice(o),n?r.toUpperCase():r.toLowerCase()}function $(e,t){const n=e.length;if(0===n)return e;let r=e.charCodeAt(0);const o=k(r);if(!o&&!U(r))return e;let s=o?1:0,c=!o,u=0,i=0,a=!1,f=r;for(let t=1;t<n;t++){if(r=e.charCodeAt(t),U(r))c=!0;else if(k(r))s++;else if(95===r)u++,95===f&&(a=!0);else if(45===r)i++,45===f&&(a=!0);else if(!C(r))return e;f=r}if(95===f||45===f)return e;if(0===u&&0===i){if(0===s||1===s&&o)return _(e,t);if(!o)switch(t){case"snake":return R(e,"_",!1);case"kebab":return R(e,"-",!1);case"pascal":return e[0].toUpperCase()+e.slice(1);case"constant":return R(e,"_",!0);default:return e}if(!c)return e;switch(t){case"snake":return R(e,"_",!1);case"kebab":return R(e,"-",!1);case"camel":return x(e);case"constant":return R(e,"_",!0);default:return e}}if(s>0||a||u>0&&i>0)return e;if(u>0)switch(t){case"camel":return A(e,"_",!1);case"pascal":return A(e,"_",!0);case"kebab":return M(e,"_","-");case"constant":return e.toUpperCase();default:return e}if(j(e))return e;switch(t){case"camel":return A(e,"-",!1);case"pascal":return A(e,"-",!0);case"snake":return M(e,"-","_");case"constant":return M(e,"-","_").toUpperCase();default:return e}}const S=new Map;let E,T={current:new Map,previous:new Map},N=0;function L(e,t){if(e.length>100)return $(e,t);if(t!==E){let e=S.get(t);e||(e={current:new Map,previous:new Map},S.set(t,e)),E=t,T=e}const n=T;let r=n.current.get(e);if(void 0!==r)return N=0,r;if(r=n.previous.get(e),void 0===r){if(r=$(e,t),++N>256&&N%8!=0)return r}else N=0;return n.current.size>=1e3&&(n.previous=n.current,n.current=new Map),n.current.set(e,r),r}const P={reason:"nesting limit reached"};function B(e,t,n=[],r=0,o=0){var s;if(null===e||"object"!=typeof e)return e;if(r>=t.depth)return e;const c=t.depth===1/0?0:r,u=t.keepReferences;if(u){const t=b(null!==(s=n[c])&&void 0!==s?s:n[c]=new Map,e);if(void 0!==t)return t}else if(o>=256)throw P;if(Array.isArray(e)){const s=[];return u&&v(n,c,e,s),K(e,s,t,n,r,o),s}const i=r+1,a=p(e);if(d(e,a)){const r=new Map;return u&&v(n,c,e,r),null===t.exclude?z(e,r,t,n,i,o):q(e,r,t.exclude,i,o),r}if(h(e,a)){const r=new Set;return u&&v(n,c,e,r),J(e,r,t,n,i,o),r}if(a===l){const r=e,s={};if(u&&v(n,c,e,s),null===t.exclude){for(const e in r)if(Object.prototype.hasOwnProperty.call(r,e)){const c=L(e,t.targetCase),u=r[e];if("object"!=typeof u||null===u){y(s,c,u);continue}y(s,c,B(u,t,n,i,o+1))}}else I(r,s,t.exclude,i,o);for(const e of Object.getOwnPropertySymbols(r))Object.prototype.propertyIsEnumerable.call(r,e)&&(s[e]=r[e]);return s}return e}function K(e,t,n,r,o,s){for(const c of e)"object"==typeof c&&null!==c?t.push(B(c,n,r,o,s+1)):t.push(c)}function z(e,t,n,r,o,s){for(const[c,u]of e)t.set("string"==typeof c?$(c,n.targetCase):c,B(u,n,r,o,s+1))}function J(e,t,n,r,o,s){for(const c of e)t.add(B(c,n,r,o,s+1))}function I(e,t,n,r,o){for(const s in e)if(Object.prototype.hasOwnProperty.call(e,s)){const c=a(n,s),u=f(n,c);y(t,c.keepKey?s:L(s,n.options.targetCase),B(e[s],u.options,u.visitedRefs,r,o+1))}}function q(e,t,n,r,o){for(const[s,c]of e){const e=a(n,s),u=f(n,e);t.set("string"!=typeof s||e.keepKey?s:$(s,n.options.targetCase),B(c,u.options,u.visitedRefs,r,o+1))}}const D=["camel","snake","pascal","kebab","constant"];function F(e){return D.includes(e)}function G(e){if("string"!=typeof e)return;const n=t(e);throw new TypeError(F(e)?`Unsupported options ${n}. Use an options object: { targetCase: ${n} }.`:`Unsupported options ${n}. Use an options object, such as { targetCase: "snake" }. To pass the function as a callback, wrap it so that it gets only its first argument.`)}function H(e){const n=e||"camel";if(!F(n))throw new TypeError(`Unsupported targetCase ${t(n)}. Use one of: ${D.join(", ")}.`);return n}function Q(e,n){var r,o;G(n);const s=null==n?void 0:n.targetCase,c=null!==(r=null==n?void 0:n.depth)&&void 0!==r?r:1/0,u=H(s);if("number"!=typeof c||Number.isNaN(c))throw new TypeError(`Unsupported depth ${t(c)}. Use a number, or omit depth to transform every level.`);const i=null==n?void 0:n.exclude,a=null===(o=null==n?void 0:n.keepReferences)||void 0===o||o;if("boolean"!=typeof a)throw new TypeError(`Unsupported keepReferences ${t(a)}. Use true or false.`);if(!a)try{return V(e,{targetCase:u,depth:c,keepReferences:a,exclude:null},i)}catch(e){if(e!==P)throw e}return V(e,{targetCase:u,depth:c,keepReferences:!0,exclude:null},i)}function V(e,t,n){const r=void 0===n?null:i(n,t);return null===r?B(e,t):B(e,r.options,r.visitedRefs)}function W(e,n){if("string"!=typeof e)throw new TypeError(`Unsupported key ${t(e)}. Use a string.`);return G(n),$(e,H(null==n?void 0:n.targetCase))}export{Q as transform,W as transformKey};
|
|
1
|
+
const e={},t={reason:"nesting limit reached"};function n(e){return{done:!1,replaced:!1,seenWidths:[],seenKeys:[],seenResults:[],nextSeen:0,seenAgain:[],fastWidths:[],fastKeys:[],fastObjects:[],fastKeyLists:[],checked:[],checks:[],toForget:e,listed:!1}}function r(e,t){const r=JSON.stringify(t);let o=e.byPaths.get(r);return o||(o=n(e.toForget),e.byPaths.set(r,o)),o}function o(e){return 1===e.length?e:[...new Set(e)].sort()}const s=[];function c(e){let t,n=!1;for(const r of e)void 0===r?n=!0:(null!=t?t:t=[]).push(r);return{keepKey:n,pathsBelow:t?o(t):s,scope:void 0}}function u(e){const t=e.indexOf(".");return-1===t?[e]:[e.slice(0,t),e.slice(t+1)]}function i(e,t){const n=[];let o;for(const t of e){const[e,r]=u(t);if("*"===e)n.push(r);else{null!=o||(o=new Map);const t=o.get(e);t?t.push(r):o.set(e,[r])}}const s=new Map;for(const[e,t]of null!=o?o:[])s.set(e,c(n.length?[...t,...n]:t));const{targetCase:i,depth:l,keepReferences:a}=t.plain.options,f={targetCase:i,depth:l,keepReferences:a,exclude:null,layouts:null===t.store?null:r(t.store,e)},p={options:f,visitedRefs:[],named:s,other:c(n),root:t};return f.exclude=p,p}function l(e,t,n){return i(e,{plain:{options:t,visitedRefs:[]},states:new Map,store:n})}const a={},f="[object Object]";function p(e){try{return Object.prototype.toString.call(e)}catch(e){return f}}function d(e,t){if(!(e instanceof Map)&&"[object Map]"!==t)return!1;try{return Map.prototype.has.call(e,void 0),!0}catch(e){return!1}}function h(e,t){if(!(e instanceof Set)&&"[object Set]"!==t)return!1;try{return Set.prototype.has.call(e,void 0),!0}catch(e){return!1}}function y(e,t,n){"__proto__"===t?Object.defineProperty(e,t,{value:n,enumerable:!0,writable:!0,configurable:!0}):e[t]=n}function g(e,t){let n=0;for(const r of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,r)&&(t[r]=e[r],n++);return n}let w=!1;function b(t,n,r,o){let s=t[n];s.size>=16e6&&(w=!0,s=t[n]=new Map([[e,s]])),s.set(r,o)}function v(t,n){const r=t.get(n);if(void 0!==r||!w)return r;let o=t.get(e);for(;void 0!==o;){const t=o.get(n);if(void 0!==t)return t;o=o.get(e)}}function C(e,t){let n,r;if(Array.isArray(e)?(n=e,r="symbol"==typeof n[n.length-1]?Reflect.ownKeys(t):Object.keys(t)):(n=Object.keys(e),r=Object.keys(t)),n.length!==r.length)return!1;for(let e=0;e<n.length;e++)if(n[e]!==r[e])return!1;return!0}function k(e){const t={...e};for(const e of Reflect.ownKeys(t))t[e]=a;return t}function j(e,t,n,r){const o=e.fastWidths.length;if(null===e.toForget)e.fastObjects[o]={...t};else{const n=k(t);e.fastObjects[o]=n,e.fastKeyLists[o]=Reflect.ownKeys(n),e.checked[o]=!0,e.checks[o]=0}e.fastKeys[o]=r,e.fastWidths[o]=n,o+1===16&&(null===e.toForget?e.done=!0:e.replaced=!0)}function A(e,t,n){return e.checked[t]=!0,C(e.fastKeyLists[t],n)?(++e.checks[t]%100==0&&(e.fastObjects[t]=k(n)),!0):(e.replaced=!0,!1)}function m(e){null===e.toForget||e.listed||(e.toForget.push(e),e.listed=!0)}function U(e){const t=n(null),{seenWidths:r,seenKeys:o,seenResults:s}=e,c=s.length;for(let n=0;n<c;n++){const u=(e.nextSeen+n)%c,i=s[u];null===i||Array.isArray(i)||(t.seenWidths.push(r[u]),t.seenKeys.push(o[u]),t.seenResults.push(i),t.seenAgain.push(!1))}return t.nextSeen=t.seenWidths.length%16,t}function x(e,t,r,o){var s;if(r>200)return;let c=null!==(s=e.layouts)&&void 0!==s?s:e.layouts=n(null);if(c.replaced&&(c=e.layouts=U(c)),c.done)return;m(c);const{fastWidths:u,fastKeys:i}=c;for(let n=0;n<u.length;n++)if(u[n]===r&&i[n]===o)return void(null===c.toForget||c.checked[n]||A(c,n,t)||x(e,t,r,o));const{seenWidths:l,seenKeys:a,seenResults:f}=c;for(let n=0;n<l.length;n++){if(l[n]!==r||a[n]!==o)continue;const s=f[n];return void(null===s?(f[n]=t,c.seenAgain[n]=!0):C(s,t)?j(c,t,r,o):Array.isArray(s)?(c.replaced=!0,x(e,t,r,o)):c.done=!0)}l[c.nextSeen]=r,a[c.nextSeen]=o,f[c.nextSeen]=t,c.seenAgain[c.nextSeen]=!1,c.nextSeen=(c.nextSeen+1)%16}function O(e){return e>=48&&e<=57}function R(e){return e>=97&&e<=122}function S(e){return e>=65&&e<=90}function K(e){if(36!==e.length)return!1;for(let t=0;t<36;t++){const n=e.charCodeAt(t);if(8===t||13===t||18===t||23===t){if(45!==n)return!1}else if(!(O(n)||n>=97&&n<=102||n>=65&&n<=70))return!1}return!0}const M="s".charCodeAt(0);function $(e,t){if(!S(e.charCodeAt(t)))return!1;const n=e.charCodeAt(t-1);if(R(n)||O(n))return!0;const r=e.charCodeAt(t+1);return!(!S(n)||!R(r))&&(r!==M||R(e.charCodeAt(t+2)))}function T(e){let t=1;for(;t<e.length&&!$(e,t);)t++;return e.slice(0,t).toLowerCase()+e.slice(t)}function _(e,t,n){return e.split(t).join(n)}function E(e,t,n){let r=n?e[0].toUpperCase():e[0],o=1,s=e.indexOf(t,1);for(;-1!==s;)r+=e.slice(o,s)+e[s+1].toUpperCase(),o=s+2,s=e.indexOf(t,o);return r+e.slice(o)}function F(e,t){const n=S(e.charCodeAt(0));switch(t){case"pascal":return n?e:e[0].toUpperCase()+e.slice(1);case"camel":return n?e[0].toLowerCase()+e.slice(1):e;case"constant":return e.toUpperCase();default:return n?e.toLowerCase():e}}function P(e,t,n){let r="",o=0;for(let n=1;n<e.length;n++)$(e,n)&&(r+=e.slice(o,n)+t,o=n);return r+=e.slice(o),n?r.toUpperCase():r.toLowerCase()}function W(e,t){const n=e.length;if(0===n)return e;let r=e.charCodeAt(0);const o=S(r);if(!o&&!R(r))return e;let s=o?1:0,c=!o,u=0,i=0,l=!1,a=r;for(let t=1;t<n;t++){if(r=e.charCodeAt(t),R(r))c=!0;else if(S(r))s++;else if(95===r)u++,95===a&&(l=!0);else if(45===r)i++,45===a&&(l=!0);else if(!O(r))return e;a=r}if(95===a||45===a)return e;if(0===u&&0===i){if(0===s||1===s&&o)return F(e,t);if(!o)switch(t){case"snake":return P(e,"_",!1);case"kebab":return P(e,"-",!1);case"pascal":return e[0].toUpperCase()+e.slice(1);case"constant":return P(e,"_",!0);default:return e}if(!c)return e;switch(t){case"snake":return P(e,"_",!1);case"kebab":return P(e,"-",!1);case"camel":return T(e);case"constant":return P(e,"_",!0);default:return e}}if(s>0||l||u>0&&i>0)return e;if(u>0)switch(t){case"camel":return E(e,"_",!1);case"pascal":return E(e,"_",!0);case"kebab":return _(e,"_","-");case"constant":return e.toUpperCase();default:return e}if(K(e))return e;switch(t){case"camel":return E(e,"-",!1);case"pascal":return E(e,"-",!0);case"snake":return _(e,"-","_");case"constant":return _(e,"-","_").toUpperCase();default:return e}}const L=new Map;let N,B={current:new Map,previous:new Map},J=0;function z(e,t){if(e.length>100)return W(e,t);if(t!==N){let e=L.get(t);e||(e={current:new Map,previous:new Map},L.set(t,e)),N=t,B=e}const n=B;let r=n.current.get(e);if(void 0!==r)return J=0,r;if(r=n.previous.get(e),void 0===r){if(r=W(e,t),++J>256&&J%8!=0)return r}else J=0;return n.current.size>=1e3&&(n.previous=n.current,n.current=new Map),n.current.set(e,r),r}function I(e,t,n,r,o,s){for(const[c,u]of e)t.set("string"==typeof c?W(c,n.targetCase):c,Y(u,n,r,o,s+1))}function q(e,t){const n="string"==typeof t?e.named.get(t):void 0;return null!=n?n:e.other}function D(e,t){const n=JSON.stringify(e);let r=t.states.get(n);return r||(r=i(e,t),t.states.set(n,r)),r}function G(e,t){var n;return null!==(n=t.scope)&&void 0!==n?n:t.scope=0===t.pathsBelow.length?e.root.plain:D(t.pathsBelow,e.root)}function H(e,t,n,r,o){for(const[s,c]of e){const e=q(n,s),u=G(n,e);t.set("string"!=typeof s||e.keepKey?s:W(s,n.options.targetCase),Y(c,u.options,u.visitedRefs,r,o+1))}}function Q(e,t,n,r,o){let s=0,c="";for(const u in e)if(Object.prototype.hasOwnProperty.call(e,u)){const i=q(n,u),l=G(n,i);c=i.keepKey?u:z(u,n.options.targetCase),s++,y(t,c,Y(e[u],l.options,l.visitedRefs,r,o+1))}s+=g(e,t),s>=20&&x(n.options,t,s,c)}function V(e,t,n,r,o,s){for(const c of e)"object"==typeof c&&null!==c?t.push(Y(c,n,r,o,s+1)):t.push(c)}function X(e,t,n,r,o,s){for(const c of e)t.add(Y(c,n,r,o,s+1))}function Y(e,n,r=[],o=0,s=0){var c;if(null===e||"object"!=typeof e)return e;if(o>=n.depth)return e;const u=n.depth===1/0?0:o,i=n.keepReferences;if(i){const t=v(null!==(c=r[u])&&void 0!==c?c:r[u]=new Map,e);if(void 0!==t)return t}else if(s>=256)throw t;if(Array.isArray(e)){const t=[];return i&&b(r,u,e,t),V(e,t,n,r,o,s),t}const l=o+1,a=p(e);if(d(e,a)){const t=new Map;return i&&b(r,u,e,t),null===n.exclude?I(e,t,n,r,l,s):H(e,t,n.exclude,l,s),t}if(h(e,a)){const t=new Set;return i&&b(r,u,e,t),X(e,t,n,r,l,s),t}if(a===f){const t=e,o={};if(i&&b(r,u,e,o),null!==n.exclude)return Q(t,o,n.exclude,l,s),o;let c=0,a="";for(const e in t)if(Object.prototype.hasOwnProperty.call(t,e)){a=z(e,n.targetCase),c++;const u=t[e];if("object"!=typeof u||null===u){y(o,a,u);continue}y(o,a,Y(u,n,r,l,s+1))}return c+=g(t,o),c>=20&&(null===n.layouts||!n.layouts.done)&&x(n,o,c,a),o}return e}function Z(e,n,r,o,s,c){let u=o,i=c;for(;;){const o={targetCase:n,depth:r,keepReferences:u,exclude:null,layouts:null===i?null:i.plain},c=null===s?null:l(s,o,i);try{return null===c?Y(e,o):Y(e,c.options,c.visitedRefs)}catch(e){if(u||e!==t)throw e;u=!0,i=null}}}const ee=/^[^.]+(?:\.[^.]+)*$/;function te(e){if("string"==typeof e)return JSON.stringify(e);if("bigint"==typeof e)return`${e}n`;if(null===e)return"null";if("object"==typeof e||"function"==typeof e)try{return Object.prototype.toString.call(e)}catch(e){return"an object"}return String(e)}function ne(e){if(null==e)return null;if(!Array.isArray(e))throw new TypeError(`Unsupported exclude ${te(e)}. Use an array of paths, such as ["metadata.*"].`);for(const t of e)if("string"!=typeof t||!ee.test(t))throw new TypeError(`Unsupported exclude path ${te(t)}. Use non-empty keys joined with dots, such as "metadata.*".`);return 0===e.length?null:o(e)}const re=["camel","snake","pascal","kebab","constant"];function oe(e){return re.includes(e)}function se(e){if("string"!=typeof e)return;const t=te(e);throw new TypeError(oe(e)?`Unsupported options ${t}. Use an options object: { targetCase: ${t} }.`:`Unsupported options ${t}. Use an options object, such as { targetCase: "snake" }. To pass the function as a callback, wrap it so that it gets only its first argument.`)}function ce(e){const t=null!=e?e:1/0;if("number"!=typeof t||Number.isNaN(t))throw new TypeError(`Unsupported depth ${te(t)}. Use a number, or omit depth to transform every level.`);return t}function ue(e){const t=null==e||e;if("boolean"!=typeof t)throw new TypeError(`Unsupported keepReferences ${te(t)}. Use true or false.`);return t}function ie(e){const t=e||"camel";if(!oe(t))throw new TypeError(`Unsupported targetCase ${te(t)}. Use one of: ${re.join(", ")}.`);return t}function le(e,t){return se(t),Z(e,ie(null==t?void 0:t.targetCase),ce(null==t?void 0:t.depth),ue(null==t?void 0:t.keepReferences),ne(null==t?void 0:t.exclude),null)}function ae(){const e=[];return{plain:n(e),byPaths:new Map,toForget:e}}function fe(e){let t=!1;for(const n of e){const{seenResults:e,seenAgain:r}=n;for(let t=0;t<e.length;t++){const n=e[t];null===n||Array.isArray(n)||(e[t]=r[t]?Reflect.ownKeys(n):null,r[t]=!1)}n.checked.fill(!1),n.listed=!1,(n.done||n.replaced)&&(t=!0)}return e.length=0,t}function pe(e,t){if("object"==typeof e&&null!==e)throw new TypeError(`Unsupported targetCase ${te(e)}. Pass the target case first, then the options: transformTo("snake", { depth: 1 }).`);if(null==t||"number"==typeof t)return;if("object"!=typeof t||Array.isArray(t))throw new TypeError(`Unsupported options ${te(t)}. Use an options object, such as { depth: 1 }, after the target case: transformTo("snake", { depth: 1 }).`);const{targetCase:n}=t;if(null!=n)throw new TypeError(`Unsupported option targetCase ${te(n)}. Pass the target case as the first argument of transformTo instead.`)}function de(e,t){pe(e,t);const n=ie(e),r=ce(null==t?void 0:t.depth),o=ue(null==t?void 0:t.keepReferences),s=null==t?void 0:t.exclude,c=ne(Array.isArray(s)?[...s]:s),u=ae();let i=!0,l=!1,a=!1;const f=()=>{l=!1,0!==u.toForget.length&&fe(u.toForget)&&(i=!1)};return e=>{if(!i||l)return l&&!a&&(a=!0,Promise.resolve().then(()=>{a=!1,l&&f()})),Z(e,n,r,o,c,null);l=!0;try{return Z(e,n,r,o,c,u)}finally{f()}}}function he(e,t){if("string"!=typeof e)throw new TypeError(`Unsupported key ${te(e)}. Use a string.`);return se(t),W(e,ie(null==t?void 0:t.targetCase))}export{le as transform,he as transformKey,de as transformTo};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "deep-case-crafter",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.7.0",
|
|
4
4
|
"description": "Convert object keys between camelCase and snake_case, deeply, with exact TypeScript types",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -66,13 +66,14 @@
|
|
|
66
66
|
"test-coverage": "npm test -- --coverage",
|
|
67
67
|
"test:types": "tsc --noEmit",
|
|
68
68
|
"tsc": "tsc --noEmit",
|
|
69
|
+
"test:dist-objects": "node --allow-natives-syntax dist-tests/fastObjects.mjs",
|
|
69
70
|
"test:dist-types": "tsc -p dist-type-tests && tsc -p dist-type-tests/tsconfig.declarations.json && node dist-type-tests/checkDeclarations.mjs && tsc -p dist-type-tests/tsconfig.consumer.json && tsc -p dist-type-tests/tsconfig.loose.json && tsc -p dist-type-tests/tsconfig.exact.json",
|
|
70
71
|
"lint": "eslint --ext .js,.jsx,.ts,.tsx src/ --max-warnings=0 --no-cache",
|
|
71
72
|
"lint:fix": "eslint --ext .js,.jsx,.ts,.tsx src/ --fix --max-warnings=0 --no-cache",
|
|
72
|
-
"format": "prettier --write src dist-type-tests benchmark .github readme.md CHANGELOG.md SECURITY.md",
|
|
73
|
-
"format:check": "prettier --check src dist-type-tests benchmark .github readme.md CHANGELOG.md SECURITY.md",
|
|
73
|
+
"format": "prettier --write src dist-type-tests dist-tests benchmark .github readme.md CHANGELOG.md SECURITY.md",
|
|
74
|
+
"format:check": "prettier --check src dist-type-tests dist-tests benchmark .github readme.md CHANGELOG.md SECURITY.md",
|
|
74
75
|
"benchmark": "tsx benchmark/*.benchmark.ts",
|
|
75
|
-
"check": "npm run lint && npm run format:check && npm run test:types && npm run test-coverage && npm run build && npm run test:dist-types"
|
|
76
|
+
"check": "npm run lint && npm run format:check && npm run test:types && npm run test-coverage && npm run build && npm run test:dist-types && npm run test:dist-objects"
|
|
76
77
|
},
|
|
77
78
|
"devDependencies": {
|
|
78
79
|
"@eslint/js": "10.0.1",
|
package/readme.md
CHANGED
|
@@ -35,7 +35,7 @@ const body = transform(user, { targetCase: 'snake' });
|
|
|
35
35
|
| Some keys left as they are | `transform(data, { exclude: ['users_by_id.*'] })` |
|
|
36
36
|
| The top level only | `transform(data, { depth: 1 })` |
|
|
37
37
|
| Faster conversion of `JSON.parse` output | `transform(data, { keepReferences: false })` |
|
|
38
|
-
|
|
|
38
|
+
| A callback, or options set once | `.then(transformTo('camel'))` |
|
|
39
39
|
| The result type, or a key's type | `TransformResult<typeof data, 'snake'>`, `TransformKey<'user_id'>` |
|
|
40
40
|
|
|
41
41
|
## Features
|
|
@@ -55,6 +55,9 @@ const body = transform(user, { targetCase: 'snake' });
|
|
|
55
55
|
returned untouched.
|
|
56
56
|
- **Keys that are data keep their names**: UUIDs always, and any other key whose path
|
|
57
57
|
you list in [`exclude`](#leaving-keys-unchanged), such as `'users_by_id.*'`.
|
|
58
|
+
- **Callbacks keep their types**: [`transformTo`](#transformtotargetcase-options) makes a
|
|
59
|
+
function with its options set once, which keeps the exact result type where it is
|
|
60
|
+
passed by name: `.then(transformTo('camel'))`, `items.map(transformTo('snake'))`.
|
|
58
61
|
- **Single keys too**: [`transformKey`](#transformkeykey-options) converts one key by
|
|
59
62
|
the same rules, `transformKey('userID', { targetCase: 'snake' })` → `'user_id'`, typed
|
|
60
63
|
`'user_id'`.
|
|
@@ -203,6 +206,28 @@ function toSortParam(field: SortField) {
|
|
|
203
206
|
|
|
204
207
|
---
|
|
205
208
|
|
|
209
|
+
### 8. Set the options once with `transformTo`
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
import { transformTo } from 'deep-case-crafter';
|
|
213
|
+
|
|
214
|
+
const toCamel = transformTo('camel');
|
|
215
|
+
const toPayload = transformTo('snake', { exclude: ['metadata.*'] });
|
|
216
|
+
|
|
217
|
+
const users = await fetch('/api/users')
|
|
218
|
+
.then((response) => response.json() as Promise<{ user_id: number }[]>)
|
|
219
|
+
.then(toCamel);
|
|
220
|
+
// ^? { userId: number }[]
|
|
221
|
+
|
|
222
|
+
const body = toPayload({ userId: 1, metadata: { orderRef: 'A1' } });
|
|
223
|
+
// ^? { user_id: number; metadata: { orderRef: string } }
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Passed by name, `transform` itself gets an `unknown` result type (see
|
|
227
|
+
[Passing `transform` as a callback](#passing-transform-as-a-callback)).
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
206
231
|
## How it compares
|
|
207
232
|
|
|
208
233
|
Checked in October and November 2026 against
|
|
@@ -230,7 +255,7 @@ Where the others are better or different:
|
|
|
230
255
|
|
|
231
256
|
- **Bundle size**: bundled and minified with esbuild, ts-case-convert's `objectToCamel`
|
|
232
257
|
and `objectToSnake` take about 1.1 KB gzipped, deep-case-crafter's `transform` about
|
|
233
|
-
|
|
258
|
+
3.7 KB.
|
|
234
259
|
- **CONSTANT_CASE input**: camelcase-keys, snakecase-keys and es-toolkit also read
|
|
235
260
|
SCREAMING_SNAKE_CASE keys, so `USER_ID` becomes `userId` or `user_id`.
|
|
236
261
|
deep-case-crafter converts to CONSTANT_CASE, but leaves keys such as `USER_ID` and
|
|
@@ -367,12 +392,13 @@ known as `string[]` give an `unknown` result type.
|
|
|
367
392
|
|
|
368
393
|
### Passing `transform` as a callback
|
|
369
394
|
|
|
370
|
-
|
|
371
|
-
`
|
|
372
|
-
type, because TypeScript then uses its last overload, `transform<Input, Output>`,
|
|
373
|
-
output it cannot infer, and `map` would pass each row's index as the options.
|
|
374
|
-
|
|
375
|
-
|
|
395
|
+
Use [`transformTo`](#transformtotargetcase-options): `.then(transformTo('camel'))`,
|
|
396
|
+
`items.map(transformTo('snake'))`. Passed by name, `transform` itself gets an `unknown`
|
|
397
|
+
result type, because TypeScript then uses its last overload, `transform<Input, Output>`,
|
|
398
|
+
whose output it cannot infer, and `map` would pass each row's index as the options.
|
|
399
|
+
Wrapping it in a function works as well: `rows.map((row) => transform(row))`. A callback
|
|
400
|
+
that passes a string, such as the key in lodash's `mapValues(object, transform)`, makes
|
|
401
|
+
`transform` throw a `TypeError`.
|
|
376
402
|
|
|
377
403
|
### Result types
|
|
378
404
|
|
|
@@ -394,8 +420,9 @@ type of the `exclude` paths, such as `['metadata.*']`.
|
|
|
394
420
|
(without `sourceCase`), and options passed with only the input type given
|
|
395
421
|
(`transform<Data>(data, options)`). Leave the type arguments out to get the precise
|
|
396
422
|
type.
|
|
397
|
-
- When a library exports a value or function built on `transform` or
|
|
398
|
-
annotate its result with `TransformResult<...>` or
|
|
423
|
+
- When a library exports a value or function built on `transform`, `transformKey` or a
|
|
424
|
+
function made by `transformTo`, annotate its result with `TransformResult<...>` or
|
|
425
|
+
`TransformKey<...>`. Otherwise the
|
|
399
426
|
result type is written out into its declaration files. For data of a fixed type,
|
|
400
427
|
recursive types (trees, JSON values) are then cut off as `any`, and very large types or
|
|
401
428
|
symbol-keyed members fail to compile (TS7056, TS4118). For a target case typed
|
|
@@ -403,7 +430,8 @@ type of the `exclude` paths, such as `['metadata.*']`.
|
|
|
403
430
|
when the library was built, not cases added later. A generic target case, as in
|
|
404
431
|
`<C extends StringCase>(targetCase: C)`, is not affected. Leave its result type
|
|
405
432
|
inferred: `TransformResult<T, C>` and `TransformKey<K, C>` do not match it, and its
|
|
406
|
-
declarations refer to the types by name.
|
|
433
|
+
declarations refer to the types by name. A function made by `transformTo` itself needs
|
|
434
|
+
no annotation: it is declared as `TransformTo<...>`.
|
|
407
435
|
- Some values cannot be told apart by their types. `Error`, `URL`, boxed primitives,
|
|
408
436
|
iterators, module namespace objects and other built-ins whose types do not declare a
|
|
409
437
|
`Symbol.toStringTag` are returned untouched, but typed as plain objects with
|
|
@@ -414,6 +442,54 @@ type of the `exclude` paths, such as `['metadata.*']`.
|
|
|
414
442
|
untouched when it has a `Symbol.toStringTag` (as every class implementing `Map` or
|
|
415
443
|
`Set` does), and rebuilt as a plain object otherwise.
|
|
416
444
|
|
|
445
|
+
### `transformTo(targetCase, options)`
|
|
446
|
+
|
|
447
|
+
Makes a function that transforms the keys of its argument as
|
|
448
|
+
`transform(data, { targetCase, ...options })` does, typed as `transform` types that call.
|
|
449
|
+
|
|
450
|
+
- **targetCase**: as for `transform` (`undefined` means `'camel'`).
|
|
451
|
+
- **options** (optional): `depth`, `exclude` and `keepReferences`, as for `transform`.
|
|
452
|
+
The target case is the first argument: `transformTo('snake', { targetCase: 'kebab' })`
|
|
453
|
+
does not compile and throws a `TypeError`.
|
|
454
|
+
|
|
455
|
+
```typescript
|
|
456
|
+
const toShallowSnake = transformTo('snake', { depth: 1 });
|
|
457
|
+
|
|
458
|
+
toShallowSnake({ userId: 1, userInfo: { firstName: 'Ann' } });
|
|
459
|
+
// { user_id: 1, user_info: { firstName: 'Ann' } }
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
- The function uses only its first argument, so it can be passed to callbacks that pass
|
|
463
|
+
more, such as `map` (the index) or lodash's `mapValues` (the key).
|
|
464
|
+
- The options are checked when the function is made, where invalid ones throw a
|
|
465
|
+
`TypeError`, and read only then: changing the options object or the `exclude` array
|
|
466
|
+
afterwards does not change the function.
|
|
467
|
+
- Each call converts its data on its own, as a call to `transform` does: shared and
|
|
468
|
+
circular references are kept within a call.
|
|
469
|
+
- The function remembers the layouts of its results across its calls. Results of 20 to
|
|
470
|
+
200 keys are fast objects from the third one of a layout in a call (see
|
|
471
|
+
[3.6.0 in the changelog](https://github.com/gyrgy/deep-case-crafter/blob/main/CHANGELOG.md#360---2026-11-08)),
|
|
472
|
+
and records converted one per call, as `rows.map(toCamel)` does, from the fourth
|
|
473
|
+
call on; once the function knows a layout, from the first. Converted one per call
|
|
474
|
+
with `transform`, such records stay in dictionary mode. With Node 24, for 20,000
|
|
475
|
+
records, a third of whose values were strings, the function took 17–25% less time
|
|
476
|
+
than one call to `transform` per record at 20, 30, 50 and 100 keys, 7–10% less at
|
|
477
|
+
85 and 200 keys, and between 4% less and 3% more at 150 to 170 keys. Its results
|
|
478
|
+
took 33–40% less memory and read 2.4 to 4.4 times as fast by property name, but 1.5
|
|
479
|
+
to 2.2 times as slowly by a computed key from a list of keys.
|
|
480
|
+
- Once a call has returned, the function keeps none of its data but keys: the keys of
|
|
481
|
+
some results, and for each layout it has learned, a copy of a result with an empty
|
|
482
|
+
object in place of every value. It checks each layout with the first result of that
|
|
483
|
+
layout in a call. Once it has learned 16 layouts (with `exclude`, 16 for one set of
|
|
484
|
+
matching paths), or results with the same number of keys and last key have other
|
|
485
|
+
keys, as records with optional keys or two kinds of records can, the rest of that call
|
|
486
|
+
and its later calls learn as calls to `transform` do.
|
|
487
|
+
- Strings are returned as they are, as `transform` returns them. To convert keys, use
|
|
488
|
+
[`transformKey`](#transformkeykey-options):
|
|
489
|
+
`keys.map((key) => transformKey(key, { targetCase: 'snake' }))`.
|
|
490
|
+
- Its type is `TransformTo<TargetCase, Options>`, and the type of its options
|
|
491
|
+
`TransformToOptions`.
|
|
492
|
+
|
|
417
493
|
### `transformKey(key, options)`
|
|
418
494
|
|
|
419
495
|
Converts a single key by the same rules as the keys of `transform`'s result.
|
|
@@ -530,16 +606,16 @@ Worth knowing:
|
|
|
530
606
|
Measured with Node 24 on an Apple M4 Pro, with Node's default stack and memory sizes:
|
|
531
607
|
|
|
532
608
|
- **Nesting depth.** The conversion is recursive. Depending on the shape, the first call
|
|
533
|
-
in a process converts 1,300 to 2,
|
|
609
|
+
in a process converts 1,300 to 2,400 levels of nesting (nested Maps the fewest, nested
|
|
534
610
|
objects the most); deeper data throws a `RangeError`. Later calls can go deeper, up to
|
|
535
|
-
about
|
|
611
|
+
about 4,800 levels, depending on the data converted before. API data nests far less,
|
|
536
612
|
but untrusted input can nest deeper (`JSON.parse` accepts millions of levels), so catch
|
|
537
613
|
the error where such input is converted.
|
|
538
614
|
- **Size.** There is no fixed limit on keys, objects or array items. The result is a full
|
|
539
615
|
copy, so the input and the result must both fit in memory: converting 1 million records
|
|
540
|
-
|
|
541
|
-
`keepReferences: false`. When memory runs out,
|
|
542
|
-
caught.
|
|
616
|
+
of 30 keys (260 MB in memory, as `JSON.parse` returns them) took 0.7 seconds and needed
|
|
617
|
+
420 MB more at its peak, and 370 MB with `keepReferences: false`. When memory runs out,
|
|
618
|
+
Node ends the process, which cannot be caught.
|
|
543
619
|
- **Long keys.** Conversion time grows linearly with a key's length: about 20 ms for a key
|
|
544
620
|
of a million characters.
|
|
545
621
|
|
|
@@ -551,8 +627,8 @@ deep-case-crafter follows [semantic versioning](https://semver.org). The v3 API
|
|
|
551
627
|
stable. Key outputs change only to fix bugs, and every change is listed in the
|
|
552
628
|
[changelog](https://github.com/gyrgy/deep-case-crafter/blob/main/CHANGELOG.md): if you
|
|
553
629
|
store converted keys, such as database columns, check it before upgrading. A minor
|
|
554
|
-
version can add an option, which `Required<TransformOptions
|
|
555
|
-
`Required<TransformKeyOptions>` then require, or a target case, which code that handles
|
|
630
|
+
version can add an option, which `Required<TransformOptions>`,
|
|
631
|
+
`Required<TransformToOptions>` and `Required<TransformKeyOptions>` then require, or a target case, which code that handles
|
|
556
632
|
every member of `StringCase` then has to handle too. It can also reject at compile time
|
|
557
633
|
options that the runtime ignores or rejects, as 3.5.0 did for a string or a number in
|
|
558
634
|
place of the options object.
|
|
@@ -570,8 +646,8 @@ in the changelog.
|
|
|
570
646
|
1. Fork the repository.
|
|
571
647
|
2. Create a new branch (`feature/my-feature`).
|
|
572
648
|
3. Commit your changes.
|
|
573
|
-
4. Run `npm run check` (lint, formatting, types, tests with coverage, build
|
|
574
|
-
published types).
|
|
649
|
+
4. Run `npm run check` (lint, formatting, types, tests with coverage, build, the
|
|
650
|
+
published types and the fast objects of the build).
|
|
575
651
|
5. Submit a pull request.
|
|
576
652
|
|
|
577
653
|
---
|