Skip to content

Firestore context params bind #75

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 45 additions & 11 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

import { has, merge, random, get } from 'lodash';
import { has, merge, random, get, forEach, split, indexOf } from 'lodash';

import { CloudFunction, EventContext, Change, https } from 'firebase-functions';
import { QueryDocumentSnapshot } from 'firebase-functions/lib/providers/firestore';

/** Fields of the event context that can be overridden/customized. */
export type EventContextOptions = {
Expand Down Expand Up @@ -153,7 +154,7 @@ export function wrap<T>(
['eventId', 'timestamp', 'params', 'auth', 'authType', 'resource'],
options
);
const defaultContext = _makeDefaultContext(cloudFunction, options);
const defaultContext = _makeDefaultContext(cloudFunction, options, data);

if (
has(defaultContext, 'eventType') &&
Expand Down Expand Up @@ -186,6 +187,21 @@ export function _makeResourceName(
return resourceName;
}

function _makeDefaultParams(triggerResource, name) {
const wildcards = triggerResource.match(new RegExp('{[^/{}]*}', 'g'));
const params = {};
if (wildcards) {
const triggerResourceParts = split(triggerResource, '/');
const eventResourceParts = split(name, '/');
forEach(wildcards, (wildcard) => {
const wildcardNoBraces = wildcard.slice(1, -1);
const position = indexOf(triggerResourceParts, wildcard);
params[wildcardNoBraces] = eventResourceParts[position];
});
}
return params;
}

function _makeEventId(): string {
return (
Math.random()
Expand All @@ -212,21 +228,39 @@ function _checkOptionValidity(

function _makeDefaultContext<T>(
cloudFunction: CloudFunction<T>,
options: ContextOptions
options: ContextOptions,
data?: T
): EventContext {
let eventContextOptions = options as EventContextOptions;
let isDocumentResourceName = false;
const resource = cloudFunction.__trigger.eventTrigger && {
service: cloudFunction.__trigger.eventTrigger.service,
name: ''
};
if(cloudFunction.__trigger.eventTrigger.service === 'firestore.googleapis.com'
&& !has(eventContextOptions, 'params')) {
try {
cloudFunction.__trigger.eventTrigger.resource.substring(0, cloudFunction.__trigger.eventTrigger.resource.indexOf('documents'))
+ 'documents/'
+ (data as unknown as QueryDocumentSnapshot).ref.path;
isDocumentResourceName = true;
} catch(error) {
resource.name = _makeResourceName(cloudFunction.__trigger.eventTrigger.resource
, has(eventContextOptions, 'params')
&& eventContextOptions.params);
}
} else {
resource.name = _makeResourceName(cloudFunction.__trigger.eventTrigger.resource, has(eventContextOptions, 'params')
&& eventContextOptions.params);
}
const defaultContext: EventContext = {
eventId: _makeEventId(),
resource: cloudFunction.__trigger.eventTrigger && {
service: cloudFunction.__trigger.eventTrigger.service,
name: _makeResourceName(
cloudFunction.__trigger.eventTrigger.resource,
has(eventContextOptions, 'params') && eventContextOptions.params
),
},
resource,
eventType: get(cloudFunction, '__trigger.eventTrigger.eventType'),
timestamp: new Date().toISOString(),
params: {},
params: isDocumentResourceName
? _makeDefaultParams(cloudFunction.__trigger.eventTrigger.resource, resource.name)
: {}
};
return defaultContext;
}
Expand Down