@jackens/nnn 2024.3.31 → 2024.4.7

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.
Files changed (4) hide show
  1. package/nnn.d.ts +32 -20
  2. package/nnn.js +16 -1
  3. package/package.json +3 -5
  4. package/readme.md +68 -24
package/nnn.d.ts CHANGED
@@ -1,17 +1,29 @@
1
+ /**
2
+ * A tiny helper for CSV parsing.
3
+ *
4
+ * Options:
5
+ * - `header`: flag indicating that the parsed CSV has a header row (default: `true`)
6
+ * - `separator`: field separator (default: `','`)
7
+ */
8
+ export declare const csvParse: (text: string, { header, separator }?: {
9
+ header?: boolean | undefined;
10
+ separator?: string | undefined;
11
+ }) => Partial<Array<Partial<Record<PropertyKey, string>>>> | Partial<Array<Partial<Array<string>>>>;
12
+
1
13
  /**
2
14
  * The type of arguments of the `escapeValues` and `escape` helpers.
3
15
  */
4
- export type EscapeMap = Map<any, (value?: any) => string>;
16
+ export type EscapeMap = Map<unknown, (value?: unknown) => string>;
5
17
 
6
18
  /**
7
19
  * A generic helper for escaping `values` by given `escapeMap`.
8
20
  */
9
- export declare const escapeValues: (escapeMap: EscapeMap, values: Partial<Array<any>>) => Partial<Array<string>>;
21
+ export declare const escapeValues: (escapeMap: EscapeMap, values: Partial<Array<unknown>>) => Partial<Array<string>>;
10
22
 
11
23
  /**
12
24
  * A generic helper for escaping `values` by given `escapeMap` (in *TemplateStrings* flavor).
13
25
  */
14
- export declare const escape: (escapeMap: EscapeMap, template: TemplateStringsArray, ...values: Partial<Array<any>>) => string;
26
+ export declare const escape: (escapeMap: EscapeMap, template: TemplateStringsArray, ...values: Partial<Array<unknown>>) => string;
15
27
 
16
28
  /**
17
29
  * A helper that implements typographic corrections specific to Polish typography.
@@ -21,7 +33,7 @@ export declare const fixTypography: (node: Node) => void;
21
33
  /**
22
34
  * The type of arguments of the `h` and `s` helpers.
23
35
  */
24
- export type HArgs1 = Partial<Record<PropertyKey, any>> | null | undefined | Node | string | number | HArgs;
36
+ export type HArgs1 = Partial<Record<PropertyKey, unknown>> | null | undefined | Node | string | number | HArgs;
25
37
 
26
38
  /**
27
39
  * The type of arguments of the `h` and `s` helpers.
@@ -33,7 +45,7 @@ export type HArgs = [string | Node, ...HArgs1[]];
33
45
  *
34
46
  * - The first argument of type `string` specifies the tag of the element to be created.
35
47
  * - The first argument of type `Node` specifies the element to be modified.
36
- * - All other arguments of type `Partial<Record<PropertyKey, any>>` are mappings of attributes and properties.
48
+ * - All other arguments of type `Partial<Record<PropertyKey, unknown>>` are mappings of attributes and properties.
37
49
  * Keys starting with `$` specify *properties* (without the leading `$`) to be set on the element being created or modified.
38
50
  * (Note that `$` is not a valid attribute name character.)
39
51
  * All other keys specify *attributes* to be set by `setAttribute`.
@@ -54,7 +66,7 @@ export declare const h: {
54
66
  *
55
67
  * - The first argument of type `string` specifies the tag of the element to be created.
56
68
  * - The first argument of type `Node` specifies the element to be modified.
57
- * - All other arguments of type `Partial<Record<PropertyKey, any>>` are mappings of attributes and properties.
69
+ * - All other arguments of type `Partial<Record<PropertyKey, unknown>>` are mappings of attributes and properties.
58
70
  * Keys starting with `$` specify *properties* (without the leading `$`) to be set on the element being created or modified.
59
71
  * (Note that `$` is not a valid attribute name character.)
60
72
  * All other keys specify *attributes* to be set by `setAttributeNS`.
@@ -78,21 +90,21 @@ export declare const svgUse: (id: string, ...args: Partial<Array<HArgs1>>) => SV
78
90
  /**
79
91
  * A replacement for the `in` operator (not to be confused with the `for-in` loop) that works properly.
80
92
  */
81
- export declare const has: (key: any, ref: any) => boolean;
93
+ export declare const has: (key: unknown, ref: unknown) => boolean;
82
94
 
83
95
  /**
84
96
  * A helper that checks if the given argument is of a certain type.
85
97
  */
86
98
  export declare const is: {
87
- (type: ArrayConstructor, arg: any): arg is Partial<Array<any>>;
88
- (type: BigIntConstructor, arg: any): arg is bigint;
89
- (type: BooleanConstructor, arg: any): arg is boolean;
90
- (type: NumberConstructor, arg: any): arg is number;
91
- (type: ObjectConstructor, arg: any): arg is Partial<Record<PropertyKey, any>>;
92
- (type: StringConstructor, arg: any): arg is string;
93
- (type: SymbolConstructor, arg: any): arg is symbol;
94
- (type: undefined, arg: any): arg is undefined | null;
95
- <T extends abstract new (...args: Partial<Array<any>>) => any>(type: T, arg: any): arg is InstanceType<T>;
99
+ (type: ArrayConstructor, arg: unknown): arg is Partial<Array<unknown>>;
100
+ (type: BigIntConstructor, arg: unknown): arg is bigint;
101
+ (type: BooleanConstructor, arg: unknown): arg is boolean;
102
+ (type: NumberConstructor, arg: unknown): arg is number;
103
+ (type: ObjectConstructor, arg: unknown): arg is Partial<Record<PropertyKey, unknown>>;
104
+ (type: StringConstructor, arg: unknown): arg is string;
105
+ (type: SymbolConstructor, arg: unknown): arg is symbol;
106
+ (type: undefined, arg: unknown): arg is undefined | null;
107
+ <T extends abstract new (...args: Partial<Array<any>>) => unknown>(type: T, arg: unknown): arg is InstanceType<T>;
96
108
  };
97
109
 
98
110
  /**
@@ -155,12 +167,12 @@ export declare const nanolightJs: (code: string) => HArgs1[];
155
167
  /**
156
168
  * A helper that implements TypeScript’s `Pick` utility type.
157
169
  */
158
- export declare const pick: <T extends Partial<Record<PropertyKey, any>>, K extends (keyof T)[]>(obj: Partial<Record<PropertyKey, any>>, keys: Partial<Array<any>>) => Pick<T, K[number]>;
170
+ export declare const pick: <T extends Partial<Record<PropertyKey, unknown>>, K extends (keyof T)[]>(obj: Partial<Record<PropertyKey, unknown>>, keys: Partial<Array<unknown>>) => Pick<T, K[number]>;
159
171
 
160
172
  /**
161
173
  * A helper that implements TypeScript’s `Omit` utility type.
162
174
  */
163
- export declare const omit: <T extends Partial<Record<PropertyKey, any>>, K extends (keyof T)[]>(obj: Partial<Record<PropertyKey, any>>, keys: Partial<Array<any>>) => Omit<T, K[number]>;
175
+ export declare const omit: <T extends Partial<Record<PropertyKey, unknown>>, K extends (keyof T)[]>(obj: Partial<Record<PropertyKey, unknown>>, keys: Partial<Array<unknown>>) => Omit<T, K[number]>;
164
176
 
165
177
  /**
166
178
  * A helper for choosing the correct singular and plural.
@@ -170,14 +182,14 @@ export declare const plUral: (singular: string, plural2: string, plural5: string
170
182
  /**
171
183
  * A helper that protects calls to nested properties by a `Proxy` that initializes non-existent values with an empty object.
172
184
  */
173
- export declare const pro: (ref: any) => any;
185
+ export declare const pro: (ref: unknown) => any;
174
186
 
175
187
  /**
176
188
  * A helper that provides information about the given `refs`.
177
189
  *
178
190
  * It returns an array of triples: `[«name», «prototype-name», «array-of-own-property-names»]`.
179
191
  */
180
- export declare const refsInfo: (...refs: Partial<Array<any>>) => [string, string, (string | undefined)[]][];
192
+ export declare const refsInfo: (...refs: Partial<Array<unknown>>) => [string, string, (string | undefined)[]][];
181
193
 
182
194
  /**
183
195
  * A helper that generates a UUID v1 identifier (with a creation timestamp).
package/nnn.js CHANGED
@@ -1,3 +1,17 @@
1
+ // src/nnn/csvParse.ts
2
+ var csvParse = (text, { header = true, separator = "," } = {}) => {
3
+ const regExp = new RegExp(`${separator}|(?<!")\\s*"((?:[^"]|"")*)"\\s*(?!")`, "g");
4
+ const rows = text.replace(/\r/g, "").replace(/\n+$/, "").replace(/\n|(?<!")("(?:[^"]|"")*")(?!")/g, (_, chunk) => chunk ?? "\r").split("\r").map((line) => line.replace(regExp, (_, chunk) => chunk == null ? "\r" : chunk.replace(/""/g, '"')).split("\r"));
5
+ if (header) {
6
+ const keys = rows.shift();
7
+ return rows.map((row) => keys.reduce((record, key, index) => {
8
+ record[key] = row[index];
9
+ return record;
10
+ }, {}));
11
+ }
12
+ return rows;
13
+ };
14
+
1
15
  // src/nnn/escape.ts
2
16
  var escapeValues = (escapeMap, values) => values.map((value) => (escapeMap.get(value?.constructor) ?? escapeMap.get(undefined))?.(value) ?? "");
3
17
  var escape = (escapeMap, template, ...values) => String.raw(template, ...escapeValues(escapeMap, values));
@@ -272,5 +286,6 @@ export {
272
286
  h,
273
287
  fixTypography,
274
288
  escapeValues,
275
- escape
289
+ escape,
290
+ csvParse
276
291
  };
package/package.json CHANGED
@@ -4,13 +4,11 @@
4
4
  "homepage": "https://jackens.github.io/nnn/doc/",
5
5
  "keywords": [
6
6
  "CSS-in-JS",
7
- "deepEqual",
7
+ "CSV",
8
+ "csvParse",
8
9
  "DOM",
9
- "eq",
10
- "equal",
11
10
  "escape",
12
11
  "Gantt",
13
- "graph",
14
12
  "h",
15
13
  "has",
16
14
  "highlight",
@@ -40,5 +38,5 @@
40
38
  "types": "nnn.d.ts",
41
39
  "name": "@jackens/nnn",
42
40
  "type": "module",
43
- "version": "2024.3.31"
41
+ "version": "2024.4.7"
44
42
  }
package/readme.md CHANGED
@@ -2,12 +2,12 @@
2
2
 
3
3
  Jackens’ JavaScript helpers.
4
4
 
5
- <sub>Version: <code class="version">2024.3.31</code></sub>
5
+ <sub>Version: <code class="version">2024.4.7</code></sub>
6
6
 
7
7
  ## Examples
8
8
 
9
- - [Chessboard Demo](https://jackens.github.io/nnn/chessboard/)
10
9
  - [Documentation](https://jackens.github.io/nnn/doc/)
10
+ - [Chessboard Demo](https://jackens.github.io/nnn/chessboard/)
11
11
  - [Gant Chart Demo](https://jackens.github.io/nnn/gantt/)
12
12
  - [Responsive Web Design Demo](https://jackens.github.io/nnn/rwd/)
13
13
 
@@ -44,6 +44,7 @@ import { «something» } from './node_modules/@jackens/nnn/nnn.js'
44
44
  - `HArgs1`: The type of arguments of the `h` and `s` helpers.
45
45
  - `JcNode`: The type of arguments of the `jc` helper.
46
46
  - `JcRoot`: The type of arguments of the `jc` helper.
47
+ - `csvParse`: A tiny helper for CSV parsing.
47
48
  - `escape`: A generic helper for escaping `values` by given `escapeMap` (in *TemplateStrings* flavor).
48
49
  - `escapeValues`: A generic helper for escaping `values` by given `escapeMap`.
49
50
  - `fixTypography`: A helper that implements typographic corrections specific to Polish typography.
@@ -67,7 +68,7 @@ import { «something» } from './node_modules/@jackens/nnn/nnn.js'
67
68
  ### EscapeMap
68
69
 
69
70
  ```ts
70
- type EscapeMap = Map<any, (value?: any) => string>;
71
+ type EscapeMap = Map<unknown, (value?: unknown) => string>;
71
72
  ```
72
73
 
73
74
  The type of arguments of the `escapeValues` and `escape` helpers.
@@ -83,7 +84,7 @@ The type of arguments of the `h` and `s` helpers.
83
84
  ### HArgs1
84
85
 
85
86
  ```ts
86
- type HArgs1 = Partial<Record<PropertyKey, any>> | null | undefined | Node | string | number | HArgs;
87
+ type HArgs1 = Partial<Record<PropertyKey, unknown>> | null | undefined | Node | string | number | HArgs;
87
88
  ```
88
89
 
89
90
  The type of arguments of the `h` and `s` helpers.
@@ -106,10 +107,53 @@ type JcRoot = Partial<Record<PropertyKey, JcNode>>;
106
107
 
107
108
  The type of arguments of the `jc` helper.
108
109
 
110
+ ### csvParse
111
+
112
+ ```ts
113
+ const csvParse: (text: string, { header, separator }?: {
114
+ header?: boolean | undefined;
115
+ separator?: string | undefined;
116
+ }) => Partial<Array<Partial<Record<PropertyKey, string>>>> | Partial<Array<Partial<Array<string>>>>;
117
+ ```
118
+
119
+ A tiny helper for CSV parsing.
120
+
121
+ Options:
122
+ - `header`: flag indicating that the parsed CSV has a header row (default: `true`)
123
+ - `separator`: field separator (default: `','`)
124
+
125
+ #### Usage Examples
126
+
127
+ ```js
128
+ const text = `"aaa
129
+ ""aaa""
130
+ aaa",bbb, "ccc,ccc"
131
+ "xxx,xxx", "yyy
132
+ yyy",zzz
133
+ 42,"42" , 17
134
+
135
+ `
136
+ expect(csvParse(text, { header: false })).toStrictEqual([
137
+ ['aaa\n"aaa"\naaa', 'bbb', 'ccc,ccc'],
138
+ ['xxx,xxx', 'yyy\nyyy', 'zzz'],
139
+ ['42', '42', ' 17']
140
+ ])
141
+
142
+ expect(csvParse(text)).toStrictEqual([{
143
+ 'aaa\n"aaa"\naaa': 'xxx,xxx',
144
+ bbb: 'yyy\nyyy',
145
+ 'ccc,ccc': 'zzz'
146
+ }, {
147
+ 'aaa\n"aaa"\naaa': '42',
148
+ bbb: '42',
149
+ 'ccc,ccc': ' 17'
150
+ }])
151
+ ```
152
+
109
153
  ### escape
110
154
 
111
155
  ```ts
112
- const escape: (escapeMap: EscapeMap, template: TemplateStringsArray, ...values: Partial<Array<any>>) => string;
156
+ const escape: (escapeMap: EscapeMap, template: TemplateStringsArray, ...values: Partial<Array<unknown>>) => string;
113
157
  ```
114
158
 
115
159
  A generic helper for escaping `values` by given `escapeMap` (in *TemplateStrings* flavor).
@@ -119,7 +163,7 @@ A generic helper for escaping `values` by given `escapeMap` (in *TemplateStrings
119
163
  ```js
120
164
  const escapeMap: EscapeMap = new Map([
121
165
  [undefined, () => 'NULL'],
122
- [Array, (values: Partial<Array<any>>) => escapeValues(escapeMap, values).join(', ')],
166
+ [Array, (values: Partial<Array<unknown>>) => escapeValues(escapeMap, values).join(', ')],
123
167
  [Boolean, (value: boolean) => `b'${+value}'`],
124
168
  [Date, (value: Date) => `'${value.toISOString().replace(/^(.+)T(.+)\..*$/, '$1 $2')}'`],
125
169
  [Number, (value: number) => `${value}`],
@@ -144,7 +188,7 @@ expect(actual).toStrictEqual(expected)
144
188
  ### escapeValues
145
189
 
146
190
  ```ts
147
- const escapeValues: (escapeMap: EscapeMap, values: Partial<Array<any>>) => Partial<Array<string>>;
191
+ const escapeValues: (escapeMap: EscapeMap, values: Partial<Array<unknown>>) => Partial<Array<string>>;
148
192
  ```
149
193
 
150
194
  A generic helper for escaping `values` by given `escapeMap`.
@@ -183,7 +227,7 @@ A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style help
183
227
 
184
228
  - The first argument of type `string` specifies the tag of the element to be created.
185
229
  - The first argument of type `Node` specifies the element to be modified.
186
- - All other arguments of type `Partial<Record<PropertyKey, any>>` are mappings of attributes and properties.
230
+ - All other arguments of type `Partial<Record<PropertyKey, unknown>>` are mappings of attributes and properties.
187
231
  Keys starting with `$` specify *properties* (without the leading `$`) to be set on the element being created or modified.
188
232
  (Note that `$` is not a valid attribute name character.)
189
233
  All other keys specify *attributes* to be set by `setAttribute`.
@@ -264,7 +308,7 @@ expect(div.key).toStrictEqual({ one: 1, two: 2 })
264
308
  ### has
265
309
 
266
310
  ```ts
267
- const has: (key: any, ref: any) => boolean;
311
+ const has: (key: unknown, ref: unknown) => boolean;
268
312
  ```
269
313
 
270
314
  A replacement for the `in` operator (not to be confused with the `for-in` loop) that works properly.
@@ -304,15 +348,15 @@ expect(has('key', null)).toBeFalse()
304
348
 
305
349
  ```ts
306
350
  const is: {
307
- (type: ArrayConstructor, arg: any): arg is Partial<Array<any>>;
308
- (type: BigIntConstructor, arg: any): arg is bigint;
309
- (type: BooleanConstructor, arg: any): arg is boolean;
310
- (type: NumberConstructor, arg: any): arg is number;
311
- (type: ObjectConstructor, arg: any): arg is Partial<Record<PropertyKey, any>>;
312
- (type: StringConstructor, arg: any): arg is string;
313
- (type: SymbolConstructor, arg: any): arg is symbol;
314
- (type: undefined, arg: any): arg is undefined | null;
315
- <T extends abstract new (...args: Partial<Array<any>>) => any>(type: T, arg: any): arg is InstanceType<T>;
351
+ (type: ArrayConstructor, arg: unknown): arg is Partial<Array<unknown>>;
352
+ (type: BigIntConstructor, arg: unknown): arg is bigint;
353
+ (type: BooleanConstructor, arg: unknown): arg is boolean;
354
+ (type: NumberConstructor, arg: unknown): arg is number;
355
+ (type: ObjectConstructor, arg: unknown): arg is Partial<Record<PropertyKey, unknown>>;
356
+ (type: StringConstructor, arg: unknown): arg is string;
357
+ (type: SymbolConstructor, arg: unknown): arg is symbol;
358
+ (type: undefined, arg: unknown): arg is undefined | null;
359
+ <T extends abstract new (...args: Partial<Array<any>>) => unknown>(type: T, arg: unknown): arg is InstanceType<T>;
316
360
  };
317
361
  ```
318
362
 
@@ -341,7 +385,7 @@ expect(is(Map, new Map([[{ j: 42 }, { J: '42' }], [{ c: 42 }, { C: '42' }]]))).t
341
385
  ```
342
386
 
343
387
  ```js
344
- const iz = (type: any, arg: any) => ({}).toString.call(arg).slice(8, -1) === type?.name
388
+ const iz = (type: unknown, arg: unknown) => ({}).toString.call(arg).slice(8, -1) === type?.name
345
389
 
346
390
  class FooBar { }
347
391
 
@@ -719,7 +763,7 @@ expect(nanolightJs(codeJs)).toStrictEqual([
719
763
  ### omit
720
764
 
721
765
  ```ts
722
- const omit: <T extends Partial<Record<PropertyKey, any>>, K extends (keyof T)[]>(obj: Partial<Record<PropertyKey, any>>, keys: Partial<Array<any>>) => Omit<T, K[number]>;
766
+ const omit: <T extends Partial<Record<PropertyKey, unknown>>, K extends (keyof T)[]>(obj: Partial<Record<PropertyKey, unknown>>, keys: Partial<Array<unknown>>) => Omit<T, K[number]>;
723
767
  ```
724
768
 
725
769
  A helper that implements TypeScript’s `Omit` utility type.
@@ -735,7 +779,7 @@ expect(omit(obj, ['c'])).toStrictEqual({ a: 42, b: '42' })
735
779
  ### pick
736
780
 
737
781
  ```ts
738
- const pick: <T extends Partial<Record<PropertyKey, any>>, K extends (keyof T)[]>(obj: Partial<Record<PropertyKey, any>>, keys: Partial<Array<any>>) => Pick<T, K[number]>;
782
+ const pick: <T extends Partial<Record<PropertyKey, unknown>>, K extends (keyof T)[]>(obj: Partial<Record<PropertyKey, unknown>>, keys: Partial<Array<unknown>>) => Pick<T, K[number]>;
739
783
  ```
740
784
 
741
785
  A helper that implements TypeScript’s `Pick` utility type.
@@ -777,7 +821,7 @@ expect(car(42)).toStrictEqual('cars')
777
821
  ### pro
778
822
 
779
823
  ```ts
780
- const pro: (ref: any) => any;
824
+ const pro: (ref: unknown) => any;
781
825
  ```
782
826
 
783
827
  A helper that protects calls to nested properties by a `Proxy` that initializes non-existent values with an empty object.
@@ -815,7 +859,7 @@ expect(ref).toStrictEqual({ one: { two: { three: { four: 1234 } } } })
815
859
  ### refsInfo
816
860
 
817
861
  ```ts
818
- const refsInfo: (...refs: Partial<Array<any>>) => [string, string, (string | undefined)[]][];
862
+ const refsInfo: (...refs: Partial<Array<unknown>>) => [string, string, (string | undefined)[]][];
819
863
  ```
820
864
 
821
865
  A helper that provides information about the given `refs`.
@@ -869,7 +913,7 @@ A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style help
869
913
 
870
914
  - The first argument of type `string` specifies the tag of the element to be created.
871
915
  - The first argument of type `Node` specifies the element to be modified.
872
- - All other arguments of type `Partial<Record<PropertyKey, any>>` are mappings of attributes and properties.
916
+ - All other arguments of type `Partial<Record<PropertyKey, unknown>>` are mappings of attributes and properties.
873
917
  Keys starting with `$` specify *properties* (without the leading `$`) to be set on the element being created or modified.
874
918
  (Note that `$` is not a valid attribute name character.)
875
919
  All other keys specify *attributes* to be set by `setAttributeNS`.