properties.ts 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. /**
  2. * Property helper functions.
  3. *
  4. * @_subsection api/utils:Properties [about-properties]
  5. */
  6. function checkType(value: any, type: string, name: string): void {
  7. const types = type.split("|").map(t => t.trim());
  8. for (let i = 0; i < types.length; i++) {
  9. switch (type) {
  10. case "any":
  11. return;
  12. case "bigint":
  13. case "boolean":
  14. case "number":
  15. case "string":
  16. if (typeof(value) === type) { return; }
  17. }
  18. }
  19. const error: any = new Error(`invalid value for type ${ type }`);
  20. error.code = "INVALID_ARGUMENT";
  21. error.argument = `value.${ name }`;
  22. error.value = value;
  23. throw error;
  24. }
  25. /**
  26. * Resolves to a new object that is a copy of %%value%%, but with all
  27. * values resolved.
  28. */
  29. export async function resolveProperties<T>(value: { [ P in keyof T ]: T[P] | Promise<T[P]>}): Promise<T> {
  30. const keys = Object.keys(value);
  31. const results = await Promise.all(keys.map((k) => Promise.resolve(value[<keyof T>k])));
  32. return results.reduce((accum: any, v, index) => {
  33. accum[keys[index]] = v;
  34. return accum;
  35. }, <{ [ P in keyof T]: T[P] }>{ });
  36. }
  37. /**
  38. * Assigns the %%values%% to %%target%% as read-only values.
  39. *
  40. * It %%types%% is specified, the values are checked.
  41. */
  42. export function defineProperties<T>(
  43. target: T,
  44. values: { [ K in keyof T ]?: T[K] },
  45. types?: { [ K in keyof T ]?: string }): void {
  46. for (let key in values) {
  47. let value = values[key];
  48. const type = (types ? types[key]: null);
  49. if (type) { checkType(value, type, key); }
  50. Object.defineProperty(target, key, { enumerable: true, value, writable: false });
  51. }
  52. }