@optique/config 1.0.0-dev.1163 → 1.0.0-dev.1169

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.cjs CHANGED
@@ -327,6 +327,29 @@ function getTypeName(value) {
327
327
  if (Array.isArray(value)) return "array";
328
328
  return typeof value;
329
329
  }
330
+ function isPromiseLike(value) {
331
+ return value != null && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function";
332
+ }
333
+ /**
334
+ * Detects native Promises and cross-realm Promises. Cross-realm
335
+ * Promises fail `instanceof Promise` but still carry the spec-required
336
+ * `Symbol.toStringTag === "Promise"`. Domain objects that merely
337
+ * define a `then()` method are not matched unless they also set
338
+ * `Symbol.toStringTag` to `"Promise"`.
339
+ */
340
+ function isPromise(value) {
341
+ if (value instanceof Promise) return true;
342
+ if (value == null || typeof value !== "object" && typeof value !== "function") return false;
343
+ return isPromiseLike(value) && value[Symbol.toStringTag] === "Promise";
344
+ }
345
+ function validateLoadResult(loaded) {
346
+ if (loaded == null || typeof loaded !== "object" || Array.isArray(loaded)) throw new TypeError(`Expected load() to return an object, but got: ${getTypeName(loaded)}.`);
347
+ if (!("config" in loaded)) throw new TypeError("Expected load() result to have a config property.");
348
+ const result = loaded;
349
+ if (isPromise(result.config)) throw new TypeError("Expected config in load() result to not be a Promise. Resolve the Promise before returning.");
350
+ if (isPromise(result.meta)) throw new TypeError("Expected meta in load() result to not be a Promise. Resolve the Promise before returning.");
351
+ return loaded;
352
+ }
330
353
  function isStandardSchema(value) {
331
354
  if (value == null || typeof value !== "object" && typeof value !== "function") return false;
332
355
  if (!("~standard" in value)) return false;
@@ -426,8 +449,13 @@ function createConfigContext(options) {
426
449
  };
427
450
  if (opts.load) {
428
451
  const loaded = opts.load(parsedPlaceholder);
429
- if (loaded instanceof Promise) return loaded.then(({ config, meta }) => validateAndBuildAnnotations(config, meta));
430
- return validateAndBuildAnnotations(loaded.config, loaded.meta);
452
+ if (isPromise(loaded)) return Promise.resolve(loaded).then((resolved) => {
453
+ const validated$1 = validateLoadResult(resolved);
454
+ return validateAndBuildAnnotations(validated$1.config, validated$1.meta);
455
+ });
456
+ if (isPromiseLike(loaded)) throw new TypeError("Expected load() to return a plain object or Promise, but got a thenable. Use a real Promise instead.");
457
+ const validated = validateLoadResult(loaded);
458
+ return validateAndBuildAnnotations(validated.config, validated.meta);
431
459
  }
432
460
  if (opts.getConfigPath) {
433
461
  const configPath = opts.getConfigPath(parsedPlaceholder);
package/dist/index.js CHANGED
@@ -304,6 +304,29 @@ function getTypeName(value) {
304
304
  if (Array.isArray(value)) return "array";
305
305
  return typeof value;
306
306
  }
307
+ function isPromiseLike(value) {
308
+ return value != null && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function";
309
+ }
310
+ /**
311
+ * Detects native Promises and cross-realm Promises. Cross-realm
312
+ * Promises fail `instanceof Promise` but still carry the spec-required
313
+ * `Symbol.toStringTag === "Promise"`. Domain objects that merely
314
+ * define a `then()` method are not matched unless they also set
315
+ * `Symbol.toStringTag` to `"Promise"`.
316
+ */
317
+ function isPromise(value) {
318
+ if (value instanceof Promise) return true;
319
+ if (value == null || typeof value !== "object" && typeof value !== "function") return false;
320
+ return isPromiseLike(value) && value[Symbol.toStringTag] === "Promise";
321
+ }
322
+ function validateLoadResult(loaded) {
323
+ if (loaded == null || typeof loaded !== "object" || Array.isArray(loaded)) throw new TypeError(`Expected load() to return an object, but got: ${getTypeName(loaded)}.`);
324
+ if (!("config" in loaded)) throw new TypeError("Expected load() result to have a config property.");
325
+ const result = loaded;
326
+ if (isPromise(result.config)) throw new TypeError("Expected config in load() result to not be a Promise. Resolve the Promise before returning.");
327
+ if (isPromise(result.meta)) throw new TypeError("Expected meta in load() result to not be a Promise. Resolve the Promise before returning.");
328
+ return loaded;
329
+ }
307
330
  function isStandardSchema(value) {
308
331
  if (value == null || typeof value !== "object" && typeof value !== "function") return false;
309
332
  if (!("~standard" in value)) return false;
@@ -403,8 +426,13 @@ function createConfigContext(options) {
403
426
  };
404
427
  if (opts.load) {
405
428
  const loaded = opts.load(parsedPlaceholder);
406
- if (loaded instanceof Promise) return loaded.then(({ config, meta }) => validateAndBuildAnnotations(config, meta));
407
- return validateAndBuildAnnotations(loaded.config, loaded.meta);
429
+ if (isPromise(loaded)) return Promise.resolve(loaded).then((resolved) => {
430
+ const validated$1 = validateLoadResult(resolved);
431
+ return validateAndBuildAnnotations(validated$1.config, validated$1.meta);
432
+ });
433
+ if (isPromiseLike(loaded)) throw new TypeError("Expected load() to return a plain object or Promise, but got a thenable. Use a real Promise instead.");
434
+ const validated = validateLoadResult(loaded);
435
+ return validateAndBuildAnnotations(validated.config, validated.meta);
408
436
  }
409
437
  if (opts.getConfigPath) {
410
438
  const configPath = opts.getConfigPath(parsedPlaceholder);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optique/config",
3
- "version": "1.0.0-dev.1163+65b042cd",
3
+ "version": "1.0.0-dev.1169+d2c2243d",
4
4
  "description": "Configuration file support for Optique with Standard Schema validation",
5
5
  "keywords": [
6
6
  "CLI",
@@ -59,7 +59,7 @@
59
59
  "@standard-schema/spec": "^1.1.0"
60
60
  },
61
61
  "dependencies": {
62
- "@optique/core": "1.0.0-dev.1163+65b042cd"
62
+ "@optique/core": "1.0.0-dev.1169+d2c2243d"
63
63
  },
64
64
  "devDependencies": {
65
65
  "@standard-schema/spec": "^1.1.0",
@@ -67,7 +67,7 @@
67
67
  "tsdown": "^0.13.0",
68
68
  "typescript": "^5.8.3",
69
69
  "zod": "^3.25.0 || ^4.0.0",
70
- "@optique/env": "1.0.0-dev.1163+65b042cd"
70
+ "@optique/env": "1.0.0-dev.1169+d2c2243d"
71
71
  },
72
72
  "scripts": {
73
73
  "build": "tsdown",