serialize()

in packages/@jsii/kernel/src/serialization.ts [659:765]


    serialize(value, _type, host) {
      if (value == null) {
        return undefined;
      }

      if (isDate(value)) {
        return serializeDate(value);
      }
      if (isScalar(value)) {
        return value;
      }
      if (Array.isArray(value)) {
        return value.map((e, idx) =>
          process(
            host,
            'serialize',
            e,
            { type: spec.CANONICAL_ANY },
            `index ${inspect(idx)}`,
          ),
        );
      }

      // Note: no case for "ENUM" here, without type declaration we can't tell the difference
      // between an enum member and a scalar.

      if (typeof value === 'function') {
        throw new SerializationError(
          'Functions cannot be passed across language boundaries',
          value,
          host,
        );
      }

      if (typeof value !== 'object' || value == null) {
        throw new SerializationError(
          `A jsii kernel assumption was violated: value is not an object`,
          value,
          host,
        );
      }

      if (
        SYMBOL_WIRE_TYPE in value &&
        (value as any)[SYMBOL_WIRE_TYPE] === TOKEN_MAP
      ) {
        return SERIALIZERS[SerializationClass.Map].serialize(
          value,
          {
            type: {
              collection: {
                kind: spec.CollectionKind.Map,
                elementtype: spec.CANONICAL_ANY,
              },
            },
          },
          host,
        );
      }

      // To make sure people aren't going to try and return Map<> or Set<> out, test for
      // those and throw a descriptive error message. We can't detect these cases any other
      // way, and the by-value serialized object will be quite useless.
      if (value instanceof Set || value instanceof Map) {
        throw new SerializationError(
          'Set and Map instances cannot be sent across the language boundary',
          value,
          host,
        );
      }

      // Use a previous reference to maintain object identity. NOTE: this may cause us to return
      // a different type than requested! This is just how it is right now.
      // https://github.com/aws/jsii/issues/399
      const prevRef = objectReference(value);
      if (prevRef) {
        return prevRef;
      }

      // If this is or should be a reference type, pass or make the reference
      // (Like regular reftype serialization, but without the type derivation to an interface)
      const jsiiType =
        jsiiTypeFqn(value, host.isVisibleType) ??
        (isByReferenceOnly(value) ? EMPTY_OBJECT_FQN : undefined);
      if (jsiiType) {
        return host.objects.registerObject(value, jsiiType);
      }

      // At this point we have an object that is not of an exported type. Either an object
      // literal, or an instance of a fully private class (cannot distinguish those cases).

      // We will serialize by-value, but recurse for serialization so that if
      // the object contains reference objects, they will be serialized appropriately.
      // (Basically, serialize anything else as a map of 'any').
      return mapValues(
        value,
        (v, key) =>
          process(
            host,
            'serialize',
            v,
            { type: spec.CANONICAL_ANY },
            `key ${inspect(key)}`,
          ),
        host,
      );
    },