@glideidentity/web-client-sdk 5.0.1 → 5.1.1-beta.3

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 (97) hide show
  1. package/README.md +8 -108
  2. package/dist/adapters/angular/index.js +1 -0
  3. package/dist/adapters/angular/phone-auth.service.d.ts +18 -0
  4. package/dist/adapters/angular/phone-auth.service.js +26 -0
  5. package/dist/adapters/react/index.js +3 -0
  6. package/dist/adapters/react/useClient.js +1 -0
  7. package/dist/adapters/react/usePhoneAuth.js +16 -1
  8. package/dist/adapters/vanilla/client.js +1 -0
  9. package/dist/adapters/vanilla/index.js +1 -0
  10. package/dist/adapters/vanilla/phone-auth.js +31 -0
  11. package/dist/adapters/vue/index.js +4 -0
  12. package/dist/adapters/vue/useClient.js +5 -0
  13. package/dist/adapters/vue/usePhoneAuth.js +20 -1
  14. package/dist/browser/web-client-sdk.min.js +1 -2
  15. package/dist/browser.js +6 -0
  16. package/dist/core/client.js +12 -0
  17. package/dist/core/logger.js +81 -1
  18. package/dist/core/phone-auth/api-types.d.ts +1 -6
  19. package/dist/core/phone-auth/api-types.js +83 -0
  20. package/dist/core/phone-auth/client.js +374 -38
  21. package/dist/core/phone-auth/error-utils.js +83 -1
  22. package/dist/core/phone-auth/index.d.ts +1 -1
  23. package/dist/core/phone-auth/index.js +2 -2
  24. package/dist/core/phone-auth/status-types.d.ts +78 -0
  25. package/dist/core/phone-auth/status-types.js +17 -0
  26. package/dist/core/phone-auth/strategies/desktop.d.ts +2 -0
  27. package/dist/core/phone-auth/strategies/desktop.js +136 -13
  28. package/dist/core/phone-auth/strategies/index.d.ts +4 -0
  29. package/dist/core/phone-auth/strategies/index.js +4 -0
  30. package/dist/core/phone-auth/strategies/link.d.ts +2 -0
  31. package/dist/core/phone-auth/strategies/link.js +97 -13
  32. package/dist/core/phone-auth/strategies/ts43.d.ts +19 -0
  33. package/dist/core/phone-auth/strategies/ts43.js +33 -2
  34. package/dist/core/phone-auth/strategies/types.js +4 -0
  35. package/dist/core/phone-auth/type-guards.js +131 -0
  36. package/dist/core/phone-auth/types.d.ts +5 -0
  37. package/dist/core/phone-auth/types.js +32 -0
  38. package/dist/core/phone-auth/ui/mobile-debug-console.js +28 -2
  39. package/dist/core/phone-auth/ui/modal.d.ts +55 -33
  40. package/dist/core/phone-auth/ui/modal.js +422 -889
  41. package/dist/core/phone-auth/validation-utils.d.ts +0 -9
  42. package/dist/core/phone-auth/validation-utils.js +34 -25
  43. package/dist/core/version.js +2 -1
  44. package/dist/esm/adapters/angular/index.js +1 -0
  45. package/dist/esm/adapters/angular/phone-auth.service.d.ts +18 -0
  46. package/dist/esm/adapters/angular/phone-auth.service.js +26 -0
  47. package/dist/esm/adapters/react/index.js +3 -0
  48. package/dist/esm/adapters/react/useClient.js +1 -0
  49. package/dist/esm/adapters/react/usePhoneAuth.js +16 -1
  50. package/dist/esm/adapters/vanilla/client.js +1 -0
  51. package/dist/esm/adapters/vanilla/index.js +1 -0
  52. package/dist/esm/adapters/vanilla/phone-auth.d.ts +24 -0
  53. package/dist/esm/adapters/vanilla/phone-auth.js +31 -0
  54. package/dist/esm/adapters/vue/index.js +4 -0
  55. package/dist/esm/adapters/vue/useClient.js +5 -0
  56. package/dist/esm/adapters/vue/usePhoneAuth.js +20 -1
  57. package/dist/esm/browser.js +6 -0
  58. package/dist/esm/core/client.d.ts +10 -0
  59. package/dist/esm/core/client.js +12 -0
  60. package/dist/esm/core/logger.d.ts +53 -0
  61. package/dist/esm/core/logger.js +81 -1
  62. package/dist/esm/core/phone-auth/api-types.d.ts +312 -2
  63. package/dist/esm/core/phone-auth/api-types.js +83 -0
  64. package/dist/esm/core/phone-auth/client.d.ts +144 -0
  65. package/dist/esm/core/phone-auth/client.js +375 -39
  66. package/dist/esm/core/phone-auth/error-utils.d.ts +29 -0
  67. package/dist/esm/core/phone-auth/error-utils.js +83 -1
  68. package/dist/esm/core/phone-auth/index.d.ts +1 -1
  69. package/dist/esm/core/phone-auth/index.js +4 -2
  70. package/dist/esm/core/phone-auth/status-types.d.ts +78 -0
  71. package/dist/esm/core/phone-auth/status-types.js +17 -0
  72. package/dist/esm/core/phone-auth/strategies/desktop.d.ts +65 -0
  73. package/dist/esm/core/phone-auth/strategies/desktop.js +136 -13
  74. package/dist/esm/core/phone-auth/strategies/index.d.ts +4 -0
  75. package/dist/esm/core/phone-auth/strategies/index.js +4 -0
  76. package/dist/esm/core/phone-auth/strategies/link.d.ts +50 -0
  77. package/dist/esm/core/phone-auth/strategies/link.js +97 -13
  78. package/dist/esm/core/phone-auth/strategies/ts43.d.ts +19 -0
  79. package/dist/esm/core/phone-auth/strategies/ts43.js +33 -2
  80. package/dist/esm/core/phone-auth/strategies/types.d.ts +13 -0
  81. package/dist/esm/core/phone-auth/strategies/types.js +4 -0
  82. package/dist/esm/core/phone-auth/type-guards.d.ts +128 -0
  83. package/dist/esm/core/phone-auth/type-guards.js +131 -0
  84. package/dist/esm/core/phone-auth/types.d.ts +113 -0
  85. package/dist/esm/core/phone-auth/types.js +32 -0
  86. package/dist/esm/core/phone-auth/ui/mobile-debug-console.d.ts +4 -0
  87. package/dist/esm/core/phone-auth/ui/mobile-debug-console.js +28 -2
  88. package/dist/esm/core/phone-auth/ui/modal.d.ts +68 -27
  89. package/dist/esm/core/phone-auth/ui/modal.js +422 -889
  90. package/dist/esm/core/phone-auth/validation-utils.d.ts +26 -4
  91. package/dist/esm/core/phone-auth/validation-utils.js +34 -24
  92. package/dist/esm/core/types.d.ts +35 -0
  93. package/dist/esm/core/version.js +2 -1
  94. package/dist/esm/index.js +9 -1
  95. package/dist/index.js +7 -0
  96. package/package.json +1 -1
  97. package/dist/browser/web-client-sdk.min.js.LICENSE.txt +0 -1
package/dist/browser.js CHANGED
@@ -1,8 +1,12 @@
1
1
  "use strict";
2
+ // Browser-specific entry point for vanilla JavaScript usage
3
+ // This excludes framework-specific adapters that require Angular/React/Vue
2
4
  Object.defineProperty(exports, "__esModule", { value: true });
3
5
  exports.PhoneAuthManager = exports.ClientManager = exports.BrowserName = exports.BrowserErrorCode = exports.BrowserError = exports.AuthenticationStrategy = exports.UseCase = exports.createErrorBreadcrumb = exports.serializeError = exports.isRetryableError = exports.getRetryDelay = exports.isErrorCode = exports.getUserMessage = exports.isUserError = exports.isPhoneAuthError = exports.PhoneAuthErrorCode = exports.PhoneAuthClient = void 0;
6
+ // Phone Authentication - Core client
4
7
  var phone_auth_1 = require("./core/phone-auth");
5
8
  Object.defineProperty(exports, "PhoneAuthClient", { enumerable: true, get: function () { return phone_auth_1.PhoneAuthClient; } });
9
+ // Phone Auth Error Utilities
6
10
  var phone_auth_2 = require("./core/phone-auth");
7
11
  Object.defineProperty(exports, "PhoneAuthErrorCode", { enumerable: true, get: function () { return phone_auth_2.PhoneAuthErrorCode; } });
8
12
  Object.defineProperty(exports, "isPhoneAuthError", { enumerable: true, get: function () { return phone_auth_2.isPhoneAuthError; } });
@@ -13,12 +17,14 @@ Object.defineProperty(exports, "getRetryDelay", { enumerable: true, get: functio
13
17
  Object.defineProperty(exports, "isRetryableError", { enumerable: true, get: function () { return phone_auth_2.isRetryableError; } });
14
18
  Object.defineProperty(exports, "serializeError", { enumerable: true, get: function () { return phone_auth_2.serializeError; } });
15
19
  Object.defineProperty(exports, "createErrorBreadcrumb", { enumerable: true, get: function () { return phone_auth_2.createErrorBreadcrumb; } });
20
+ // Export constants for use case and strategy
16
21
  var types_1 = require("./core/phone-auth/types");
17
22
  Object.defineProperty(exports, "UseCase", { enumerable: true, get: function () { return types_1.USE_CASE; } });
18
23
  Object.defineProperty(exports, "AuthenticationStrategy", { enumerable: true, get: function () { return types_1.AUTHENTICATION_STRATEGY; } });
19
24
  Object.defineProperty(exports, "BrowserError", { enumerable: true, get: function () { return types_1.BrowserError; } });
20
25
  Object.defineProperty(exports, "BrowserErrorCode", { enumerable: true, get: function () { return types_1.BrowserErrorCode; } });
21
26
  Object.defineProperty(exports, "BrowserName", { enumerable: true, get: function () { return types_1.BrowserName; } });
27
+ // Vanilla adapters ONLY (no framework dependencies)
22
28
  var client_1 = require("./adapters/vanilla/client");
23
29
  Object.defineProperty(exports, "ClientManager", { enumerable: true, get: function () { return client_1.VanillaClient; } });
24
30
  var phone_auth_3 = require("./adapters/vanilla/phone-auth");
@@ -25,6 +25,7 @@ class SDKClient {
25
25
  'Content-Type': 'application/json',
26
26
  },
27
27
  });
28
+ // Initialize Phone Auth client
28
29
  this.phoneAuth = new phone_auth_1.PhoneAuthClient({
29
30
  endpoints: config.phoneAuthEndpoints ? {
30
31
  prepare: config.phoneAuthEndpoints.prepareRequest,
@@ -32,6 +33,7 @@ class SDKClient {
32
33
  } : undefined,
33
34
  debug: config.debug
34
35
  });
36
+ // Add authentication interceptor
35
37
  this.client.interceptors.request.use((config) => __awaiter(this, void 0, void 0, function* () {
36
38
  if (this.token) {
37
39
  config.headers.Authorization = `Bearer ${this.token}`;
@@ -39,12 +41,22 @@ class SDKClient {
39
41
  return config;
40
42
  }));
41
43
  }
44
+ /**
45
+ * Set authentication token for API requests
46
+ */
42
47
  setToken(token) {
43
48
  this.token = token;
44
49
  }
50
+ /**
51
+ * Clear authentication token
52
+ */
45
53
  clearToken() {
46
54
  this.token = undefined;
47
55
  }
56
+ /**
57
+ * Make a GET request to the API
58
+ * Note: Requires baseURL to be set in the config
59
+ */
48
60
  get(path, options) {
49
61
  return __awaiter(this, void 0, void 0, function* () {
50
62
  if (!this.config.baseURL) {
@@ -1,4 +1,8 @@
1
1
  "use strict";
2
+ /**
3
+ * Industry-grade logging for Glide Web SDK
4
+ * Following best practices from Stripe, Auth0, Twilio, and AWS Amplify
5
+ */
2
6
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
7
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
8
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -21,6 +25,9 @@ var LogLevel;
21
25
  LogLevel[LogLevel["INFO"] = 3] = "INFO";
22
26
  LogLevel[LogLevel["DEBUG"] = 4] = "DEBUG";
23
27
  })(LogLevel || (exports.LogLevel = LogLevel = {}));
28
+ /**
29
+ * Default browser console logger with automatic data sanitization
30
+ */
24
31
  class ConsoleLogger {
25
32
  constructor(level = LogLevel.SILENT, prefix = '[Glide]', enableGrouping = false) {
26
33
  this.level = level;
@@ -50,7 +57,9 @@ class ConsoleLogger {
50
57
  log(level, message, fields) {
51
58
  const timestamp = new Date().toISOString();
52
59
  const sanitizedFields = fields ? this.sanitizeFields(fields) : {};
60
+ // Format the message
53
61
  const formattedMessage = `${this.prefix} ${timestamp} [${level.toUpperCase()}] ${message}`;
62
+ // Use console grouping for better readability if enabled
54
63
  if (this.enableGrouping && Object.keys(sanitizedFields).length > 0) {
55
64
  console.groupCollapsed(formattedMessage);
56
65
  Object.entries(sanitizedFields).forEach(([key, value]) => {
@@ -59,6 +68,7 @@ class ConsoleLogger {
59
68
  console.groupEnd();
60
69
  }
61
70
  else {
71
+ // Standard logging with or without fields
62
72
  if (Object.keys(sanitizedFields).length > 0) {
63
73
  console[level](formattedMessage, sanitizedFields);
64
74
  }
@@ -67,6 +77,9 @@ class ConsoleLogger {
67
77
  }
68
78
  }
69
79
  }
80
+ /**
81
+ * Sanitize sensitive data from log fields
82
+ */
70
83
  sanitizeFields(fields) {
71
84
  const sanitized = {};
72
85
  for (const [key, value] of Object.entries(fields)) {
@@ -74,7 +87,11 @@ class ConsoleLogger {
74
87
  }
75
88
  return sanitized;
76
89
  }
90
+ /**
91
+ * Redact sensitive information based on field name and value patterns
92
+ */
77
93
  sanitizeValue(key, value) {
94
+ // List of sensitive field patterns
78
95
  const sensitiveFields = [
79
96
  'apikey', 'api_key', 'apiKey',
80
97
  'token', 'accesstoken', 'access_token', 'accessToken',
@@ -84,6 +101,7 @@ class ConsoleLogger {
84
101
  'cookie', 'session',
85
102
  ];
86
103
  const lowerKey = key.toLowerCase();
104
+ // Check if field name indicates sensitive data
87
105
  for (const sensitive of sensitiveFields) {
88
106
  if (lowerKey.includes(sensitive.toLowerCase())) {
89
107
  if (typeof value === 'string' && value.length > 4) {
@@ -92,30 +110,38 @@ class ConsoleLogger {
92
110
  return '****[REDACTED]';
93
111
  }
94
112
  }
113
+ // Handle specific value patterns
95
114
  if (typeof value === 'string') {
115
+ // Phone number pattern - show area code only
96
116
  const phoneRegex = /^\+?[1-9]\d{6,14}$/;
97
117
  if (phoneRegex.test(value)) {
98
118
  return value.substring(0, 6) + '****';
99
119
  }
120
+ // Email pattern - show domain only
100
121
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
101
122
  if (emailRegex.test(value)) {
102
123
  const [, domain] = value.split('@');
103
124
  return '****@' + domain;
104
125
  }
126
+ // URL with credentials
105
127
  if (value.includes('://') && value.includes('@')) {
106
128
  return value.replace(/\/\/([^:]+):([^@]+)@/, '//****:****@');
107
129
  }
130
+ // JWT tokens
108
131
  if (value.startsWith('eyJ') && value.split('.').length === 3) {
109
132
  return value.substring(0, 10) + '****[JWT]';
110
133
  }
134
+ // Credit card numbers
111
135
  const creditCardRegex = /\b\d{13,19}\b/;
112
136
  if (creditCardRegex.test(value)) {
113
137
  return value.substring(0, 4) + '****' + value.substring(value.length - 4);
114
138
  }
115
139
  }
140
+ // Recursively sanitize objects
116
141
  if (value && typeof value === 'object' && !Array.isArray(value)) {
117
142
  return this.sanitizeFields(value);
118
143
  }
144
+ // Sanitize arrays
119
145
  if (Array.isArray(value)) {
120
146
  return value.map((item, index) => this.sanitizeValue(`${key}[${index}]`, item));
121
147
  }
@@ -123,6 +149,9 @@ class ConsoleLogger {
123
149
  }
124
150
  }
125
151
  exports.ConsoleLogger = ConsoleLogger;
152
+ /**
153
+ * No-op logger for when logging is disabled
154
+ */
126
155
  class NoopLogger {
127
156
  debug(message, fields) { }
128
157
  info(message, fields) { }
@@ -130,16 +159,22 @@ class NoopLogger {
130
159
  error(message, fields) { }
131
160
  }
132
161
  exports.NoopLogger = NoopLogger;
162
+ /**
163
+ * Remote logger for sending logs to a backend service
164
+ * Useful for debugging production issues
165
+ */
133
166
  class RemoteLogger {
134
167
  constructor(endpoint, apiKey, fallbackLogger) {
135
168
  this.buffer = [];
136
- this.flushInterval = 5000;
169
+ this.flushInterval = 5000; // 5 seconds
137
170
  this.maxBufferSize = 100;
138
171
  this.endpoint = endpoint;
139
172
  this.apiKey = apiKey;
140
173
  this.localLogger = fallbackLogger || new ConsoleLogger(LogLevel.ERROR);
174
+ // Set up automatic flushing
141
175
  if (typeof window !== 'undefined') {
142
176
  setInterval(() => this.flush(), this.flushInterval);
177
+ // Flush on page unload
143
178
  window.addEventListener('beforeunload', () => this.flush());
144
179
  }
145
180
  }
@@ -165,7 +200,9 @@ class RemoteLogger {
165
200
  url: typeof window !== 'undefined' ? window.location.href : undefined,
166
201
  };
167
202
  this.buffer.push(logEntry);
203
+ // Also log locally for immediate feedback
168
204
  this.localLogger[level](message, fields);
205
+ // Flush if buffer is full
169
206
  if (this.buffer.length >= this.maxBufferSize) {
170
207
  this.flush();
171
208
  }
@@ -187,12 +224,18 @@ class RemoteLogger {
187
224
  });
188
225
  }
189
226
  catch (error) {
227
+ // Failed to send logs, log locally
190
228
  this.localLogger.error('Failed to send logs to remote server', { error });
229
+ // Optionally, put logs back in buffer for retry
230
+ // this.buffer.unshift(...logs);
191
231
  }
192
232
  });
193
233
  }
194
234
  }
195
235
  exports.RemoteLogger = RemoteLogger;
236
+ /**
237
+ * Parse log level from string
238
+ */
196
239
  function parseLogLevel(level) {
197
240
  switch (level.toLowerCase()) {
198
241
  case 'debug':
@@ -212,7 +255,11 @@ function parseLogLevel(level) {
212
255
  return LogLevel.SILENT;
213
256
  }
214
257
  }
258
+ /**
259
+ * Get log level from browser environment
260
+ */
215
261
  function getLogLevelFromEnv() {
262
+ // Check localStorage
216
263
  if (typeof localStorage !== 'undefined') {
217
264
  const storedLevel = localStorage.getItem('GLIDE_LOG_LEVEL');
218
265
  if (storedLevel) {
@@ -223,6 +270,7 @@ function getLogLevelFromEnv() {
223
270
  return LogLevel.DEBUG;
224
271
  }
225
272
  }
273
+ // Check URL parameters
226
274
  if (typeof window !== 'undefined' && window.location) {
227
275
  const params = new URLSearchParams(window.location.search);
228
276
  const urlLogLevel = params.get('glide_log_level');
@@ -235,19 +283,31 @@ function getLogLevelFromEnv() {
235
283
  }
236
284
  return LogLevel.SILENT;
237
285
  }
286
+ /**
287
+ * Performance timer for measuring operation duration
288
+ */
238
289
  class PerformanceTimer {
239
290
  constructor(logger) {
240
291
  this.marks = new Map();
241
292
  this.startTime = performance.now();
242
293
  this.logger = logger;
243
294
  }
295
+ /**
296
+ * Mark a point in time
297
+ */
244
298
  mark(name) {
245
299
  this.marks.set(name, performance.now());
246
300
  }
301
+ /**
302
+ * Log elapsed time with optional fields
303
+ */
247
304
  logElapsed(message, fields) {
248
305
  const elapsed = performance.now() - this.startTime;
249
306
  this.logger.debug(message, Object.assign(Object.assign({}, fields), { elapsedMs: elapsed, elapsed: `${elapsed.toFixed(2)}ms` }));
250
307
  }
308
+ /**
309
+ * Log time between marks
310
+ */
251
311
  logMarkDuration(fromMark, toMark, message, fields) {
252
312
  const from = this.marks.get(fromMark);
253
313
  const to = this.marks.get(toMark);
@@ -259,29 +319,49 @@ class PerformanceTimer {
259
319
  }
260
320
  }
261
321
  exports.PerformanceTimer = PerformanceTimer;
322
+ /**
323
+ * Generate a unique request ID for distributed tracing
324
+ */
262
325
  function generateRequestId() {
263
326
  return `req_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
264
327
  }
328
+ /**
329
+ * Logger factory for creating loggers with consistent configuration
330
+ */
265
331
  class LoggerFactory {
332
+ /**
333
+ * Set the default log level for all new loggers
334
+ */
266
335
  static setDefaultLevel(level) {
267
336
  this.defaultLevel = level;
268
337
  }
338
+ /**
339
+ * Set a default logger instance to use
340
+ */
269
341
  static setDefaultLogger(logger) {
270
342
  this.defaultLogger = logger;
271
343
  }
344
+ /**
345
+ * Create a logger instance based on configuration
346
+ */
272
347
  static create(options) {
273
348
  var _a, _b;
349
+ // Use custom logger if provided
274
350
  if (options === null || options === void 0 ? void 0 : options.custom) {
275
351
  return options.custom;
276
352
  }
353
+ // Use default logger if set
277
354
  if (this.defaultLogger) {
278
355
  return this.defaultLogger;
279
356
  }
357
+ // Determine log level
280
358
  const level = (_b = (_a = options === null || options === void 0 ? void 0 : options.level) !== null && _a !== void 0 ? _a : getLogLevelFromEnv()) !== null && _b !== void 0 ? _b : this.defaultLevel;
359
+ // Create remote logger if configured
281
360
  if (options === null || options === void 0 ? void 0 : options.remote) {
282
361
  const fallbackLogger = new ConsoleLogger(level, options === null || options === void 0 ? void 0 : options.prefix);
283
362
  return new RemoteLogger(options.remote.endpoint, options.remote.apiKey, fallbackLogger);
284
363
  }
364
+ // Create console logger
285
365
  return new ConsoleLogger(level, options === null || options === void 0 ? void 0 : options.prefix);
286
366
  }
287
367
  }
@@ -25,8 +25,6 @@ export interface SessionInfo {
25
25
  session_key: string;
26
26
  /** Security nonce */
27
27
  nonce?: string;
28
- /** Encryption key for secure operations */
29
- enc_key?: string;
30
28
  /** Additional metadata from server */
31
29
  metadata?: Record<string, string>;
32
30
  }
@@ -82,7 +80,7 @@ export interface PrepareOptions {
82
80
  }
83
81
  /**
84
82
  * Request to prepare authentication session
85
- * Note: nonce and id are auto-generated by SDKs if not provided
83
+ * Note: id is auto-generated by SDK if not provided
86
84
  */
87
85
  export interface PrepareRequest {
88
86
  /** Use case for this authentication (optional when parent_session_id is provided - inherited from parent) */
@@ -92,9 +90,6 @@ export interface PrepareRequest {
92
90
  phone_number?: PhoneNumber;
93
91
  /** Alternative to phone_number */
94
92
  plmn?: PLMN;
95
- /** Optional: Auto-generated by SDKs if not provided */
96
- /** Unique nonce (SDK generates secure random if not provided) */
97
- nonce?: string;
98
93
  /** Request identifier (SDK generates unique ID if not provided) */
99
94
  id?: string;
100
95
  /** Optional fields */
@@ -1,4 +1,16 @@
1
1
  "use strict";
2
+ /**
3
+ * Glide Phone Authentication API Types
4
+ *
5
+ * This file is copied from the master API specification at /glide-api-types.ts
6
+ * It defines the exact contract that ALL implementations must follow.
7
+ *
8
+ * NAMING CONVENTION:
9
+ * - ALL TYPES USE snake_case FOR API COMMUNICATION
10
+ * - Frontend SDKs should use snake_case throughout for consistency
11
+ * - This eliminates conversion errors and makes debugging easier
12
+ * - While not idiomatic JavaScript, it matches the API exactly
13
+ */
2
14
  Object.defineProperty(exports, "__esModule", { value: true });
3
15
  exports.E164_REGEX = exports.ERROR_STATUS_CODES = exports.ERROR_MESSAGES = exports.ERROR_CODE = exports.AUTHENTICATION_STRATEGY = exports.USE_CASE = void 0;
4
16
  exports.validatePhoneNumber = validatePhoneNumber;
@@ -10,31 +22,52 @@ exports.getErrorStatusCode = getErrorStatusCode;
10
22
  exports.isTS43Data = isTS43Data;
11
23
  exports.isLinkData = isLinkData;
12
24
  exports.isErrorResponse = isErrorResponse;
25
+ // ============================================================================
26
+ // USE CASES
27
+ // ============================================================================
13
28
  exports.USE_CASE = {
14
29
  GET_PHONE_NUMBER: 'GetPhoneNumber',
15
30
  VERIFY_PHONE_NUMBER: 'VerifyPhoneNumber'
16
31
  };
32
+ // ============================================================================
33
+ // AUTHENTICATION STRATEGIES
34
+ // ============================================================================
17
35
  exports.AUTHENTICATION_STRATEGY = {
18
36
  TS43: 'ts43',
19
37
  LINK: 'link',
20
38
  DESKTOP: 'desktop'
21
39
  };
40
+ // ============================================================================
41
+ // ERROR HANDLING
42
+ // ============================================================================
43
+ /**
44
+ * Error codes - MUST match server implementation
45
+ */
22
46
  exports.ERROR_CODE = {
47
+ // 400 Bad Request
23
48
  INVALID_PHONE_NUMBER: 'INVALID_PHONE_NUMBER',
24
49
  MISSING_REQUIRED_FIELD: 'MISSING_REQUIRED_FIELD',
25
50
  INVALID_USE_CASE: 'INVALID_USE_CASE',
51
+ // 404 Not Found
26
52
  INVALID_SESSION: 'INVALID_SESSION',
27
53
  SESSION_EXPIRED: 'SESSION_EXPIRED',
54
+ // 422 Unprocessable Entity
28
55
  CARRIER_NOT_ELIGIBLE: 'CARRIER_NOT_ELIGIBLE',
29
56
  UNSUPPORTED_PLATFORM: 'UNSUPPORTED_PLATFORM',
30
57
  PHONE_NUMBER_MISMATCH: 'PHONE_NUMBER_MISMATCH',
31
58
  INVALID_CREDENTIAL: 'INVALID_CREDENTIAL',
32
59
  VERIFICATION_FAILED: 'VERIFICATION_FAILED',
33
60
  USE_CASE_MISMATCH: 'USE_CASE_MISMATCH',
61
+ // 429 Too Many Requests
34
62
  RATE_LIMIT_EXCEEDED: 'RATE_LIMIT_EXCEEDED',
63
+ // 500 Internal Server Error
35
64
  INTERNAL_SERVER_ERROR: 'INTERNAL_SERVER_ERROR',
65
+ // 503 Service Unavailable
36
66
  SERVICE_UNAVAILABLE: 'SERVICE_UNAVAILABLE'
37
67
  };
68
+ /**
69
+ * Error messages - User-friendly messages for each error code
70
+ */
38
71
  exports.ERROR_MESSAGES = {
39
72
  [exports.ERROR_CODE.INVALID_PHONE_NUMBER]: "Phone number must be in E.164 format",
40
73
  [exports.ERROR_CODE.MISSING_REQUIRED_FIELD]: "Required field is missing",
@@ -51,6 +84,9 @@ exports.ERROR_MESSAGES = {
51
84
  [exports.ERROR_CODE.INTERNAL_SERVER_ERROR]: "An unexpected error occurred",
52
85
  [exports.ERROR_CODE.SERVICE_UNAVAILABLE]: "Service temporarily unavailable"
53
86
  };
87
+ /**
88
+ * HTTP status codes for each error
89
+ */
54
90
  exports.ERROR_STATUS_CODES = {
55
91
  [exports.ERROR_CODE.INVALID_PHONE_NUMBER]: 400,
56
92
  [exports.ERROR_CODE.MISSING_REQUIRED_FIELD]: 400,
@@ -67,26 +103,50 @@ exports.ERROR_STATUS_CODES = {
67
103
  [exports.ERROR_CODE.INTERNAL_SERVER_ERROR]: 500,
68
104
  [exports.ERROR_CODE.SERVICE_UNAVAILABLE]: 503
69
105
  };
106
+ // ============================================================================
107
+ // VALIDATION HELPERS
108
+ // ============================================================================
109
+ /**
110
+ * E.164 phone number validation regex
111
+ */
70
112
  exports.E164_REGEX = /^\+[1-9]\d{1,14}$/;
113
+ /**
114
+ * Validate phone number format
115
+ */
71
116
  function validatePhoneNumber(phone) {
72
117
  return exports.E164_REGEX.test(phone);
73
118
  }
119
+ /**
120
+ * Validate PLMN format
121
+ */
74
122
  function validatePLMN(plmn) {
123
+ // MCC: exactly 3 digits
75
124
  if (!/^\d{3}$/.test(plmn.mcc))
76
125
  return false;
126
+ // MNC: 2 or 3 digits
77
127
  if (!/^\d{2,3}$/.test(plmn.mnc))
78
128
  return false;
79
129
  return true;
80
130
  }
131
+ /**
132
+ * Validate session info
133
+ */
81
134
  function validateSession(session) {
82
135
  if (!session.session_key || session.session_key.length < 16)
83
136
  return false;
137
+ // nonce is optional and stored in metadata if needed
84
138
  return true;
85
139
  }
140
+ /**
141
+ * Validate use case
142
+ */
86
143
  function validateUseCase(useCase) {
87
144
  return useCase === exports.USE_CASE.GET_PHONE_NUMBER ||
88
145
  useCase === exports.USE_CASE.VERIFY_PHONE_NUMBER;
89
146
  }
147
+ /**
148
+ * Create error response helper
149
+ */
90
150
  function createErrorResponse(code, details, requestId) {
91
151
  return {
92
152
  code,
@@ -96,37 +156,60 @@ function createErrorResponse(code, details, requestId) {
96
156
  details
97
157
  };
98
158
  }
159
+ /**
160
+ * Get HTTP status code for error
161
+ */
99
162
  function getErrorStatusCode(code) {
100
163
  return exports.ERROR_STATUS_CODES[code] || 500;
101
164
  }
165
+ // ============================================================================
166
+ // TYPE GUARDS
167
+ // ============================================================================
168
+ /**
169
+ * Check if data is TS43 strategy data
170
+ */
102
171
  function isTS43Data(data) {
172
+ // Check for TS43 data structure - has protocol and data.dcql_query
103
173
  return data &&
104
174
  typeof data.protocol === 'string' &&
105
175
  data.data &&
106
176
  data.data.dcql_query;
107
177
  }
178
+ /**
179
+ * Check if data is Link strategy data
180
+ */
108
181
  function isLinkData(data) {
109
182
  return data && data.url && typeof data.url === 'string';
110
183
  }
184
+ /**
185
+ * Check if response is an error
186
+ */
111
187
  function isErrorResponse(response) {
112
188
  return response &&
113
189
  typeof response.code === 'string' &&
114
190
  typeof response.message === 'string';
115
191
  }
192
+ // ============================================================================
193
+ // EXPORTS FOR CONVENIENCE
194
+ // ============================================================================
116
195
  exports.default = {
196
+ // Constants
117
197
  USE_CASE: exports.USE_CASE,
118
198
  AUTHENTICATION_STRATEGY: exports.AUTHENTICATION_STRATEGY,
119
199
  ERROR_CODE: exports.ERROR_CODE,
120
200
  ERROR_MESSAGES: exports.ERROR_MESSAGES,
121
201
  ERROR_STATUS_CODES: exports.ERROR_STATUS_CODES,
122
202
  E164_REGEX: exports.E164_REGEX,
203
+ // Validators
123
204
  validatePhoneNumber,
124
205
  validatePLMN,
125
206
  validateSession,
126
207
  validateUseCase,
208
+ // Type guards
127
209
  isTS43Data,
128
210
  isLinkData,
129
211
  isErrorResponse,
212
+ // Helpers
130
213
  createErrorResponse,
131
214
  getErrorStatusCode
132
215
  };