@axinom/mosaic-graphql-common 0.7.0 → 0.8.0-rc.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"subscriptions-plugin-factory.d.ts","sourceRoot":"","sources":["../../src/plugins/subscriptions-plugin-factory.ts"],"names":[],"mappings":"AAUA,OAAO,EAAS,MAAM,EAAE,MAAM,cAAc,CAAC;AAyD7C;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,kBACtB,MAAM,YACX,MAAM,kBACD,KAAK,GAAG,MAAM,KAC5B,MAoCC,CAAC"}
1
+ {"version":3,"file":"subscriptions-plugin-factory.d.ts","sourceRoot":"","sources":["../../src/plugins/subscriptions-plugin-factory.ts"],"names":[],"mappings":"AAcA,OAAO,EAAS,MAAM,EAAE,MAAM,cAAc,CAAC;AAuG7C;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,kBACtB,MAAM,YACX,MAAM,kBACD,KAAK,GAAG,MAAM,KAC5B,MAmDC,CAAC"}
@@ -1,4 +1,15 @@
1
1
  "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
2
13
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
14
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
15
  };
@@ -25,6 +36,36 @@ function recordByIdFromTable(build, sqlTable) {
25
36
  function getId() {
26
37
  return async (event) => event.subject;
27
38
  }
39
+ /**
40
+ * Produces parts of the type definitions with the objective to not break
41
+ * existing GraphQL subscription implementations if only the libraries were
42
+ * updated, but database triggers were not.
43
+ */
44
+ const getEventTypeDefComponents = (build, mainTableName, typeName) => {
45
+ // Tag that is put on a table involved in a subscription by an `ax_define.define_subscription_triggers` call.
46
+ const tag = `subscription_events_${mainTableName}`;
47
+ const introspection = build.pgIntrospectionResultsByKind;
48
+ const enumValues = introspection.class
49
+ .filter((cls) => cls.tags[tag])
50
+ .flatMap((cls) => cls.tags[tag].split(','))
51
+ .join('\n');
52
+ const typeNameSuffix = 'SubscriptionEventKey';
53
+ let enumType = `enum ${typeName}${typeNameSuffix} { ${enumValues} }`;
54
+ let deprecationReason = `@deprecated(reason: "Use 'eventKey' instead.")`;
55
+ let eventEnumProperty = `eventKey: ${typeName}${typeNameSuffix}`;
56
+ // TODO: Drop this and `event` property when it is time to drop backward
57
+ // compatibility support for subscription event property.
58
+ if (enumValues === '') {
59
+ enumType = '';
60
+ deprecationReason = `@deprecated(reason: "Update the subscription triggers to add a strongly-typed 'eventKey' property to be used instead.")`;
61
+ eventEnumProperty = '';
62
+ // eslint-disable-next-line no-console
63
+ console.warn(`Deprecation Warning: The "event" property on all subscription payloads is deprecated.
64
+ Please re-initialize the subscription database triggers with the updated "ax_define" functions.
65
+ The last parameter of "ax_define.define_subscription_triggers" shall now be screaming snake-case string (e.g. MOVIE_TAG instead of MovieTag).`, { context: exports.SubscriptionsPluginFactory.name });
66
+ }
67
+ return { enumType, deprecationReason, eventEnumProperty };
68
+ };
28
69
  /**
29
70
  * Factory function to create a makeExtendSchemaPlugin that adds a subscription endpoint for specific entity.
30
71
  * @param mainTableName name of the table in the database without schema
@@ -36,12 +77,16 @@ const SubscriptionsPluginFactory = (mainTableName, typeName, gqlIdDataType = 'In
36
77
  const variableName = inflection_1.default.camelize(typeName, true);
37
78
  const payloadName = inflection_1.default.camelize(typeName, false) + 'SubscriptionPayload';
38
79
  const topicName = 'graphql:' + mainTableName;
80
+ const { enumType, deprecationReason, eventEnumProperty } = getEventTypeDefComponents(build, mainTableName, typeName);
39
81
  return {
40
82
  typeDefs: (0, graphile_utils_1.gql) `
83
+ ${enumType}
84
+
41
85
  type ${payloadName} {
42
86
  id: ${gqlIdDataType}! # Populated by our resolver below
43
87
  ${variableName}: ${typeName} # Populated by our resolver below
44
- event: String # Part of the NOTIFY payload
88
+ event: String ${deprecationReason} # Part of the NOTIFY payload
89
+ ${eventEnumProperty} # Part of the NOTIFY payload
45
90
  }
46
91
 
47
92
  extend type Subscription {
@@ -58,7 +103,12 @@ const SubscriptionsPluginFactory = (mainTableName, typeName, gqlIdDataType = 'In
58
103
  [variableName]: recordByIdFromTable(build, sql.fragment([`app_public.${mainTableName}`])),
59
104
  },
60
105
  Subscription: {
61
- [`${variableName}Mutated`]: (event) => event,
106
+ [`${variableName}Mutated`]: (data) => {
107
+ const { event } = data, rest = __rest(data, ["event"]);
108
+ return Object.assign(Object.assign({}, rest), { eventKey: event, event: /[a-z]/.test(event) // if event value has lowercase letters
109
+ ? event
110
+ : inflection_1.default.camelize(event.toLowerCase(), false) });
111
+ },
62
112
  },
63
113
  },
64
114
  };
@@ -1 +1 @@
1
- {"version":3,"file":"subscriptions-plugin-factory.js","sourceRoot":"","sources":["../../src/plugins/subscriptions-plugin-factory.ts"],"names":[],"mappings":";;;;;;AAEA,mDAIwB;AAGxB,4DAAoC;AAsBpC;;;;GAIG;AACH,SAAS,mBAAmB,CAC1B,KAAY,EACZ,QAAa;IAEb,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;IAC7B,OAAO,KAAK,EACV,KAAoC,EACpC,KAA8B,EAC9B,QAAa;IACb,sDAAsD;IACtD,EAAE,QAAQ,EAAE,EAAE,4BAA4B,EAAE,EAAE,EAC9C,EAAE;QACF,MAAM,IAAI,GAAG,MAAM,4BAA4B,CAC7C,QAAQ,EACR,CAAC,UAAe,EAAE,UAAwB,EAAE,EAAE;YAC5C,UAAU,CAAC,KAAK,CACd,GAAG,CAAC,QAAQ,CAAA,GAAG,UAAU,SAAS,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAC7D,CAAC;QACJ,CAAC,CACF,CAAC;QACF,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,KAAK;IAIZ,OAAO,KAAK,EAAE,KAAoC,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC;AACvE,CAAC;AAED;;;;;GAKG;AACI,MAAM,0BAA0B,GAAG,CACxC,aAAqB,EACrB,QAAgB,EAChB,gBAAgC,KAAK,EAC7B,EAAE,CACV,IAAA,uCAAsB,EAAC,CAAC,KAAY,EAAE,EAAE;IACtC,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;IAC7B,MAAM,YAAY,GAAG,oBAAU,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACzD,MAAM,WAAW,GACf,oBAAU,CAAC,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAG,qBAAqB,CAAC;IAC/D,MAAM,SAAS,GAAG,UAAU,GAAG,aAAa,CAAC;IAC7C,OAAO;QACL,QAAQ,EAAE,IAAA,oBAAG,EAAA;aACN,WAAW;cACV,aAAa;UACjB,YAAY,KAAK,QAAQ;;;;;;2BAMR,QAAQ;;UAEzB,YAAY,YAAY,WAAW;oCACT,SAAS;;KAExC;QACC,SAAS,EAAE;YACT,CAAC,WAAW,CAAC,EAAE;gBACb,EAAE,EAAE,KAAK,EAAE;gBACX,CAAC,YAAY,CAAC,EAAE,mBAAmB,CACjC,KAAK,EACL,GAAG,CAAC,QAAQ,CAAC,CAAC,cAAc,aAAa,EAAE,CAAC,CAAC,CAC9C;aACF;YACD,YAAY,EAAE;gBACZ,CAAC,GAAG,YAAY,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK;aAC7C;SACF;KACqB,CAAC;AAC3B,CAAC,CAAC,CAAC;AAxCQ,QAAA,0BAA0B,8BAwClC"}
1
+ {"version":3,"file":"subscriptions-plugin-factory.js","sourceRoot":"","sources":["../../src/plugins/subscriptions-plugin-factory.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axinom/mosaic-graphql-common",
3
- "version": "0.7.0",
3
+ "version": "0.8.0-rc.1",
4
4
  "description": "Common GraphQL and PostGraphile related functionality.",
5
5
  "author": "Axinom",
6
6
  "license": "PROPRIETARY",
@@ -57,5 +57,5 @@
57
57
  "publishConfig": {
58
58
  "access": "public"
59
59
  },
60
- "gitHead": "e583a1076964626d1d0b1f9fb507d1defc307102"
60
+ "gitHead": "e103b626f8fa440654a67d2ff9b47d1c6316167d"
61
61
  }
@@ -1,5 +1,9 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { QueryBuilder, SQL } from 'graphile-build-pg';
2
+ import {
3
+ PgIntrospectionResultsByKind,
4
+ QueryBuilder,
5
+ SQL,
6
+ } from 'graphile-build-pg';
3
7
  import {
4
8
  ExtensionDefinition,
5
9
  gql,
@@ -65,6 +69,52 @@ function getId(): AugmentedGraphQLFieldResolver<
65
69
  return async (event: ITgGraphQLSubscriptionPayload) => event.subject;
66
70
  }
67
71
 
72
+ /**
73
+ * Produces parts of the type definitions with the objective to not break
74
+ * existing GraphQL subscription implementations if only the libraries were
75
+ * updated, but database triggers were not.
76
+ */
77
+ const getEventTypeDefComponents = (
78
+ build: Build,
79
+ mainTableName: string,
80
+ typeName: string,
81
+ ): {
82
+ enumType: string;
83
+ deprecationReason: string;
84
+ eventEnumProperty: string;
85
+ } => {
86
+ // Tag that is put on a table involved in a subscription by an `ax_define.define_subscription_triggers` call.
87
+ const tag = `subscription_events_${mainTableName}`;
88
+ const introspection: PgIntrospectionResultsByKind =
89
+ build.pgIntrospectionResultsByKind;
90
+ const enumValues = introspection.class
91
+ .filter((cls) => cls.tags[tag])
92
+ .flatMap((cls) => (cls.tags[tag] as string).split(','))
93
+ .join('\n');
94
+
95
+ const typeNameSuffix = 'SubscriptionEventKey';
96
+ let enumType = `enum ${typeName}${typeNameSuffix} { ${enumValues} }`;
97
+ let deprecationReason = `@deprecated(reason: "Use 'eventKey' instead.")`;
98
+ let eventEnumProperty = `eventKey: ${typeName}${typeNameSuffix}`;
99
+
100
+ // TODO: Drop this and `event` property when it is time to drop backward
101
+ // compatibility support for subscription event property.
102
+ if (enumValues === '') {
103
+ enumType = '';
104
+ deprecationReason = `@deprecated(reason: "Update the subscription triggers to add a strongly-typed 'eventKey' property to be used instead.")`;
105
+ eventEnumProperty = '';
106
+ // eslint-disable-next-line no-console
107
+ console.warn(
108
+ `Deprecation Warning: The "event" property on all subscription payloads is deprecated.
109
+ Please re-initialize the subscription database triggers with the updated "ax_define" functions.
110
+ The last parameter of "ax_define.define_subscription_triggers" shall now be screaming snake-case string (e.g. MOVIE_TAG instead of MovieTag).`,
111
+ { context: SubscriptionsPluginFactory.name },
112
+ );
113
+ }
114
+
115
+ return { enumType, deprecationReason, eventEnumProperty };
116
+ };
117
+
68
118
  /**
69
119
  * Factory function to create a makeExtendSchemaPlugin that adds a subscription endpoint for specific entity.
70
120
  * @param mainTableName name of the table in the database without schema
@@ -82,12 +132,18 @@ export const SubscriptionsPluginFactory = (
82
132
  const payloadName =
83
133
  inflection.camelize(typeName, false) + 'SubscriptionPayload';
84
134
  const topicName = 'graphql:' + mainTableName;
135
+
136
+ const { enumType, deprecationReason, eventEnumProperty } =
137
+ getEventTypeDefComponents(build, mainTableName, typeName);
85
138
  return {
86
139
  typeDefs: gql`
140
+ ${enumType}
141
+
87
142
  type ${payloadName} {
88
143
  id: ${gqlIdDataType}! # Populated by our resolver below
89
144
  ${variableName}: ${typeName} # Populated by our resolver below
90
- event: String # Part of the NOTIFY payload
145
+ event: String ${deprecationReason} # Part of the NOTIFY payload
146
+ ${eventEnumProperty} # Part of the NOTIFY payload
91
147
  }
92
148
 
93
149
  extend type Subscription {
@@ -107,7 +163,16 @@ export const SubscriptionsPluginFactory = (
107
163
  ),
108
164
  },
109
165
  Subscription: {
110
- [`${variableName}Mutated`]: (event) => event,
166
+ [`${variableName}Mutated`]: (data) => {
167
+ const { event, ...rest } = data;
168
+ return {
169
+ ...rest,
170
+ eventKey: event,
171
+ event: /[a-z]/.test(event) // if event value has lowercase letters
172
+ ? event
173
+ : inflection.camelize(event.toLowerCase(), false),
174
+ };
175
+ },
111
176
  },
112
177
  },
113
178
  } as ExtensionDefinition;