@cardog/ocm-client 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,293 @@
1
+ // src/client.ts
2
+ var DEFAULT_BASE_URL = "https://api.openchargemap.io";
3
+ var DEFAULT_VERSION = "v4";
4
+ var OCMClient = class {
5
+ apiKey;
6
+ baseUrl;
7
+ version;
8
+ fetchFn;
9
+ timeout;
10
+ sessionToken;
11
+ constructor(options) {
12
+ if (!options.apiKey) {
13
+ throw new Error("API key is required");
14
+ }
15
+ this.apiKey = options.apiKey;
16
+ this.baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;
17
+ this.version = options.version ?? DEFAULT_VERSION;
18
+ this.fetchFn = options.fetch ?? globalThis.fetch;
19
+ this.timeout = options.timeout ?? 3e4;
20
+ this.sessionToken = options.sessionToken;
21
+ }
22
+ /**
23
+ * Build URL with query parameters
24
+ */
25
+ buildUrl(endpoint, params) {
26
+ const url = new URL(`/${this.version}${endpoint}`, this.baseUrl);
27
+ if (params) {
28
+ for (const [key, value] of Object.entries(params)) {
29
+ if (value === void 0 || value === null) continue;
30
+ if (Array.isArray(value)) {
31
+ url.searchParams.set(key, value.join(","));
32
+ } else if (value instanceof Date) {
33
+ url.searchParams.set(key, value.toISOString());
34
+ } else {
35
+ url.searchParams.set(key, String(value));
36
+ }
37
+ }
38
+ }
39
+ return url.toString();
40
+ }
41
+ /**
42
+ * Make a request with proper headers and error handling
43
+ */
44
+ async request(endpoint, options = {}) {
45
+ const { method = "GET", params, body } = options;
46
+ const url = this.buildUrl(endpoint, params);
47
+ const headers = {
48
+ "X-API-Key": this.apiKey,
49
+ "Content-Type": "application/json"
50
+ };
51
+ if (this.sessionToken) {
52
+ headers["Authorization"] = `Bearer ${this.sessionToken}`;
53
+ }
54
+ const controller = new AbortController();
55
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
56
+ try {
57
+ const response = await this.fetchFn(url, {
58
+ method,
59
+ headers,
60
+ body: body ? JSON.stringify(body) : void 0,
61
+ signal: controller.signal
62
+ });
63
+ if (!response.ok) {
64
+ const errorText = await response.text();
65
+ throw new OCMAPIError(response.status, errorText);
66
+ }
67
+ return response.json();
68
+ } finally {
69
+ clearTimeout(timeoutId);
70
+ }
71
+ }
72
+ // ============================================
73
+ // POI (Point of Interest) Methods
74
+ // ============================================
75
+ /**
76
+ * Search for charging stations
77
+ *
78
+ * @example
79
+ * ```ts
80
+ * // Nearby search
81
+ * const stations = await client.searchPOI({
82
+ * latitude: 37.7749,
83
+ * longitude: -122.4194,
84
+ * distance: 10,
85
+ * distanceunit: "km"
86
+ * });
87
+ *
88
+ * // Fast chargers only
89
+ * const fastChargers = await client.searchPOI({
90
+ * latitude: 37.7749,
91
+ * longitude: -122.4194,
92
+ * connectiontypeid: [32, 33], // CCS Combo
93
+ * minpowerkw: 50
94
+ * });
95
+ * ```
96
+ */
97
+ async searchPOI(params = {}) {
98
+ return this.request("/poi", {
99
+ params
100
+ });
101
+ }
102
+ /**
103
+ * Get a specific POI by ID
104
+ */
105
+ async getPOI(id, verbose = true) {
106
+ const results = await this.request("/poi", {
107
+ params: { chargepointid: id, verbose }
108
+ });
109
+ return results[0] ?? null;
110
+ }
111
+ /**
112
+ * Search POIs and return GeoJSON format
113
+ */
114
+ async searchPOIGeoJSON(params) {
115
+ return this.request("/poi", {
116
+ params: { ...params, output: "geojson" }
117
+ });
118
+ }
119
+ /**
120
+ * Get POIs modified since a specific date
121
+ * Useful for syncing/caching
122
+ */
123
+ async getPOIUpdates(since, params = {}) {
124
+ return this.searchPOI({ ...params, modifiedsince: since });
125
+ }
126
+ // ============================================
127
+ // Reference Data Methods
128
+ // ============================================
129
+ /**
130
+ * Get all reference data (lookup tables)
131
+ * Results should be cached locally
132
+ *
133
+ * @example
134
+ * ```ts
135
+ * const refData = await client.getReferenceData();
136
+ * console.log(refData.ConnectionTypes);
137
+ * console.log(refData.StatusTypes);
138
+ * ```
139
+ */
140
+ async getReferenceData() {
141
+ return this.request("/referencedata");
142
+ }
143
+ // ============================================
144
+ // Authentication Methods
145
+ // ============================================
146
+ /**
147
+ * Authenticate user and get session token
148
+ * Store the sessionToken for subsequent authenticated requests
149
+ */
150
+ async authenticate(credentials) {
151
+ const response = await this.request(
152
+ "/profile/authenticate",
153
+ {
154
+ method: "POST",
155
+ body: credentials
156
+ }
157
+ );
158
+ if (response.CurrentSessionToken) {
159
+ this.sessionToken = response.CurrentSessionToken;
160
+ }
161
+ return response;
162
+ }
163
+ /**
164
+ * Set session token for authenticated requests
165
+ */
166
+ setSessionToken(token) {
167
+ this.sessionToken = token;
168
+ }
169
+ /**
170
+ * Clear session token
171
+ */
172
+ clearSession() {
173
+ this.sessionToken = void 0;
174
+ }
175
+ // ============================================
176
+ // Submission Methods (Require Authentication)
177
+ // ============================================
178
+ /**
179
+ * Submit a new POI
180
+ * Requires authentication
181
+ */
182
+ async submitPOI(poi) {
183
+ if (!this.sessionToken) {
184
+ throw new Error("Authentication required. Call authenticate() first.");
185
+ }
186
+ return this.request("/system/poi", {
187
+ method: "POST",
188
+ body: poi
189
+ });
190
+ }
191
+ /**
192
+ * Submit a comment/check-in on a POI
193
+ * Requires authentication
194
+ */
195
+ async submitComment(comment) {
196
+ if (!this.sessionToken) {
197
+ throw new Error("Authentication required. Call authenticate() first.");
198
+ }
199
+ return this.request("/system/comment", {
200
+ method: "POST",
201
+ body: comment
202
+ });
203
+ }
204
+ };
205
+ var OCMAPIError = class extends Error {
206
+ status;
207
+ code;
208
+ constructor(status, message) {
209
+ super(message);
210
+ this.name = "OCMAPIError";
211
+ this.status = status;
212
+ if (message.includes("REJECTED_APIKEY_MISSING")) {
213
+ this.code = "APIKEY_MISSING";
214
+ } else if (message.includes("REJECTED_APIKEY_INVALID")) {
215
+ this.code = "APIKEY_INVALID";
216
+ } else if (message.includes("Blocked for API Abuse")) {
217
+ this.code = "RATE_LIMITED";
218
+ }
219
+ }
220
+ };
221
+ function createOCMClient(options) {
222
+ return new OCMClient(options);
223
+ }
224
+
225
+ // src/types/enums.ts
226
+ var StandardConnectionTypes = /* @__PURE__ */ ((StandardConnectionTypes2) => {
227
+ StandardConnectionTypes2[StandardConnectionTypes2["Unknown"] = 0] = "Unknown";
228
+ StandardConnectionTypes2[StandardConnectionTypes2["J1772"] = 1] = "J1772";
229
+ StandardConnectionTypes2[StandardConnectionTypes2["CHAdeMO"] = 2] = "CHAdeMO";
230
+ StandardConnectionTypes2[StandardConnectionTypes2["Type2Mennekes"] = 25] = "Type2Mennekes";
231
+ StandardConnectionTypes2[StandardConnectionTypes2["Type2Outlet"] = 28] = "Type2Outlet";
232
+ StandardConnectionTypes2[StandardConnectionTypes2["CCSCombo1"] = 32] = "CCSCombo1";
233
+ StandardConnectionTypes2[StandardConnectionTypes2["CCSCombo2"] = 33] = "CCSCombo2";
234
+ StandardConnectionTypes2[StandardConnectionTypes2["Tesla"] = 27] = "Tesla";
235
+ StandardConnectionTypes2[StandardConnectionTypes2["TeslaSupercharger"] = 30] = "TeslaSupercharger";
236
+ StandardConnectionTypes2[StandardConnectionTypes2["NACS"] = 36] = "NACS";
237
+ StandardConnectionTypes2[StandardConnectionTypes2["Type1CCS"] = 32] = "Type1CCS";
238
+ StandardConnectionTypes2[StandardConnectionTypes2["Type2CCS"] = 33] = "Type2CCS";
239
+ return StandardConnectionTypes2;
240
+ })(StandardConnectionTypes || {});
241
+ var StandardStatusTypes = /* @__PURE__ */ ((StandardStatusTypes2) => {
242
+ StandardStatusTypes2[StandardStatusTypes2["Unknown"] = 0] = "Unknown";
243
+ StandardStatusTypes2[StandardStatusTypes2["CurrentlyAvailable"] = 50] = "CurrentlyAvailable";
244
+ StandardStatusTypes2[StandardStatusTypes2["Operational"] = 50] = "Operational";
245
+ StandardStatusTypes2[StandardStatusTypes2["NotOperational"] = 100] = "NotOperational";
246
+ StandardStatusTypes2[StandardStatusTypes2["PlannedForFuture"] = 150] = "PlannedForFuture";
247
+ StandardStatusTypes2[StandardStatusTypes2["TemporarilyUnavailable"] = 75] = "TemporarilyUnavailable";
248
+ StandardStatusTypes2[StandardStatusTypes2["Removed"] = 200] = "Removed";
249
+ return StandardStatusTypes2;
250
+ })(StandardStatusTypes || {});
251
+ var StandardUsageTypes = /* @__PURE__ */ ((StandardUsageTypes2) => {
252
+ StandardUsageTypes2[StandardUsageTypes2["Unknown"] = 0] = "Unknown";
253
+ StandardUsageTypes2[StandardUsageTypes2["Public"] = 1] = "Public";
254
+ StandardUsageTypes2[StandardUsageTypes2["PublicMembershipRequired"] = 4] = "PublicMembershipRequired";
255
+ StandardUsageTypes2[StandardUsageTypes2["PublicPayAtLocation"] = 5] = "PublicPayAtLocation";
256
+ StandardUsageTypes2[StandardUsageTypes2["PublicNoticeRequired"] = 7] = "PublicNoticeRequired";
257
+ StandardUsageTypes2[StandardUsageTypes2["Private"] = 2] = "Private";
258
+ StandardUsageTypes2[StandardUsageTypes2["PrivateForStaffAndVisitors"] = 6] = "PrivateForStaffAndVisitors";
259
+ StandardUsageTypes2[StandardUsageTypes2["PrivateResidential"] = 3] = "PrivateResidential";
260
+ return StandardUsageTypes2;
261
+ })(StandardUsageTypes || {});
262
+ var StandardCurrentTypes = /* @__PURE__ */ ((StandardCurrentTypes2) => {
263
+ StandardCurrentTypes2[StandardCurrentTypes2["Unknown"] = 0] = "Unknown";
264
+ StandardCurrentTypes2[StandardCurrentTypes2["AC_SinglePhase"] = 10] = "AC_SinglePhase";
265
+ StandardCurrentTypes2[StandardCurrentTypes2["AC_ThreePhase"] = 20] = "AC_ThreePhase";
266
+ StandardCurrentTypes2[StandardCurrentTypes2["DC"] = 30] = "DC";
267
+ return StandardCurrentTypes2;
268
+ })(StandardCurrentTypes || {});
269
+ var ChargingLevels = /* @__PURE__ */ ((ChargingLevels2) => {
270
+ ChargingLevels2[ChargingLevels2["Level1"] = 1] = "Level1";
271
+ ChargingLevels2[ChargingLevels2["Level2"] = 2] = "Level2";
272
+ ChargingLevels2[ChargingLevels2["Level3_DCFastCharging"] = 3] = "Level3_DCFastCharging";
273
+ return ChargingLevels2;
274
+ })(ChargingLevels || {});
275
+ var StandardSubmissionStatusTypes = /* @__PURE__ */ ((StandardSubmissionStatusTypes2) => {
276
+ StandardSubmissionStatusTypes2[StandardSubmissionStatusTypes2["Submitted_UnderReview"] = 1] = "Submitted_UnderReview";
277
+ StandardSubmissionStatusTypes2[StandardSubmissionStatusTypes2["Imported_UnverifiedOrLowQuality"] = 100] = "Imported_UnverifiedOrLowQuality";
278
+ StandardSubmissionStatusTypes2[StandardSubmissionStatusTypes2["Imported_Published"] = 200] = "Imported_Published";
279
+ StandardSubmissionStatusTypes2[StandardSubmissionStatusTypes2["Submitted_Published"] = 1e3] = "Submitted_Published";
280
+ return StandardSubmissionStatusTypes2;
281
+ })(StandardSubmissionStatusTypes || {});
282
+ export {
283
+ ChargingLevels,
284
+ OCMAPIError,
285
+ OCMClient,
286
+ StandardConnectionTypes,
287
+ StandardCurrentTypes,
288
+ StandardStatusTypes,
289
+ StandardSubmissionStatusTypes,
290
+ StandardUsageTypes,
291
+ createOCMClient
292
+ };
293
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/client.ts","../src/types/enums.ts"],"sourcesContent":["import type {\n POISearchParams,\n AuthenticateParams,\n AuthenticateResponse,\n SubmitPOIParams,\n SubmitCommentParams,\n POIGeoJSONCollection,\n} from \"./types/requests\";\nimport type { ChargePoint, CoreReferenceData } from \"./types\";\n\nconst DEFAULT_BASE_URL = \"https://api.openchargemap.io\";\nconst DEFAULT_VERSION = \"v4\";\n\nexport interface OCMClientOptions {\n /**\n * API key for authentication (required)\n * Get one at https://openchargemap.org\n */\n apiKey: string;\n\n /**\n * Base URL for the API\n * @default \"https://api.openchargemap.io\"\n */\n baseUrl?: string;\n\n /**\n * API version\n * @default \"v4\"\n */\n version?: string;\n\n /**\n * Custom fetch implementation (useful for testing or server-side usage)\n */\n fetch?: typeof fetch;\n\n /**\n * Default timeout in milliseconds\n * @default 30000\n */\n timeout?: number;\n\n /**\n * User session token for authenticated requests\n */\n sessionToken?: string;\n}\n\nexport class OCMClient {\n private apiKey: string;\n private baseUrl: string;\n private version: string;\n private fetchFn: typeof fetch;\n private timeout: number;\n private sessionToken?: string;\n\n constructor(options: OCMClientOptions) {\n if (!options.apiKey) {\n throw new Error(\"API key is required\");\n }\n\n this.apiKey = options.apiKey;\n this.baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;\n this.version = options.version ?? DEFAULT_VERSION;\n this.fetchFn = options.fetch ?? globalThis.fetch;\n this.timeout = options.timeout ?? 30000;\n this.sessionToken = options.sessionToken;\n }\n\n /**\n * Build URL with query parameters\n */\n private buildUrl(\n endpoint: string,\n params?: Record<string, unknown>\n ): string {\n const url = new URL(`/${this.version}${endpoint}`, this.baseUrl);\n\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value === undefined || value === null) continue;\n\n if (Array.isArray(value)) {\n url.searchParams.set(key, value.join(\",\"));\n } else if (value instanceof Date) {\n url.searchParams.set(key, value.toISOString());\n } else {\n url.searchParams.set(key, String(value));\n }\n }\n }\n\n return url.toString();\n }\n\n /**\n * Make a request with proper headers and error handling\n */\n private async request<T>(\n endpoint: string,\n options: {\n method?: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n params?: Record<string, unknown>;\n body?: unknown;\n } = {}\n ): Promise<T> {\n const { method = \"GET\", params, body } = options;\n const url = this.buildUrl(endpoint, params);\n\n const headers: Record<string, string> = {\n \"X-API-Key\": this.apiKey,\n \"Content-Type\": \"application/json\",\n };\n\n if (this.sessionToken) {\n headers[\"Authorization\"] = `Bearer ${this.sessionToken}`;\n }\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await this.fetchFn(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new OCMAPIError(response.status, errorText);\n }\n\n return response.json() as Promise<T>;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n // ============================================\n // POI (Point of Interest) Methods\n // ============================================\n\n /**\n * Search for charging stations\n *\n * @example\n * ```ts\n * // Nearby search\n * const stations = await client.searchPOI({\n * latitude: 37.7749,\n * longitude: -122.4194,\n * distance: 10,\n * distanceunit: \"km\"\n * });\n *\n * // Fast chargers only\n * const fastChargers = await client.searchPOI({\n * latitude: 37.7749,\n * longitude: -122.4194,\n * connectiontypeid: [32, 33], // CCS Combo\n * minpowerkw: 50\n * });\n * ```\n */\n async searchPOI(params: POISearchParams = {}): Promise<ChargePoint[]> {\n return this.request<ChargePoint[]>(\"/poi\", {\n params: params as Record<string, unknown>,\n });\n }\n\n /**\n * Get a specific POI by ID\n */\n async getPOI(id: number, verbose = true): Promise<ChargePoint | null> {\n const results = await this.request<ChargePoint[]>(\"/poi\", {\n params: { chargepointid: id, verbose },\n });\n return results[0] ?? null;\n }\n\n /**\n * Search POIs and return GeoJSON format\n */\n async searchPOIGeoJSON(\n params: Omit<POISearchParams, \"output\">\n ): Promise<POIGeoJSONCollection> {\n return this.request<POIGeoJSONCollection>(\"/poi\", {\n params: { ...params, output: \"geojson\" } as Record<string, unknown>,\n });\n }\n\n /**\n * Get POIs modified since a specific date\n * Useful for syncing/caching\n */\n async getPOIUpdates(\n since: Date,\n params: Omit<POISearchParams, \"modifiedsince\"> = {}\n ): Promise<ChargePoint[]> {\n return this.searchPOI({ ...params, modifiedsince: since });\n }\n\n // ============================================\n // Reference Data Methods\n // ============================================\n\n /**\n * Get all reference data (lookup tables)\n * Results should be cached locally\n *\n * @example\n * ```ts\n * const refData = await client.getReferenceData();\n * console.log(refData.ConnectionTypes);\n * console.log(refData.StatusTypes);\n * ```\n */\n async getReferenceData(): Promise<CoreReferenceData> {\n return this.request<CoreReferenceData>(\"/referencedata\");\n }\n\n // ============================================\n // Authentication Methods\n // ============================================\n\n /**\n * Authenticate user and get session token\n * Store the sessionToken for subsequent authenticated requests\n */\n async authenticate(\n credentials: AuthenticateParams\n ): Promise<AuthenticateResponse> {\n const response = await this.request<AuthenticateResponse>(\n \"/profile/authenticate\",\n {\n method: \"POST\",\n body: credentials,\n }\n );\n\n // Store session token for future requests\n if (response.CurrentSessionToken) {\n this.sessionToken = response.CurrentSessionToken;\n }\n\n return response;\n }\n\n /**\n * Set session token for authenticated requests\n */\n setSessionToken(token: string): void {\n this.sessionToken = token;\n }\n\n /**\n * Clear session token\n */\n clearSession(): void {\n this.sessionToken = undefined;\n }\n\n // ============================================\n // Submission Methods (Require Authentication)\n // ============================================\n\n /**\n * Submit a new POI\n * Requires authentication\n */\n async submitPOI(poi: SubmitPOIParams): Promise<{ ID: number }> {\n if (!this.sessionToken) {\n throw new Error(\"Authentication required. Call authenticate() first.\");\n }\n return this.request<{ ID: number }>(\"/system/poi\", {\n method: \"POST\",\n body: poi,\n });\n }\n\n /**\n * Submit a comment/check-in on a POI\n * Requires authentication\n */\n async submitComment(\n comment: SubmitCommentParams\n ): Promise<{ ID: number }> {\n if (!this.sessionToken) {\n throw new Error(\"Authentication required. Call authenticate() first.\");\n }\n return this.request<{ ID: number }>(\"/system/comment\", {\n method: \"POST\",\n body: comment,\n });\n }\n}\n\n/**\n * Custom error class for OCM API errors\n */\nexport class OCMAPIError extends Error {\n public status: number;\n public code?: string;\n\n constructor(status: number, message: string) {\n super(message);\n this.name = \"OCMAPIError\";\n this.status = status;\n\n // Parse common error codes\n if (message.includes(\"REJECTED_APIKEY_MISSING\")) {\n this.code = \"APIKEY_MISSING\";\n } else if (message.includes(\"REJECTED_APIKEY_INVALID\")) {\n this.code = \"APIKEY_INVALID\";\n } else if (message.includes(\"Blocked for API Abuse\")) {\n this.code = \"RATE_LIMITED\";\n }\n }\n}\n\n/**\n * Create an OCM client instance\n */\nexport function createOCMClient(options: OCMClientOptions): OCMClient {\n return new OCMClient(options);\n}\n","/**\n * Standard connection type IDs from Open Charge Map\n *\n * These values correspond to the ConnectionType reference data.\n * @see https://github.com/openchargemap/ocm-system/blob/master/API/OCM.Net/OCM.API.Model/Base/CoreReferenceData.cs#L89\n * @see https://openchargemap.org/site/develop/api - GET /v4/referencedata\n */\nexport enum StandardConnectionTypes {\n /** Unknown or unspecified connector */\n Unknown = 0,\n /** SAE J1772 - Standard North American Level 1/2 connector */\n J1772 = 1,\n /** CHAdeMO - Japanese DC fast charging standard */\n CHAdeMO = 2,\n /** IEC 62196-2 Type 2 - European AC connector (Mennekes) */\n Type2Mennekes = 25,\n /** Type 2 socket outlet */\n Type2Outlet = 28,\n /** SAE J1772 Combo (CCS1) - North American DC fast charging */\n CCSCombo1 = 32,\n /** IEC 62196-3 Combo (CCS2) - European DC fast charging */\n CCSCombo2 = 33,\n /** Tesla proprietary connector (Roadster) */\n Tesla = 27,\n /** Tesla Supercharger connector */\n TeslaSupercharger = 30,\n /** NACS (North American Charging Standard) - Tesla's connector adopted as SAE J3400 */\n NACS = 36,\n /** Alias for CCSCombo1 */\n Type1CCS = 32,\n /** Alias for CCSCombo2 */\n Type2CCS = 33,\n}\n\n/**\n * Standard status type IDs indicating operational state\n *\n * @see https://github.com/openchargemap/ocm-system/blob/master/API/OCM.Net/OCM.API.Model/Base/CoreReferenceData.cs#L71\n */\nexport enum StandardStatusTypes {\n /** Status unknown or not specified */\n Unknown = 0,\n /** Station is operational and available for use */\n CurrentlyAvailable = 50,\n /** Alias for CurrentlyAvailable */\n Operational = 50,\n /** Station is not operational */\n NotOperational = 100,\n /** Station is planned for future installation */\n PlannedForFuture = 150,\n /** Station is temporarily unavailable (maintenance, etc.) */\n TemporarilyUnavailable = 75,\n /** Station has been removed/decommissioned */\n Removed = 200,\n}\n\n/**\n * Standard usage type IDs indicating access restrictions\n *\n * @see https://github.com/openchargemap/ocm-system/blob/master/API/OCM.Net/OCM.API.Model/Base/CoreReferenceData.cs#L80\n */\nexport enum StandardUsageTypes {\n /** Usage type unknown */\n Unknown = 0,\n /** Public access - no restrictions */\n Public = 1,\n /** Public access but membership/account required */\n PublicMembershipRequired = 4,\n /** Public access with payment at location */\n PublicPayAtLocation = 5,\n /** Public access but notice/call ahead required */\n PublicNoticeRequired = 7,\n /** Private - restricted access */\n Private = 2,\n /** Private - for staff and visitors only */\n PrivateForStaffAndVisitors = 6,\n /** Private residential */\n PrivateResidential = 3,\n}\n\n/**\n * Standard current types for charging connections\n *\n * @see https://github.com/openchargemap/ocm-system/blob/master/API/OCM.Net/OCM.API.Model/Base/CoreReferenceData.cs#L62\n */\nexport enum StandardCurrentTypes {\n /** Current type unknown */\n Unknown = 0,\n /** AC single phase */\n AC_SinglePhase = 10,\n /** AC three phase */\n AC_ThreePhase = 20,\n /** DC (Direct Current) */\n DC = 30,\n}\n\n/**\n * Charging level IDs (ChargerType in OCM)\n *\n * @see https://github.com/openchargemap/ocm-system/blob/master/API/OCM.Net/OCM.API.Model/Base/CoreReferenceData.cs#L53\n */\nexport enum ChargingLevels {\n /** Level 1 - Standard household outlet (slow) */\n Level1 = 1,\n /** Level 2 - Dedicated EVSE (medium speed) */\n Level2 = 2,\n /** Level 3 - DC Fast Charging (rapid) */\n Level3_DCFastCharging = 3,\n}\n\n/**\n * Submission status types for POI data quality\n *\n * @see https://github.com/openchargemap/ocm-system/blob/master/API/OCM.Net/OCM.API.Model/Base/CoreReferenceData.cs#L98\n */\nexport enum StandardSubmissionStatusTypes {\n /** Submitted and pending review */\n Submitted_UnderReview = 1,\n /** Imported from external source, unverified */\n Imported_UnverifiedOrLowQuality = 100,\n /** Imported and published */\n Imported_Published = 200,\n /** User submitted and published */\n Submitted_Published = 1000,\n}\n"],"mappings":"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","names":["StandardConnectionTypes","StandardStatusTypes","StandardUsageTypes","StandardCurrentTypes","ChargingLevels","StandardSubmissionStatusTypes"]}
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "@cardog/ocm-client",
3
+ "version": "0.1.0",
4
+ "description": "TypeScript client for the Open Charge Map API - access the world's largest open database of EV charging stations",
5
+ "author": "Cardog <hello@cardog.io>",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "require": "./dist/index.cjs"
13
+ }
14
+ },
15
+ "main": "./dist/index.cjs",
16
+ "module": "./dist/index.js",
17
+ "types": "./dist/index.d.ts",
18
+ "files": [
19
+ "dist",
20
+ "README.md",
21
+ "LICENSE",
22
+ "CHANGELOG.md"
23
+ ],
24
+ "sideEffects": false,
25
+ "keywords": [
26
+ "openchargemap",
27
+ "ocm",
28
+ "ev",
29
+ "electric-vehicle",
30
+ "charging-stations",
31
+ "chargers",
32
+ "api-client",
33
+ "typescript",
34
+ "evse",
35
+ "charging-infrastructure",
36
+ "poi",
37
+ "geolocation"
38
+ ],
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "git+https://github.com/cardog-ai/ocm-client.git"
42
+ },
43
+ "bugs": {
44
+ "url": "https://github.com/cardog-ai/ocm-client/issues"
45
+ },
46
+ "homepage": "https://github.com/cardog-ai/ocm-client#readme",
47
+ "engines": {
48
+ "node": ">=18.0.0"
49
+ },
50
+ "devDependencies": {
51
+ "@types/node": "^20.10.0",
52
+ "@typescript-eslint/eslint-plugin": "^7.0.0",
53
+ "@typescript-eslint/parser": "^7.0.0",
54
+ "eslint": "^8.57.0",
55
+ "eslint-config-prettier": "^9.1.0",
56
+ "prettier": "^3.2.0",
57
+ "tsup": "^8.0.0",
58
+ "typescript": "^5.3.0",
59
+ "vitest": "^2.0.0"
60
+ },
61
+ "scripts": {
62
+ "build": "tsup",
63
+ "dev": "tsup --watch",
64
+ "typecheck": "tsc --noEmit",
65
+ "lint": "eslint src --ext .ts",
66
+ "lint:fix": "eslint src --ext .ts --fix",
67
+ "format": "prettier --write \"src/**/*.ts\"",
68
+ "format:check": "prettier --check \"src/**/*.ts\"",
69
+ "clean": "rm -rf dist",
70
+ "test": "vitest run",
71
+ "test:watch": "vitest"
72
+ }
73
+ }