export function onOperation()

in src/v2/providers/storage.ts [293:375]


export function onOperation(
  eventType: string,
  bucketOrOptsOrHandler:
    | string
    | StorageOptions
    | ((event: CloudEvent<StorageObjectData>) => any | Promise<any>),
  handler: (event: CloudEvent<StorageObjectData>) => any | Promise<any>
): CloudFunction<StorageObjectData> {
  if (typeof bucketOrOptsOrHandler === 'function') {
    handler = bucketOrOptsOrHandler as (
      event: CloudEvent<StorageObjectData>
    ) => any | Promise<any>;
    bucketOrOptsOrHandler = {};
  }

  const [opts, bucket] = getOptsAndBucket(
    bucketOrOptsOrHandler as string | StorageOptions
  );

  const func = (raw: CloudEvent<unknown>) => {
    return handler(raw as CloudEvent<StorageObjectData>);
  };

  func.run = handler;

  Object.defineProperty(func, '__trigger', {
    get: () => {
      const baseOpts = options.optionsToTriggerAnnotations(
        options.getGlobalOptions()
      );
      const specificOpts = options.optionsToTriggerAnnotations(opts);

      return {
        platform: 'gcfv2',
        ...baseOpts,
        ...specificOpts,
        labels: {
          ...baseOpts?.labels,
          ...specificOpts?.labels,
        },
        eventTrigger: {
          eventType,
          resource: bucket, // TODO(colerogers): replace with 'bucket,' eventually
        },
      };
    },
  });

  // TypeScript doesn't recognize defineProperty as adding a property and complains
  // that __endpoint doesn't exist. We can either cast to any and lose all type safety
  // or we can just assign a meaningless value before calling defineProperty.
  func.__endpoint = {} as ManifestEndpoint;

  // SDK may attempt to read FIREBASE_CONFIG env var to fetch the default bucket name.
  // To prevent runtime errors when FIREBASE_CONFIG env var is missing, we use getters.
  Object.defineProperty(func, '__endpoint', {
    get: () => {
      const baseOpts = options.optionsToEndpoint(options.getGlobalOptions());
      const specificOpts = options.optionsToEndpoint(opts);

      const endpoint: ManifestEndpoint = {
        platform: 'gcfv2',
        ...baseOpts,
        ...specificOpts,
        labels: {
          ...baseOpts?.labels,
          ...specificOpts?.labels,
        },
        eventTrigger: {
          eventType,
          eventFilters: {
            bucket,
          },
          retry: false,
        },
      };
      copyIfPresent(endpoint.eventTrigger, opts, 'retry', 'retry');
      return endpoint;
    },
  });

  return func;
}