nodenetcdf 4.9.3 → 4.9.31
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/TYPESCRIPT.md +211 -0
- package/index.d.ts +389 -0
- package/package.json +7 -3
- package/scripts/test-types.js +15 -0
- package/src/Attribute.cpp +39 -0
- package/src/Attribute.h +1 -0
- package/src/Dimension.cpp +36 -0
- package/src/Dimension.h +1 -0
- package/src/File.cpp +14 -0
- package/src/File.h +1 -0
- package/src/Group.cpp +87 -14
- package/src/Group.h +1 -0
- package/src/Variable.cpp +52 -2
- package/src/Variable.h +1 -0
- package/test/attribute.js +62 -0
- package/test/json.js +140 -0
- package/test/typescript-test.ts +87 -0
package/TYPESCRIPT.md
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# TypeScript Support
|
|
2
|
+
|
|
3
|
+
This package includes TypeScript type definitions for full IntelliSense and type safety when using the NetCDF4 library in TypeScript projects.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
The type definitions are automatically included when you install the package:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install nodenetcdf
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
### Importing
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { File, Group, Variable, Dimension, Attribute } from 'nodenetcdf';
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Type Definitions
|
|
22
|
+
|
|
23
|
+
The package exports the following types:
|
|
24
|
+
|
|
25
|
+
- **Classes**: `File`, `Group`, `Variable`, `Dimension`, `Attribute`
|
|
26
|
+
- **Type Aliases**: `NetCDFDataType`, `FileMode`, `FileFormat`, `Endianness`, `ChecksumMode`, `ChunkMode`, `FillMode`
|
|
27
|
+
|
|
28
|
+
### Example Usage
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { File, NetCDFDataType } from 'nodenetcdf';
|
|
32
|
+
|
|
33
|
+
// Create a new NetCDF file
|
|
34
|
+
const file = new File('output.nc', 'c!', 'nodenetcdf');
|
|
35
|
+
|
|
36
|
+
// Access the root group (fully typed)
|
|
37
|
+
const root = file.root;
|
|
38
|
+
|
|
39
|
+
// Add dimensions with type safety
|
|
40
|
+
const timeDim = root.addDimension('time', 0); // unlimited dimension
|
|
41
|
+
const latDim = root.addDimension('lat', 180);
|
|
42
|
+
const lonDim = root.addDimension('lon', 360);
|
|
43
|
+
|
|
44
|
+
// Add variables with proper typing
|
|
45
|
+
const tempVar = root.addVariable('temperature', 'float', [timeDim, latDim, lonDim]);
|
|
46
|
+
|
|
47
|
+
// Set variable properties with autocomplete support
|
|
48
|
+
tempVar.endianness = 'little';
|
|
49
|
+
tempVar.compressionLevel = 6;
|
|
50
|
+
tempVar.fillValue = -999.0;
|
|
51
|
+
|
|
52
|
+
// Add attributes (type-checked)
|
|
53
|
+
tempVar.addAttribute('units', 'string', 'degrees_C');
|
|
54
|
+
tempVar.addAttribute('long_name', 'string', 'Air Temperature');
|
|
55
|
+
|
|
56
|
+
// Write and read data with type safety
|
|
57
|
+
tempVar.write(data);
|
|
58
|
+
const retrievedData = tempVar.read();
|
|
59
|
+
|
|
60
|
+
// Sync and close
|
|
61
|
+
file.sync();
|
|
62
|
+
file.close();
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Available Types
|
|
66
|
+
|
|
67
|
+
### NetCDFDataType
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
type NetCDFDataType =
|
|
71
|
+
| 'byte'
|
|
72
|
+
| 'char'
|
|
73
|
+
| 'short'
|
|
74
|
+
| 'int'
|
|
75
|
+
| 'float'
|
|
76
|
+
| 'double'
|
|
77
|
+
| 'ubyte'
|
|
78
|
+
| 'ushort'
|
|
79
|
+
| 'uint'
|
|
80
|
+
| 'int64'
|
|
81
|
+
| 'string';
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### FileMode
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
type FileMode =
|
|
88
|
+
| 'r' // Read-only
|
|
89
|
+
| 'w' // Read-write
|
|
90
|
+
| 'c' // Create (no clobber)
|
|
91
|
+
| 'c!'; // Create (clobber/overwrite)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### FileFormat
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
type FileFormat =
|
|
98
|
+
| 'classic' // Classic NetCDF format
|
|
99
|
+
| 'classic64' // 64-bit offset format
|
|
100
|
+
| 'nodenetcdf' // NetCDF-4 format
|
|
101
|
+
| 'nodenetcdfclassic'; // NetCDF-4 classic model
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## API Documentation
|
|
105
|
+
|
|
106
|
+
### File Class
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
class File {
|
|
110
|
+
constructor(filename: string, mode: FileMode, format?: FileFormat);
|
|
111
|
+
readonly root: Group;
|
|
112
|
+
sync(): void;
|
|
113
|
+
close(): void;
|
|
114
|
+
inspect(): string;
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Group Class
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
class Group {
|
|
122
|
+
readonly id: number;
|
|
123
|
+
readonly variables: { [name: string]: Variable };
|
|
124
|
+
readonly dimensions: { [name: string]: Dimension };
|
|
125
|
+
readonly unlimited: Dimension | null;
|
|
126
|
+
readonly attributes: { [name: string]: Attribute };
|
|
127
|
+
readonly subgroups: { [name: string]: Group };
|
|
128
|
+
readonly name: string;
|
|
129
|
+
readonly fullname: string;
|
|
130
|
+
|
|
131
|
+
addAttribute(name: string, type: NetCDFDataType, value: any): Attribute;
|
|
132
|
+
addDimension(name: string, length: number): Dimension;
|
|
133
|
+
addSubgroup(name: string): Group;
|
|
134
|
+
addVariable(name: string, type: NetCDFDataType, dimensions: (string | Dimension)[]): Variable;
|
|
135
|
+
inspect(): string;
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Variable Class
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
class Variable {
|
|
143
|
+
readonly id: number;
|
|
144
|
+
readonly type: NetCDFDataType;
|
|
145
|
+
readonly dimensions: Dimension[];
|
|
146
|
+
readonly attributes: { [name: string]: Attribute };
|
|
147
|
+
name: string;
|
|
148
|
+
endianness: Endianness;
|
|
149
|
+
checksumMode: ChecksumMode;
|
|
150
|
+
chunkMode: ChunkMode;
|
|
151
|
+
chunkSizes: number[];
|
|
152
|
+
fillMode: FillMode;
|
|
153
|
+
fillValue: any;
|
|
154
|
+
compressionShuffle: boolean;
|
|
155
|
+
compressionDeflate: boolean;
|
|
156
|
+
compressionLevel: number;
|
|
157
|
+
|
|
158
|
+
read(): any;
|
|
159
|
+
readSlice(start: number[], count: number[]): any;
|
|
160
|
+
readStridedSlice(start: number[], count: number[], stride: number[]): any;
|
|
161
|
+
write(data: any): void;
|
|
162
|
+
writeSlice(start: number[], count: number[], data: any): void;
|
|
163
|
+
writeStridedSlice(start: number[], count: number[], stride: number[], data: any): void;
|
|
164
|
+
addAttribute(name: string, type: NetCDFDataType, value: any): Attribute;
|
|
165
|
+
inspect(): string;
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Dimension Class
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
class Dimension {
|
|
173
|
+
readonly id: number;
|
|
174
|
+
readonly length: number;
|
|
175
|
+
name: string;
|
|
176
|
+
inspect(): string;
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Attribute Class
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
class Attribute {
|
|
184
|
+
name: string;
|
|
185
|
+
value: any;
|
|
186
|
+
delete(): void;
|
|
187
|
+
inspect(): string;
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Benefits of TypeScript Support
|
|
192
|
+
|
|
193
|
+
1. **IntelliSense**: Get autocomplete suggestions for all methods and properties
|
|
194
|
+
2. **Type Safety**: Catch type errors at compile time instead of runtime
|
|
195
|
+
3. **Documentation**: Inline documentation available in your IDE
|
|
196
|
+
4. **Refactoring**: Safely rename and refactor code with confidence
|
|
197
|
+
5. **Error Prevention**: Prevent common mistakes like invalid file modes or data types
|
|
198
|
+
|
|
199
|
+
## Testing
|
|
200
|
+
|
|
201
|
+
The package includes a TypeScript test file to verify the type definitions:
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
npx tsc test/typescript-test.ts --noEmit --skipLibCheck
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
This ensures all type definitions are correct and complete.
|
|
208
|
+
|
|
209
|
+
## Contributing
|
|
210
|
+
|
|
211
|
+
If you find any issues with the type definitions or have suggestions for improvements, please open an issue on the GitHub repository.
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
// Type definitions for nodenetcdf
|
|
2
|
+
// Project: https://github.com/pheonixfirewingz/netcdf4
|
|
3
|
+
// Definitions by: Luke Shore <luke.a.shore@oliva.energy>
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* NetCDF data types
|
|
7
|
+
*/
|
|
8
|
+
export type NetCDFDataType =
|
|
9
|
+
| 'byte'
|
|
10
|
+
| 'char'
|
|
11
|
+
| 'short'
|
|
12
|
+
| 'int'
|
|
13
|
+
| 'float'
|
|
14
|
+
| 'double'
|
|
15
|
+
| 'ubyte'
|
|
16
|
+
| 'ushort'
|
|
17
|
+
| 'uint'
|
|
18
|
+
| 'int64'
|
|
19
|
+
| 'string';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* File open/create modes
|
|
23
|
+
*/
|
|
24
|
+
export type FileMode =
|
|
25
|
+
| 'r' // Read-only
|
|
26
|
+
| 'w' // Read-write
|
|
27
|
+
| 'c' // Create (no clobber)
|
|
28
|
+
| 'c!'; // Create (clobber/overwrite)
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* NetCDF file formats
|
|
32
|
+
*/
|
|
33
|
+
export type FileFormat =
|
|
34
|
+
| 'classic' // Classic NetCDF format
|
|
35
|
+
| 'classic64' // 64-bit offset format
|
|
36
|
+
| 'nodenetcdf' // NetCDF-4 format
|
|
37
|
+
| 'nodenetcdfclassic'; // NetCDF-4 classic model
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Endianness options
|
|
41
|
+
*/
|
|
42
|
+
export type Endianness = 'little' | 'big' | 'native';
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Checksum modes
|
|
46
|
+
*/
|
|
47
|
+
export type ChecksumMode = 'none' | 'fletcher32';
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Chunk modes
|
|
51
|
+
*/
|
|
52
|
+
export type ChunkMode = 'contiguous' | 'chunked';
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Fill modes
|
|
56
|
+
*/
|
|
57
|
+
export type FillMode = 'fill' | 'nofill';
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Represents a NetCDF attribute
|
|
61
|
+
*/
|
|
62
|
+
export class Attribute {
|
|
63
|
+
/**
|
|
64
|
+
* The name of the attribute
|
|
65
|
+
*/
|
|
66
|
+
name: string;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* The value of the attribute
|
|
70
|
+
*/
|
|
71
|
+
value: any;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Delete this attribute
|
|
75
|
+
*/
|
|
76
|
+
delete(): void;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Inspect the attribute
|
|
80
|
+
*/
|
|
81
|
+
inspect(): string;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Convert the attribute to a JSON-serializable object
|
|
85
|
+
*/
|
|
86
|
+
toJSON(): { name: string; value: any };
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Represents a NetCDF dimension
|
|
91
|
+
*/
|
|
92
|
+
export class Dimension {
|
|
93
|
+
/**
|
|
94
|
+
* The dimension ID
|
|
95
|
+
*/
|
|
96
|
+
readonly id: number;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* The length of the dimension
|
|
100
|
+
*/
|
|
101
|
+
readonly length: number;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* The name of the dimension
|
|
105
|
+
*/
|
|
106
|
+
name: string;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Inspect the dimension
|
|
110
|
+
*/
|
|
111
|
+
inspect(): string;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Convert the dimension to a JSON-serializable object
|
|
115
|
+
*/
|
|
116
|
+
toJSON(): { id: number; name: string; length: number };
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Represents a NetCDF variable
|
|
121
|
+
*/
|
|
122
|
+
export class Variable {
|
|
123
|
+
/**
|
|
124
|
+
* The variable ID
|
|
125
|
+
*/
|
|
126
|
+
readonly id: number;
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* The data type of the variable
|
|
130
|
+
*/
|
|
131
|
+
readonly type: NetCDFDataType;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* The dimensions of the variable
|
|
135
|
+
*/
|
|
136
|
+
readonly dimensions: Dimension[];
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* The attributes of the variable
|
|
140
|
+
*/
|
|
141
|
+
readonly attributes: { [name: string]: Attribute };
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* The name of the variable
|
|
145
|
+
*/
|
|
146
|
+
name: string;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* The endianness of the variable
|
|
150
|
+
*/
|
|
151
|
+
endianness: Endianness;
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* The checksum mode
|
|
155
|
+
*/
|
|
156
|
+
checksumMode: ChecksumMode;
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* The chunk mode
|
|
160
|
+
*/
|
|
161
|
+
chunkMode: ChunkMode;
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* The chunk sizes
|
|
165
|
+
*/
|
|
166
|
+
chunkSizes: number[];
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* The fill mode
|
|
170
|
+
*/
|
|
171
|
+
fillMode: FillMode;
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* The fill value
|
|
175
|
+
*/
|
|
176
|
+
fillValue: any;
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Whether compression shuffle is enabled
|
|
180
|
+
*/
|
|
181
|
+
compressionShuffle: boolean;
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Whether compression deflate is enabled
|
|
185
|
+
*/
|
|
186
|
+
compressionDeflate: boolean;
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* The compression level (0-9)
|
|
190
|
+
*/
|
|
191
|
+
compressionLevel: number;
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Read the entire variable
|
|
195
|
+
*/
|
|
196
|
+
read(): any;
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Read a slice of the variable
|
|
200
|
+
* @param start - Starting indices for each dimension
|
|
201
|
+
* @param count - Number of elements to read in each dimension
|
|
202
|
+
*/
|
|
203
|
+
readSlice(start: number[], count: number[]): any;
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Read a strided slice of the variable
|
|
207
|
+
* @param start - Starting indices for each dimension
|
|
208
|
+
* @param count - Number of elements to read in each dimension
|
|
209
|
+
* @param stride - Stride for each dimension
|
|
210
|
+
*/
|
|
211
|
+
readStridedSlice(start: number[], count: number[], stride: number[]): any;
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Write data to the entire variable
|
|
215
|
+
* @param data - Data to write
|
|
216
|
+
*/
|
|
217
|
+
write(data: any): void;
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Write data to a slice of the variable
|
|
221
|
+
* @param start - Starting indices for each dimension
|
|
222
|
+
* @param count - Number of elements to write in each dimension
|
|
223
|
+
* @param data - Data to write
|
|
224
|
+
*/
|
|
225
|
+
writeSlice(start: number[], count: number[], data: any): void;
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Write data to a strided slice of the variable
|
|
229
|
+
* @param start - Starting indices for each dimension
|
|
230
|
+
* @param count - Number of elements to write in each dimension
|
|
231
|
+
* @param stride - Stride for each dimension
|
|
232
|
+
* @param data - Data to write
|
|
233
|
+
*/
|
|
234
|
+
writeStridedSlice(start: number[], count: number[], stride: number[], data: any): void;
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Add an attribute to the variable
|
|
238
|
+
* @param name - Attribute name
|
|
239
|
+
* @param type - Data type
|
|
240
|
+
* @param value - Attribute value
|
|
241
|
+
*/
|
|
242
|
+
addAttribute(name: string, type: NetCDFDataType, value: any): Attribute;
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Inspect the variable
|
|
246
|
+
*/
|
|
247
|
+
inspect(): string;
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Convert the variable to a JSON-serializable object (recursively serializes dimensions and attributes)
|
|
251
|
+
*/
|
|
252
|
+
toJSON(): {
|
|
253
|
+
id: number;
|
|
254
|
+
name: string;
|
|
255
|
+
type: NetCDFDataType;
|
|
256
|
+
dimensions: Array<{ id: number; name: string; length: number }>;
|
|
257
|
+
attributes: { [name: string]: { name: string; value: any } };
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Represents a NetCDF group
|
|
263
|
+
*/
|
|
264
|
+
export class Group {
|
|
265
|
+
/**
|
|
266
|
+
* The group ID
|
|
267
|
+
*/
|
|
268
|
+
readonly id: number;
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Variables in this group
|
|
272
|
+
*/
|
|
273
|
+
readonly variables: { [name: string]: Variable };
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Dimensions in this group
|
|
277
|
+
*/
|
|
278
|
+
readonly dimensions: { [name: string]: Dimension };
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* The unlimited dimension in this group
|
|
282
|
+
*/
|
|
283
|
+
readonly unlimited: Dimension | null;
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Attributes in this group
|
|
287
|
+
*/
|
|
288
|
+
readonly attributes: { [name: string]: Attribute };
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Subgroups in this group
|
|
292
|
+
*/
|
|
293
|
+
readonly subgroups: { [name: string]: Group };
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* The name of the group
|
|
297
|
+
*/
|
|
298
|
+
readonly name: string;
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* The full name (path) of the group
|
|
302
|
+
*/
|
|
303
|
+
readonly fullname: string;
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Add an attribute to the group
|
|
307
|
+
* @param name - Attribute name
|
|
308
|
+
* @param type - Data type
|
|
309
|
+
* @param value - Attribute value
|
|
310
|
+
*/
|
|
311
|
+
addAttribute(name: string, type: NetCDFDataType, value: any): Attribute;
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Add a dimension to the group
|
|
315
|
+
* @param name - Dimension name
|
|
316
|
+
* @param length - Dimension length (0 for unlimited)
|
|
317
|
+
*/
|
|
318
|
+
addDimension(name: string, length: number): Dimension;
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Add a subgroup to the group
|
|
322
|
+
* @param name - Subgroup name
|
|
323
|
+
*/
|
|
324
|
+
addSubgroup(name: string): Group;
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Add a variable to the group
|
|
328
|
+
* @param name - Variable name
|
|
329
|
+
* @param type - Data type
|
|
330
|
+
* @param dimensions - Array of dimension names or Dimension objects
|
|
331
|
+
*/
|
|
332
|
+
addVariable(name: string, type: NetCDFDataType, dimensions: (string | Dimension)[]): Variable;
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Inspect the group
|
|
336
|
+
*/
|
|
337
|
+
inspect(): string;
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Convert the group to a JSON-serializable object (recursively serializes all children: dimensions, variables, attributes, subgroups)
|
|
341
|
+
*/
|
|
342
|
+
toJSON(): {
|
|
343
|
+
id: number;
|
|
344
|
+
name: string;
|
|
345
|
+
fullname: string;
|
|
346
|
+
dimensions: { [name: string]: { id: number; name: string; length: number } };
|
|
347
|
+
variables: { [name: string]: any };
|
|
348
|
+
attributes: { [name: string]: { name: string; value: any } };
|
|
349
|
+
subgroups: { [name: string]: any };
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Represents a NetCDF file
|
|
355
|
+
*/
|
|
356
|
+
export class File {
|
|
357
|
+
/**
|
|
358
|
+
* The root group of the file
|
|
359
|
+
*/
|
|
360
|
+
readonly root: Group;
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Open or create a NetCDF file
|
|
364
|
+
* @param filename - Path to the file
|
|
365
|
+
* @param mode - File mode ('r', 'w', 'c', 'c!')
|
|
366
|
+
* @param format - File format (optional, defaults to 'nodenetcdf')
|
|
367
|
+
*/
|
|
368
|
+
constructor(filename: string, mode: FileMode, format?: FileFormat);
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Synchronize the file to disk
|
|
372
|
+
*/
|
|
373
|
+
sync(): void;
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Close the file
|
|
377
|
+
*/
|
|
378
|
+
close(): void;
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Inspect the file
|
|
382
|
+
*/
|
|
383
|
+
inspect(): string;
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Convert the file to a JSON-serializable object (serializes the entire file structure via root group)
|
|
387
|
+
*/
|
|
388
|
+
toJSON(): any;
|
|
389
|
+
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nodenetcdf",
|
|
3
|
-
"version": "4.9.
|
|
3
|
+
"version": "4.9.31",
|
|
4
4
|
"description": "Read and write NodeNetCDF files",
|
|
5
5
|
"main": "./build/Release/nodenetcdf.node",
|
|
6
|
+
"types": "./index.d.ts",
|
|
6
7
|
"scripts": {
|
|
7
8
|
"preinstall": "node scripts/setup-vcpkg.js",
|
|
8
9
|
"install": "node scripts/verify-build-deps.js && node-gyp configure build",
|
|
9
10
|
"postinstall": "node scripts/copy-deps.js",
|
|
10
|
-
"test": "mocha",
|
|
11
|
+
"test": "npm run test:types && mocha",
|
|
12
|
+
"test:types": "node scripts/test-types.js",
|
|
11
13
|
"verify-deps": "node scripts/verify-build-deps.js"
|
|
12
14
|
},
|
|
13
15
|
"author": {
|
|
@@ -30,6 +32,8 @@
|
|
|
30
32
|
},
|
|
31
33
|
"devDependencies": {
|
|
32
34
|
"chai": "^6.2.0",
|
|
33
|
-
"mocha": "^11.7.4"
|
|
35
|
+
"mocha": "^11.7.4",
|
|
36
|
+
"typescript": "^5.7.2",
|
|
37
|
+
"@types/node": "^22.10.5"
|
|
34
38
|
}
|
|
35
39
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const { execSync } = require('child_process');
|
|
2
|
+
|
|
3
|
+
console.log('\nRunning TypeScript type checking...\n');
|
|
4
|
+
|
|
5
|
+
try {
|
|
6
|
+
execSync('tsc test/typescript-test.ts --noEmit --skipLibCheck', {
|
|
7
|
+
stdio: 'inherit',
|
|
8
|
+
cwd: process.cwd()
|
|
9
|
+
});
|
|
10
|
+
console.log('\n✅ TypeScript type checking passed!\n');
|
|
11
|
+
process.exit(0);
|
|
12
|
+
} catch (error) {
|
|
13
|
+
console.log('\n❌ TypeScript type checking failed!\n');
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
package/src/Attribute.cpp
CHANGED
|
@@ -46,6 +46,7 @@ void Attribute::Init(v8::Local<v8::Object> exports)
|
|
|
46
46
|
tpl->InstanceTemplate()->SetInternalFieldCount(1);
|
|
47
47
|
NODE_SET_PROTOTYPE_METHOD(tpl, "delete", Attribute::Delete);
|
|
48
48
|
NODE_SET_PROTOTYPE_METHOD(tpl, "inspect", Attribute::Inspect);
|
|
49
|
+
NODE_SET_PROTOTYPE_METHOD(tpl, "toJSON", Attribute::ToJSON);
|
|
49
50
|
tpl->InstanceTemplate()->SetAccessor(
|
|
50
51
|
v8::String::NewFromUtf8(isolate, "name", v8::NewStringType::kNormal).ToLocalChecked(), Attribute::GetName,
|
|
51
52
|
Attribute::SetName);
|
|
@@ -331,4 +332,42 @@ void Attribute::Inspect(const v8::FunctionCallbackInfo<v8::Value> &args)
|
|
|
331
332
|
args.GetReturnValue().Set(
|
|
332
333
|
v8::String::NewFromUtf8(isolate, "[object Attribute]", v8::NewStringType::kNormal).ToLocalChecked());
|
|
333
334
|
}
|
|
335
|
+
|
|
336
|
+
void Attribute::ToJSON(const v8::FunctionCallbackInfo<v8::Value> &args)
|
|
337
|
+
{
|
|
338
|
+
v8::Isolate *isolate = args.GetIsolate();
|
|
339
|
+
v8::Local<v8::Context> context = isolate->GetCurrentContext();
|
|
340
|
+
const auto *obj = node::ObjectWrap::Unwrap<Attribute>(args.Holder());
|
|
341
|
+
|
|
342
|
+
// Use internalized strings for better performance
|
|
343
|
+
v8::Local<v8::String> name_str = v8::String::NewFromUtf8Literal(isolate, "name");
|
|
344
|
+
v8::Local<v8::String> value_str = v8::String::NewFromUtf8Literal(isolate, "value");
|
|
345
|
+
|
|
346
|
+
v8::Local<v8::Object> json = v8::Object::New(isolate);
|
|
347
|
+
|
|
348
|
+
// Add name
|
|
349
|
+
(void)json->CreateDataProperty(context, name_str,
|
|
350
|
+
v8::String::NewFromUtf8(isolate, obj->name.c_str(), v8::NewStringType::kInternalized).ToLocalChecked());
|
|
351
|
+
|
|
352
|
+
// Add value - get from the object's value property
|
|
353
|
+
// Use a TryCatch to handle errors when getting the value
|
|
354
|
+
v8::TryCatch try_catch(isolate);
|
|
355
|
+
v8::MaybeLocal<v8::Value> maybeValue = args.Holder()->Get(context, value_str);
|
|
356
|
+
v8::Local<v8::Value> value;
|
|
357
|
+
|
|
358
|
+
if (!maybeValue.ToLocal(&value) || try_catch.HasCaught())
|
|
359
|
+
{
|
|
360
|
+
// If getting the value failed or threw an exception, clear the exception
|
|
361
|
+
// and set value to null instead of crashing
|
|
362
|
+
if (try_catch.HasCaught())
|
|
363
|
+
{
|
|
364
|
+
try_catch.Reset();
|
|
365
|
+
}
|
|
366
|
+
value = v8::Null(isolate);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
(void)json->CreateDataProperty(context, value_str, value);
|
|
370
|
+
|
|
371
|
+
args.GetReturnValue().Set(json);
|
|
372
|
+
}
|
|
334
373
|
} // namespace nodenetcdfjs
|
package/src/Attribute.h
CHANGED
|
@@ -34,6 +34,7 @@ class Attribute : public node::ObjectWrap
|
|
|
34
34
|
static void SetValue(v8::Local<v8::String> property, v8::Local<v8::Value> val,
|
|
35
35
|
const v8::PropertyCallbackInfo<void> &info);
|
|
36
36
|
static void Inspect(const v8::FunctionCallbackInfo<v8::Value> &args);
|
|
37
|
+
static void ToJSON(const v8::FunctionCallbackInfo<v8::Value> &args);
|
|
37
38
|
|
|
38
39
|
std::string name{};
|
|
39
40
|
int var_id{-1};
|