@aprestmo/norway-geodata 0.1.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.js ADDED
@@ -0,0 +1,433 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getVersion = getVersion;
7
+ exports.getMunicipalities = getMunicipalities;
8
+ exports.getMunicipalityById = getMunicipalityById;
9
+ exports.getMunicipalitiesByName = getMunicipalitiesByName;
10
+ exports.getCounties = getCounties;
11
+ exports.getCountyById = getCountyById;
12
+ exports.getCountyByName = getCountyByName;
13
+ exports.getMunicipalitiesByCounty = getMunicipalitiesByCounty;
14
+ exports.getMunicipalityByPostalCode = getMunicipalityByPostalCode;
15
+ exports.getPostalCodesByMunicipality = getPostalCodesByMunicipality;
16
+ exports.getAllPostalCodes = getAllPostalCodes;
17
+ exports.getMunicipalitiesByPopulation = getMunicipalitiesByPopulation;
18
+ exports.getMunicipalitiesByArea = getMunicipalitiesByArea;
19
+ exports.getMunicipalitiesByLanguage = getMunicipalitiesByLanguage;
20
+ exports.getMunicipalitiesFiltered = getMunicipalitiesFiltered;
21
+ exports.getTotalPopulation = getTotalPopulation;
22
+ exports.getTotalArea = getTotalArea;
23
+ exports.getPopulationDensityStats = getPopulationDensityStats;
24
+ exports.getMunicipalitiesByPopulationDensity = getMunicipalitiesByPopulationDensity;
25
+ exports.getLargestMunicipalities = getLargestMunicipalities;
26
+ exports.getSmallestMunicipalities = getSmallestMunicipalities;
27
+ exports.getPostalCodes = getPostalCodes;
28
+ exports.getPostalCodeByCode = getPostalCodeByCode;
29
+ exports.getPostalCodesByPlace = getPostalCodesByPlace;
30
+ exports.getPostalCodesByMunicipalityId = getPostalCodesByMunicipalityId;
31
+ exports.getUniquePostalPlaces = getUniquePostalPlaces;
32
+ exports.getPostalCodesInRange = getPostalCodesInRange;
33
+ exports.getPostalCodesStats = getPostalCodesStats;
34
+ exports.getPostalCodesSorted = getPostalCodesSorted;
35
+ exports.isValidPostalCode = isValidPostalCode;
36
+ exports.getPostalCodesByMunicipalityName = getPostalCodesByMunicipalityName;
37
+ const kommuner_2025_json_1 = __importDefault(require("../data/kommuner-2025.json"));
38
+ const fylker_2025_json_1 = __importDefault(require("../data/fylker-2025.json"));
39
+ const postal_codes_2025_json_1 = __importDefault(require("../data/postal-codes-2025.json"));
40
+ const package_json_1 = __importDefault(require("../package.json"));
41
+ // Type-safe data imports
42
+ const municipalities = kommuner_2025_json_1.default;
43
+ const counties = fylker_2025_json_1.default;
44
+ const postalCodes = postal_codes_2025_json_1.default;
45
+ /**
46
+ * Get the library version following semantic versioning.
47
+ * @returns Version string (e.g., "1.0.0")
48
+ */
49
+ function getVersion() {
50
+ return package_json_1.default.version;
51
+ }
52
+ /**
53
+ * Get all municipalities with metadata.
54
+ * @returns Array of all municipalities
55
+ */
56
+ function getMunicipalities() {
57
+ return municipalities;
58
+ }
59
+ /**
60
+ * Get a municipality by municipality ID.
61
+ * @param id - 4-digit municipality ID (e.g., "0301" for Oslo)
62
+ * @returns Municipality object or undefined if not found
63
+ * @throws {TypeError} If id is not a string
64
+ */
65
+ function getMunicipalityById(id) {
66
+ if (typeof id !== 'string') {
67
+ throw new TypeError('Municipality ID must be a string');
68
+ }
69
+ return municipalities.find(m => m.k_id === id);
70
+ }
71
+ /**
72
+ * Get municipalities by name (case-insensitive partial match by default).
73
+ * @param name - Municipality name or partial name to search for
74
+ * @param options - Search options
75
+ * @returns Array of matching municipalities
76
+ * @throws {TypeError} If name is not a string
77
+ */
78
+ function getMunicipalitiesByName(name, options = {}) {
79
+ if (typeof name !== 'string') {
80
+ throw new TypeError('Municipality name must be a string');
81
+ }
82
+ const { includeAllNames = true, caseSensitive = false, exactMatch = false } = options;
83
+ const searchTerm = caseSensitive ? name : name.toLowerCase();
84
+ return municipalities.filter(m => {
85
+ const namesToSearch = includeAllNames
86
+ ? [m.k_name, m.k_name_no]
87
+ : [m.k_name];
88
+ return namesToSearch.some(municipalityName => {
89
+ const compareString = caseSensitive
90
+ ? municipalityName
91
+ : municipalityName.toLowerCase();
92
+ return exactMatch
93
+ ? compareString === searchTerm
94
+ : compareString.includes(searchTerm);
95
+ });
96
+ });
97
+ }
98
+ /**
99
+ * Get all counties (fylker) with metadata.
100
+ * @returns Array of all counties
101
+ */
102
+ function getCounties() {
103
+ return counties;
104
+ }
105
+ /**
106
+ * Get a county by county ID.
107
+ * @param id - 2-digit county ID (e.g., "03" for Oslo)
108
+ * @returns County object or undefined if not found
109
+ * @throws {TypeError} If id is not a string
110
+ */
111
+ function getCountyById(id) {
112
+ if (typeof id !== 'string') {
113
+ throw new TypeError('County ID must be a string');
114
+ }
115
+ return counties.find(f => f.f_id === id);
116
+ }
117
+ /**
118
+ * Get county by name (case-insensitive partial match).
119
+ * @param name - County name or partial name to search for
120
+ * @param exactMatch - Whether to match exactly (default: false)
121
+ * @returns County object or undefined if not found
122
+ * @throws {TypeError} If name is not a string
123
+ */
124
+ function getCountyByName(name, exactMatch = false) {
125
+ if (typeof name !== 'string') {
126
+ throw new TypeError('County name must be a string');
127
+ }
128
+ const searchTerm = name.toLowerCase();
129
+ return counties.find(f => {
130
+ const countyName = f.f_name.toLowerCase();
131
+ return exactMatch ? countyName === searchTerm : countyName.includes(searchTerm);
132
+ });
133
+ }
134
+ /**
135
+ * Get all municipalities in a given county.
136
+ * @param countyId - 2-digit county ID (first two digits of municipality k_id)
137
+ * @returns Array of municipalities in the county
138
+ * @throws {TypeError} If countyId is not a string
139
+ */
140
+ function getMunicipalitiesByCounty(countyId) {
141
+ if (typeof countyId !== 'string') {
142
+ throw new TypeError('County ID must be a string');
143
+ }
144
+ return municipalities.filter(m => m.k_id.startsWith(countyId));
145
+ }
146
+ /**
147
+ * Get municipality by postal code.
148
+ * @param postalCode - Postal code to search for
149
+ * @returns Municipality object or undefined if not found
150
+ * @throws {TypeError} If postal code is not a valid number
151
+ */
152
+ function getMunicipalityByPostalCode(postalCode) {
153
+ const code = String(postalCode);
154
+ if (!code.match(/^\d{4}$/)) {
155
+ throw new TypeError('Postal code must be a valid 4-digit number');
156
+ }
157
+ return municipalities.find(m => m.k_postal_codes.some(pc => pc.postal_code === code));
158
+ }
159
+ /**
160
+ * Get all postal codes for a specific municipality.
161
+ * @param municipalityId - 4-digit municipality ID
162
+ * @returns Array of postal codes or undefined if municipality not found
163
+ */
164
+ function getPostalCodesByMunicipality(municipalityId) {
165
+ const municipality = getMunicipalityById(municipalityId);
166
+ return municipality ? municipality.k_postal_codes.map(pc => pc.postal_code) : undefined;
167
+ }
168
+ /**
169
+ * Get all postal codes from all municipalities.
170
+ * @param includeDetails - If true, returns objects with postal code and place name. If false, returns only postal codes (default: false)
171
+ * @returns Array of postal codes or postal code objects
172
+ */
173
+ function getAllPostalCodes(includeDetails = false) {
174
+ if (includeDetails) {
175
+ const allPostalCodes = [];
176
+ municipalities.forEach(municipality => {
177
+ municipality.k_postal_codes.forEach(pc => {
178
+ allPostalCodes.push({
179
+ zip: pc.postal_code,
180
+ place: pc.postal_place,
181
+ municipalityId: municipality.k_id,
182
+ municipalityName: municipality.k_name
183
+ });
184
+ });
185
+ });
186
+ return allPostalCodes.sort((a, b) => a.zip.localeCompare(b.zip));
187
+ }
188
+ else {
189
+ const allPostalCodes = new Set();
190
+ municipalities.forEach(municipality => {
191
+ municipality.k_postal_codes.forEach(pc => {
192
+ allPostalCodes.add(pc.postal_code);
193
+ });
194
+ });
195
+ return Array.from(allPostalCodes).sort();
196
+ }
197
+ }
198
+ /**
199
+ * Get municipalities sorted by population.
200
+ * @param ascending - Sort in ascending order if true (default: false for descending)
201
+ * @returns Array of municipalities sorted by population
202
+ */
203
+ function getMunicipalitiesByPopulation(ascending = false) {
204
+ const sorted = [...municipalities].sort((a, b) => ascending ? a.k_population - b.k_population : b.k_population - a.k_population);
205
+ return sorted;
206
+ }
207
+ /**
208
+ * Get municipalities sorted by area.
209
+ * @param ascending - Sort in ascending order if true (default: false for descending)
210
+ * @returns Array of municipalities sorted by area
211
+ */
212
+ function getMunicipalitiesByArea(ascending = false) {
213
+ const sorted = [...municipalities].sort((a, b) => ascending ? a.k_area - b.k_area : b.k_area - a.k_area);
214
+ return sorted;
215
+ }
216
+ /**
217
+ * Get municipalities by language status.
218
+ * @param language - Language status
219
+ * @returns Array of municipalities with the specified language status
220
+ * @throws {TypeError} If language is not a string
221
+ */
222
+ function getMunicipalitiesByLanguage(language) {
223
+ if (typeof language !== 'string') {
224
+ throw new TypeError('Language must be a string');
225
+ }
226
+ return municipalities.filter(m => m.k_language === language);
227
+ }
228
+ /**
229
+ * Get municipalities with advanced filtering options.
230
+ * @param options - Filter options
231
+ * @returns Array of municipalities matching the filter criteria
232
+ */
233
+ function getMunicipalitiesFiltered(options) {
234
+ return municipalities.filter(m => {
235
+ if (options.minPopulation !== undefined && m.k_population < options.minPopulation)
236
+ return false;
237
+ if (options.maxPopulation !== undefined && m.k_population > options.maxPopulation)
238
+ return false;
239
+ if (options.minArea !== undefined && m.k_area < options.minArea)
240
+ return false;
241
+ if (options.maxArea !== undefined && m.k_area > options.maxArea)
242
+ return false;
243
+ if (options.language !== undefined && m.k_language !== options.language)
244
+ return false;
245
+ if (options.countyId !== undefined && !m.k_id.startsWith(options.countyId))
246
+ return false;
247
+ return true;
248
+ });
249
+ }
250
+ /**
251
+ * Get total population of all municipalities.
252
+ * @returns Total population
253
+ */
254
+ function getTotalPopulation() {
255
+ return municipalities.reduce((total, m) => total + m.k_population, 0);
256
+ }
257
+ /**
258
+ * Get total area of all municipalities.
259
+ * @returns Total area in square kilometers
260
+ */
261
+ function getTotalArea() {
262
+ return municipalities.reduce((total, m) => total + m.k_area, 0);
263
+ }
264
+ /**
265
+ * Get population density statistics.
266
+ * @returns Object with min, max, and average population density
267
+ */
268
+ function getPopulationDensityStats() {
269
+ const densities = municipalities.map(m => m.k_population / m.k_area);
270
+ return {
271
+ min: Math.min(...densities),
272
+ max: Math.max(...densities),
273
+ average: densities.reduce((sum, d) => sum + d, 0) / densities.length
274
+ };
275
+ }
276
+ /**
277
+ * Get municipalities by population density range.
278
+ * @param minDensity - Minimum population density (people per km²)
279
+ * @param maxDensity - Maximum population density (people per km²)
280
+ * @returns Array of municipalities within the density range
281
+ */
282
+ function getMunicipalitiesByPopulationDensity(minDensity = 0, maxDensity = Infinity) {
283
+ return municipalities.filter(m => {
284
+ const density = m.k_population / m.k_area;
285
+ return density >= minDensity && density <= maxDensity;
286
+ });
287
+ }
288
+ /**
289
+ * Get the largest municipalities by population.
290
+ * @param count - Number of municipalities to return (default: 10)
291
+ * @returns Array of largest municipalities by population
292
+ */
293
+ function getLargestMunicipalities(count = 10) {
294
+ return getMunicipalitiesByPopulation(false).slice(0, count);
295
+ }
296
+ /**
297
+ * Get the smallest municipalities by population.
298
+ * @param count - Number of municipalities to return (default: 10)
299
+ * @returns Array of smallest municipalities by population
300
+ */
301
+ function getSmallestMunicipalities(count = 10) {
302
+ return getMunicipalitiesByPopulation(true).slice(0, count);
303
+ }
304
+ // ========================
305
+ // POSTAL CODE FUNCTIONS
306
+ // ========================
307
+ /**
308
+ * Get all postal codes with metadata.
309
+ * @returns Array of all postal codes
310
+ */
311
+ function getPostalCodes() {
312
+ return postalCodes;
313
+ }
314
+ /**
315
+ * Get postal code information by postal code.
316
+ * @param code - 4-digit postal code (e.g., "0001")
317
+ * @returns PostalCode object or undefined if not found
318
+ * @throws {TypeError} If code is not a string
319
+ */
320
+ function getPostalCodeByCode(code) {
321
+ if (typeof code !== 'string') {
322
+ throw new TypeError('Postal code must be a string');
323
+ }
324
+ return postalCodes.find(pc => pc.k_postal_code === code);
325
+ }
326
+ /**
327
+ * Get postal codes by postal place (case-insensitive partial match by default).
328
+ * @param place - Postal place name or partial name to search for
329
+ * @param options - Search options
330
+ * @returns Array of matching postal codes
331
+ * @throws {TypeError} If place is not a string
332
+ */
333
+ function getPostalCodesByPlace(place, options = {}) {
334
+ if (typeof place !== 'string') {
335
+ throw new TypeError('Postal place must be a string');
336
+ }
337
+ const { caseSensitive = false, exactMatch = false } = options;
338
+ const searchTerm = caseSensitive ? place : place.toLowerCase();
339
+ return postalCodes.filter(pc => {
340
+ const placeName = caseSensitive
341
+ ? pc.k_postal_place
342
+ : pc.k_postal_place.toLowerCase();
343
+ return exactMatch
344
+ ? placeName === searchTerm
345
+ : placeName.includes(searchTerm);
346
+ });
347
+ }
348
+ /**
349
+ * Get postal codes by municipality ID.
350
+ * @param municipalityId - 4-digit municipality ID (e.g., "0301" for Oslo)
351
+ * @returns Array of postal codes for the municipality
352
+ * @throws {TypeError} If municipalityId is not a string
353
+ */
354
+ function getPostalCodesByMunicipalityId(municipalityId) {
355
+ if (typeof municipalityId !== 'string') {
356
+ throw new TypeError('Municipality ID must be a string');
357
+ }
358
+ return postalCodes.filter(pc => pc.k_id === municipalityId);
359
+ }
360
+ /**
361
+ * Get unique postal places.
362
+ * @returns Array of unique postal place names sorted alphabetically
363
+ */
364
+ function getUniquePostalPlaces() {
365
+ const uniquePlaces = new Set();
366
+ postalCodes.forEach(pc => uniquePlaces.add(pc.k_postal_place));
367
+ return Array.from(uniquePlaces).sort();
368
+ }
369
+ /**
370
+ * Get postal codes within a range.
371
+ * @param startCode - Starting postal code (inclusive)
372
+ * @param endCode - Ending postal code (inclusive)
373
+ * @returns Array of postal codes within the range
374
+ * @throws {TypeError} If start or end codes are not strings
375
+ */
376
+ function getPostalCodesInRange(startCode, endCode) {
377
+ if (typeof startCode !== 'string' || typeof endCode !== 'string') {
378
+ throw new TypeError('Start and end codes must be strings');
379
+ }
380
+ return postalCodes.filter(pc => pc.k_postal_code >= startCode && pc.k_postal_code <= endCode);
381
+ }
382
+ /**
383
+ * Get postal codes statistics.
384
+ * @returns Object with total count and unique places count
385
+ */
386
+ function getPostalCodesStats() {
387
+ const uniquePlaces = new Set();
388
+ const uniqueMunicipalities = new Set();
389
+ postalCodes.forEach(pc => {
390
+ uniquePlaces.add(pc.k_postal_place);
391
+ uniqueMunicipalities.add(pc.k_id);
392
+ });
393
+ return {
394
+ totalPostalCodes: postalCodes.length,
395
+ uniquePlaces: uniquePlaces.size,
396
+ uniqueMunicipalities: uniqueMunicipalities.size
397
+ };
398
+ }
399
+ /**
400
+ * Get postal codes sorted by code.
401
+ * @param ascending - Sort in ascending order if true (default: true)
402
+ * @returns Array of postal codes sorted by postal code
403
+ */
404
+ function getPostalCodesSorted(ascending = true) {
405
+ const sorted = [...postalCodes].sort((a, b) => ascending
406
+ ? a.k_postal_code.localeCompare(b.k_postal_code)
407
+ : b.k_postal_code.localeCompare(a.k_postal_code));
408
+ return sorted;
409
+ }
410
+ /**
411
+ * Check if a postal code exists.
412
+ * @param code - 4-digit postal code to check
413
+ * @returns True if postal code exists, false otherwise
414
+ */
415
+ function isValidPostalCode(code) {
416
+ if (typeof code !== 'string') {
417
+ return false;
418
+ }
419
+ return postalCodes.some(pc => pc.k_postal_code === code);
420
+ }
421
+ /**
422
+ * Get postal codes by municipality name.
423
+ * Note: This function combines data from municipalities and postal codes.
424
+ * @param municipalityName - Municipality name to search for
425
+ * @param exactMatch - Whether to match exactly (default: false)
426
+ * @returns Array of postal codes for municipalities matching the name
427
+ */
428
+ function getPostalCodesByMunicipalityName(municipalityName, exactMatch = false) {
429
+ const matchingMunicipalities = getMunicipalitiesByName(municipalityName, { exactMatch });
430
+ const municipalityIds = matchingMunicipalities.map(m => m.k_id);
431
+ return postalCodes.filter(pc => municipalityIds.includes(pc.k_id));
432
+ }
433
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Language status for Norwegian municipalities
3
+ */
4
+ export type LanguageStatus = 'Nøytral' | 'Bokmål' | 'Nynorsk' | 'Sami' | 'Kvensk';
5
+ /**
6
+ * Municipality (Kommune) data structure
7
+ */
8
+ export interface Municipality {
9
+ /** 4-digit municipality ID */
10
+ readonly k_id: string;
11
+ /** Municipality name */
12
+ readonly k_name: string;
13
+ /** Municipality name in Norwegian */
14
+ readonly k_name_no: string;
15
+ /** Administrative center */
16
+ readonly k_adm_center: string;
17
+ /** Population count */
18
+ readonly k_population: number;
19
+ /** Area in square kilometers */
20
+ readonly k_area: number;
21
+ /** Official language status */
22
+ readonly k_language: LanguageStatus;
23
+ /** Official website URL */
24
+ readonly k_url: string;
25
+ /** Array of postal codes with place names */
26
+ readonly k_postal_codes: readonly {
27
+ /** 4-digit postal code */
28
+ readonly postal_code: string;
29
+ /** Place name */
30
+ readonly postal_place: string;
31
+ }[];
32
+ }
33
+ /**
34
+ * County (Fylke) data structure
35
+ */
36
+ export interface County {
37
+ /** 2-digit county ID */
38
+ readonly f_id: string;
39
+ /** County name */
40
+ readonly f_name: string;
41
+ /** Official website URL */
42
+ readonly f_url: string;
43
+ }
44
+ /**
45
+ * Population density statistics
46
+ */
47
+ export interface PopulationDensityStats {
48
+ /** Minimum population density (people per km²) */
49
+ readonly min: number;
50
+ /** Maximum population density (people per km²) */
51
+ readonly max: number;
52
+ /** Average population density (people per km²) */
53
+ readonly average: number;
54
+ }
55
+ /**
56
+ * Version bump types for semantic versioning
57
+ */
58
+ export type VersionBumpType = 'patch' | 'minor' | 'major' | 'prerelease';
59
+ /**
60
+ * Sort order options
61
+ */
62
+ export type SortOrder = 'asc' | 'desc';
63
+ /**
64
+ * Search options for municipalities
65
+ */
66
+ export interface MunicipalitySearchOptions {
67
+ /** Search in both Norwegian and English names */
68
+ readonly includeAllNames?: boolean;
69
+ /** Case sensitive search */
70
+ readonly caseSensitive?: boolean;
71
+ /** Exact match only */
72
+ readonly exactMatch?: boolean;
73
+ }
74
+ /**
75
+ * Filter options for municipalities
76
+ */
77
+ export interface MunicipalityFilterOptions {
78
+ /** Minimum population */
79
+ readonly minPopulation?: number;
80
+ /** Maximum population */
81
+ readonly maxPopulation?: number;
82
+ /** Minimum area (km²) */
83
+ readonly minArea?: number;
84
+ /** Maximum area (km²) */
85
+ readonly maxArea?: number;
86
+ /** Language status */
87
+ readonly language?: LanguageStatus;
88
+ /** County ID */
89
+ readonly countyId?: string;
90
+ }
91
+ /**
92
+ * Postal Code data structure
93
+ */
94
+ export interface PostalCode {
95
+ /** 4-digit postal code */
96
+ readonly k_postal_code: string;
97
+ /** Postal place name */
98
+ readonly k_postal_place: string;
99
+ /** 4-digit municipality ID */
100
+ readonly k_id: string;
101
+ }
102
+ /**
103
+ * Search options for postal codes
104
+ */
105
+ export interface PostalCodeSearchOptions {
106
+ /** Case sensitive search */
107
+ readonly caseSensitive?: boolean;
108
+ /** Exact match only */
109
+ readonly exactMatch?: boolean;
110
+ }
111
+ //# sourceMappingURL=types.d.ts.map
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
package/package.json ADDED
@@ -0,0 +1,95 @@
1
+ {
2
+ "name": "@aprestmo/norway-geodata",
3
+ "version": "0.1.0",
4
+ "description": "Administrative geographic data for Norway including municipalities, counties, and postal codes.",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "require": "./dist/index.js",
11
+ "import": "./dist/index.js"
12
+ },
13
+ "./data/municipalities": "./data/kommuner-2025.json",
14
+ "./data/counties": "./data/fylker-2025.json",
15
+ "./types": {
16
+ "types": "./dist/types.d.ts",
17
+ "require": "./dist/types.js",
18
+ "import": "./dist/types.js"
19
+ },
20
+ "./package.json": "./package.json"
21
+ },
22
+ "engines": {
23
+ "node": ">=18.0.0",
24
+ "npm": ">=8.0.0"
25
+ },
26
+ "scripts": {
27
+ "build": "npm run build:cjs && npm run build:esm",
28
+ "build:cjs": "tsc -p tsconfig.json",
29
+ "build:esm": "tsc -p tsconfig.esm.json",
30
+ "build:watch": "tsc --watch",
31
+ "clean": "rimraf dist",
32
+ "prebuild": "npm run clean",
33
+ "test": "npm run build && node -e \"console.log('Running TypeScript validation...'); require('./dist/index.js'); console.log('✅ All exports working correctly!');\"",
34
+ "test:types": "tsc --noEmit",
35
+ "validate": "node scripts/validate-data.js",
36
+ "prepublishOnly": "npm run validate && npm run build && npm test",
37
+ "dev": "npm run build:watch",
38
+ "version:patch": "npm version patch --no-git-tag-version",
39
+ "version:minor": "npm version minor --no-git-tag-version",
40
+ "version:major": "npm version major --no-git-tag-version",
41
+ "version:prerelease": "npm version prerelease --no-git-tag-version",
42
+ "check-version": "npm view @aprestmo/norway-geodata version",
43
+ "check-conflicts": "node -e \"const pkg=require('./package.json'); const localVer=pkg.version; console.log('Local version:', localVer); require('child_process').exec('npm view @aprestmo/norway-geodata version', (err,stdout) => { if(err) { console.log('✅ Package not published yet - safe to publish'); return; } const remoteVer=stdout.trim(); console.log('Published version:', remoteVer); if(localVer===remoteVer) console.log('❌ Version conflict! Local version already published'); else console.log('✅ No conflicts - safe to publish'); });\"",
44
+ "version-status": "node -e \"const pkg=require('./package.json'); console.log('📦 Package:', pkg.name); console.log('🏷️ Local version:', pkg.version); require('child_process').exec('npm view @aprestmo/norway-geodata version', (err,stdout) => { if(err) { console.log('📡 Published: Not yet published'); } else { console.log('📡 Published version:', stdout.trim()); } });\"",
45
+ "publish:npm": "npm run check-conflicts && npm run prepublishOnly && npm publish --access public",
46
+ "publish:npm-dry": "npm run prepublishOnly && npm publish --dry-run",
47
+ "publish:github": "npm run prepublishOnly && npm publish --registry=https://npm.pkg.github.com",
48
+ "publish:both": "npm run publish:npm && npm run publish:github",
49
+ "release:patch": "npm run version:patch && npm run publish:npm",
50
+ "release:minor": "npm run version:minor && npm run publish:npm",
51
+ "release:major": "npm run version:major && npm run publish:npm"
52
+ },
53
+ "files": [
54
+ "dist",
55
+ "data",
56
+ "README.md",
57
+ "LICENSE",
58
+ "!dist/**/*.test.*",
59
+ "!dist/**/*.spec.*",
60
+ "!dist/**/*.map"
61
+ ],
62
+ "devDependencies": {
63
+ "@types/jest": "^29.5.12",
64
+ "@types/node": "^22.0.0",
65
+ "jest": "^29.7.0",
66
+ "rimraf": "^6.0.1",
67
+ "ts-jest": "^29.2.5",
68
+ "typescript": "^5.6.0"
69
+ },
70
+ "keywords": [
71
+ "norway",
72
+ "geodata",
73
+ "municipalities",
74
+ "counties",
75
+ "postal-codes",
76
+ "kommune",
77
+ "fylke",
78
+ "typescript",
79
+ "types"
80
+ ],
81
+ "author": "Alexander Prestmo",
82
+ "license": "MIT",
83
+ "repository": {
84
+ "type": "git",
85
+ "url": "git+https://github.com/aprestmo/norway-geodata.git"
86
+ },
87
+ "publishConfig": {
88
+ "access": "public",
89
+ "registry": "https://registry.npmjs.org"
90
+ },
91
+ "overrides": {
92
+ "inflight": "npm:@lukekarrys/inflight@^1.0.4",
93
+ "glob": "^10.3.0"
94
+ }
95
+ }