@fraym/projections 0.3.0 → 0.4.0

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.
package/README.md CHANGED
@@ -20,7 +20,9 @@ You need to add the `Tenant-Id` header in order to use the graphQL Endpoint and
20
20
  Use the `projections` cli command to automatically apply your projection schemas to the projections service.
21
21
 
22
22
  Your type schemas have to match the glob you specify in the `PROJECTIONS_SCHEMA_GLOB` env variable (default: `./src/**/*.graphql`).
23
- You can specify the address (and port) of the crud service instance you use in the `PROJECTIONS_SERVER_ADDRESS` env variable (default: `127.0.0.1:9000`).
23
+ You can specify the address (and port) of the projections service instance you use in the `PROJECTIONS_SERVER_ADDRESS` env variable (default: `127.0.0.1:9000`).
24
+
25
+ Use the `PROJECTIONS_NAMESPACE` env variable to restrict all migrations to your namespace. This is useful if multiple apps share the projections service. Note: You cannot name your projection or namespace by a `Fraym` prefix. This is a reserved prefix for fraym apps.
24
26
 
25
27
  You need to add a file that contains all built-in directives to your type schemas. The latest version of this file can be found [here](default.graphql).
26
28
 
@@ -31,6 +33,7 @@ Use a `.env` file or env variables to configure cte clients and the command:
31
33
  ```env
32
34
  PROJECTIONS_SERVER_ADDRESS=127.0.0.1:9000
33
35
  PROJECTIONS_SCHEMA_GLOB=./src/projections/*.graphql
36
+ PROJECTIONS_NAMESPACE=
34
37
  ```
35
38
 
36
39
  ## Usage
@@ -94,7 +97,7 @@ You can specify a fourth parameter if you want to return a empty dataset instead
94
97
  const data = await deliveryClient.getData("tenantId", "YourProjection", "id", true);
95
98
  ```
96
99
 
97
- ### Get (paginated) data
100
+ ### Get (paginated / filtered) data
98
101
 
99
102
  The name of `YourProjection` has to equal your type name in your schema (also in casing).
100
103
 
@@ -14,47 +14,60 @@ const client_1 = require("../management/client");
14
14
  const run = async () => {
15
15
  (0, dotenv_1.config)();
16
16
  const argv = await (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
17
- .config({ schemaGlob: "./src/**/*.graphql", serverAddress: "127.0.0.1:9000" })
17
+ .config({
18
+ schemaGlob: "./src/**/*.graphql",
19
+ serverAddress: "127.0.0.1:9000",
20
+ namespace: "",
21
+ })
18
22
  .pkgConf("projections").argv;
19
23
  let schemaGlob = argv.schemaGlob;
20
24
  let serverAddress = argv.serverAddress;
25
+ let namespace = argv.namespace;
21
26
  if (process.env.PROJECTIONS_SCHEMA_GLOB) {
22
27
  schemaGlob = process.env.PROJECTIONS_SCHEMA_GLOB;
23
28
  }
24
29
  if (process.env.PROJECTIONS_SERVER_ADDRESS) {
25
30
  serverAddress = process.env.PROJECTIONS_SERVER_ADDRESS;
26
31
  }
32
+ if (process.env.PROJECTIONS_NAMESPACE) {
33
+ namespace = process.env.PROJECTIONS_NAMESPACE;
34
+ }
35
+ if (namespace === "Fraym") {
36
+ throw new Error("Cannot use Fraym as namespace as it is reserved for fraym apps");
37
+ }
27
38
  const schema = await (0, load_1.loadSchema)(`${schemaGlob}`, {
28
39
  loaders: [new graphql_file_loader_1.GraphQLFileLoader()],
29
40
  });
30
- const definitions = getTypeDefinition(schema);
31
- await migrateSchemas(definitions, serverAddress);
41
+ const definitions = getTypeDefinition(schema, namespace);
42
+ await migrateSchemas(definitions, serverAddress, namespace);
32
43
  };
33
44
  run();
34
- const getTypeDefinition = (schema) => {
45
+ const getTypeDefinition = (schema, namespace) => {
35
46
  const definitions = {};
36
47
  schema.toConfig().types.forEach(t => {
37
48
  if (!(t instanceof graphql_1.GraphQLObjectType) && !(t instanceof graphql_1.GraphQLEnumType)) {
38
49
  return;
39
50
  }
40
- const name = t.toString();
51
+ const name = `${namespace}${t.toString()}`;
52
+ ensureValidName(name);
41
53
  if (definitions[name]) {
42
54
  throw new Error(`duplicate definition for type "${name}" detected, try renaming one of them as they have to be uniquely named`);
43
55
  }
44
56
  if (t instanceof graphql_1.GraphQLObjectType) {
45
- definitions[name] = getTypeDefinitionFromGraphQLObjectType(t);
57
+ definitions[name] = getTypeDefinitionFromGraphQLObjectType(t, namespace);
46
58
  return;
47
59
  }
48
60
  if (t instanceof graphql_1.GraphQLEnumType) {
49
- definitions[name] = getTypeDefinitionFromGraphQLEnumType(t);
61
+ definitions[name] = getTypeDefinitionFromGraphQLEnumType(t, namespace);
50
62
  return;
51
63
  }
52
64
  });
53
65
  return definitions;
54
66
  };
55
- const getTypeDefinitionFromGraphQLEnumType = (t) => {
67
+ const getTypeDefinitionFromGraphQLEnumType = (t, namespace) => {
56
68
  var _a, _b;
57
- const name = t.toString();
69
+ const name = `${namespace}${t.toString()}`;
70
+ ensureValidName(name);
58
71
  let enumValuesString = "";
59
72
  (_b = (_a = t.astNode) === null || _a === void 0 ? void 0 : _a.values) === null || _b === void 0 ? void 0 : _b.forEach(value => {
60
73
  enumValuesString += `\n\t${value.name.value}`;
@@ -66,14 +79,15 @@ const getTypeDefinitionFromGraphQLEnumType = (t) => {
66
79
  schema,
67
80
  };
68
81
  };
69
- const getTypeDefinitionFromGraphQLObjectType = (t) => {
82
+ const getTypeDefinitionFromGraphQLObjectType = (t, namespace) => {
70
83
  var _a, _b, _c, _d, _e, _f;
71
84
  let isProjection = false;
72
85
  if (((_a = t.astNode) === null || _a === void 0 ? void 0 : _a.directives) && ((_b = t.astNode) === null || _b === void 0 ? void 0 : _b.directives.length) > 0) {
73
86
  const directiveNames = t.astNode.directives.map(directive => directive.name.value);
74
87
  isProjection = directiveNames.includes("upsertOn");
75
88
  }
76
- const name = t.toString();
89
+ const name = `${namespace}${t.toString()}`;
90
+ ensureValidName(name);
77
91
  let objectDirectivesString = "";
78
92
  let objectFieldsString = "";
79
93
  let nestedTypes = [];
@@ -81,7 +95,7 @@ const getTypeDefinitionFromGraphQLObjectType = (t) => {
81
95
  objectDirectivesString += getDirectiveString(d);
82
96
  });
83
97
  (_f = (_e = t.astNode) === null || _e === void 0 ? void 0 : _e.fields) === null || _f === void 0 ? void 0 : _f.forEach(f => {
84
- const { str, nestedTypes: newNestedTypes } = getFieldStringAndNestedTypes(f);
98
+ const { str, nestedTypes: newNestedTypes } = getFieldStringAndNestedTypes(f, namespace);
85
99
  objectFieldsString += str;
86
100
  newNestedTypes.forEach(nested => {
87
101
  if (nestedTypes.indexOf(nested) === -1) {
@@ -96,13 +110,13 @@ const getTypeDefinitionFromGraphQLObjectType = (t) => {
96
110
  schema,
97
111
  };
98
112
  };
99
- const getFieldStringAndNestedTypes = (f) => {
113
+ const getFieldStringAndNestedTypes = (f, namespace) => {
100
114
  var _a;
101
115
  let directivesString = "";
102
116
  (_a = f.directives) === null || _a === void 0 ? void 0 : _a.forEach(d => {
103
117
  directivesString += getDirectiveString(d);
104
118
  });
105
- const { nestedType, str: typeString } = getTypeData(f.type);
119
+ const { nestedType, str: typeString } = getTypeData(f.type, namespace);
106
120
  const nestedTypes = [];
107
121
  if (nestedType) {
108
122
  nestedTypes.push(nestedType);
@@ -112,10 +126,11 @@ const getFieldStringAndNestedTypes = (f) => {
112
126
  nestedTypes,
113
127
  };
114
128
  };
115
- const getTypeData = (t) => {
129
+ const getTypeData = (t, namespace) => {
116
130
  switch (t.kind) {
117
131
  case graphql_1.Kind.NAMED_TYPE:
118
132
  const name = t.name.value;
133
+ ensureValidName(`${namespace}${name}`);
119
134
  return name === "String" ||
120
135
  name === "Float" ||
121
136
  name === "ID" ||
@@ -127,17 +142,17 @@ const getTypeData = (t) => {
127
142
  str: name,
128
143
  }
129
144
  : {
130
- str: name,
131
- nestedType: name,
145
+ str: `${namespace}${name}`,
146
+ nestedType: `${namespace}${name}`,
132
147
  };
133
148
  case graphql_1.Kind.LIST_TYPE:
134
- const { nestedType: listNestedType, str: listStr } = getTypeData(t.type);
149
+ const { nestedType: listNestedType, str: listStr } = getTypeData(t.type, namespace);
135
150
  return {
136
151
  str: `[${listStr}]`,
137
152
  nestedType: listNestedType,
138
153
  };
139
154
  case graphql_1.Kind.NON_NULL_TYPE:
140
- const { nestedType: nonNullNestedType, str: nonNullStr } = getTypeData(t.type);
155
+ const { nestedType: nonNullNestedType, str: nonNullStr } = getTypeData(t.type, namespace);
141
156
  return {
142
157
  str: `${nonNullStr}!`,
143
158
  nestedType: nonNullNestedType,
@@ -189,9 +204,9 @@ const getValueString = (v) => {
189
204
  throw new Error(`values of kind ${v.kind} are currently not supported`);
190
205
  }
191
206
  };
192
- const migrateSchemas = async (definitions, serverAddress) => {
207
+ const migrateSchemas = async (definitions, serverAddress, namespace) => {
193
208
  const managementClient = await (0, client_1.newManagementClient)({ serverAddress });
194
- let existingProjections = (await managementClient.getAll()).filter(projectionName => !projectionName.startsWith("Crud"));
209
+ let existingProjections = (await managementClient.getAll()).filter(projectionName => !projectionName.startsWith("Crud") && projectionName.startsWith(namespace));
195
210
  let createSchema = "";
196
211
  let updateSchema = "";
197
212
  const projectionsToCreate = [];
@@ -247,3 +262,8 @@ const migrateSchemas = async (definitions, serverAddress) => {
247
262
  console.log(`Removed ${projectionsToRemove.length} projections`);
248
263
  }
249
264
  };
265
+ const ensureValidName = (name) => {
266
+ if (name.startsWith("Fraym")) {
267
+ throw new Error(`Cannot use Fraym as projection name prefix as it is reserved for fraym apps, got ${name}`);
268
+ }
269
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fraym/projections",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "license": "UNLICENSED",
5
5
  "homepage": "https://github.com/fraym/projections-nodejs",
6
6
  "repository": {