@constructive-io/graphql-server 2.14.7 → 2.15.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/codegen/orm/client.d.ts +55 -0
- package/codegen/orm/client.js +75 -0
- package/codegen/orm/index.d.ts +632 -0
- package/codegen/orm/index.js +182 -0
- package/codegen/orm/input-types.d.ts +13248 -0
- package/codegen/orm/input-types.js +7 -0
- package/codegen/orm/models/api.d.ts +42 -0
- package/codegen/orm/models/api.js +77 -0
- package/codegen/orm/models/apiExtension.d.ts +42 -0
- package/codegen/orm/models/apiExtension.js +77 -0
- package/codegen/orm/models/apiModule.d.ts +42 -0
- package/codegen/orm/models/apiModule.js +77 -0
- package/codegen/orm/models/apiSchema.d.ts +42 -0
- package/codegen/orm/models/apiSchema.js +77 -0
- package/codegen/orm/models/app.d.ts +42 -0
- package/codegen/orm/models/app.js +77 -0
- package/codegen/orm/models/checkConstraint.d.ts +42 -0
- package/codegen/orm/models/checkConstraint.js +77 -0
- package/codegen/orm/models/connectedAccountsModule.d.ts +42 -0
- package/codegen/orm/models/connectedAccountsModule.js +77 -0
- package/codegen/orm/models/cryptoAddressesModule.d.ts +42 -0
- package/codegen/orm/models/cryptoAddressesModule.js +77 -0
- package/codegen/orm/models/cryptoAuthModule.d.ts +42 -0
- package/codegen/orm/models/cryptoAuthModule.js +77 -0
- package/codegen/orm/models/database.d.ts +42 -0
- package/codegen/orm/models/database.js +77 -0
- package/codegen/orm/models/databaseExtension.d.ts +42 -0
- package/codegen/orm/models/databaseExtension.js +77 -0
- package/codegen/orm/models/databaseProvision.d.ts +42 -0
- package/codegen/orm/models/databaseProvision.js +77 -0
- package/codegen/orm/models/defaultIdsModule.d.ts +42 -0
- package/codegen/orm/models/defaultIdsModule.js +77 -0
- package/codegen/orm/models/denormalizedTableField.d.ts +42 -0
- package/codegen/orm/models/denormalizedTableField.js +77 -0
- package/codegen/orm/models/domain.d.ts +42 -0
- package/codegen/orm/models/domain.js +77 -0
- package/codegen/orm/models/emailsModule.d.ts +42 -0
- package/codegen/orm/models/emailsModule.js +77 -0
- package/codegen/orm/models/encryptedSecretsModule.d.ts +42 -0
- package/codegen/orm/models/encryptedSecretsModule.js +77 -0
- package/codegen/orm/models/extension.d.ts +42 -0
- package/codegen/orm/models/extension.js +77 -0
- package/codegen/orm/models/field.d.ts +42 -0
- package/codegen/orm/models/field.js +77 -0
- package/codegen/orm/models/fieldModule.d.ts +42 -0
- package/codegen/orm/models/fieldModule.js +77 -0
- package/codegen/orm/models/foreignKeyConstraint.d.ts +42 -0
- package/codegen/orm/models/foreignKeyConstraint.js +77 -0
- package/codegen/orm/models/fullTextSearch.d.ts +42 -0
- package/codegen/orm/models/fullTextSearch.js +77 -0
- package/codegen/orm/models/hierarchyModule.d.ts +42 -0
- package/codegen/orm/models/hierarchyModule.js +77 -0
- package/codegen/orm/models/index.d.ts +64 -0
- package/codegen/orm/models/index.js +127 -0
- package/codegen/orm/models/indexModel.d.ts +42 -0
- package/codegen/orm/models/indexModel.js +77 -0
- package/codegen/orm/models/invitesModule.d.ts +42 -0
- package/codegen/orm/models/invitesModule.js +77 -0
- package/codegen/orm/models/levelsModule.d.ts +42 -0
- package/codegen/orm/models/levelsModule.js +77 -0
- package/codegen/orm/models/limitFunction.d.ts +42 -0
- package/codegen/orm/models/limitFunction.js +77 -0
- package/codegen/orm/models/limitsModule.d.ts +42 -0
- package/codegen/orm/models/limitsModule.js +77 -0
- package/codegen/orm/models/membershipTypesModule.d.ts +42 -0
- package/codegen/orm/models/membershipTypesModule.js +77 -0
- package/codegen/orm/models/membershipsModule.d.ts +42 -0
- package/codegen/orm/models/membershipsModule.js +77 -0
- package/codegen/orm/models/module.d.ts +42 -0
- package/codegen/orm/models/module.js +77 -0
- package/codegen/orm/models/moduleDefinition.d.ts +42 -0
- package/codegen/orm/models/moduleDefinition.js +77 -0
- package/codegen/orm/models/moduleField.d.ts +42 -0
- package/codegen/orm/models/moduleField.js +77 -0
- package/codegen/orm/models/moduleInputRecord.d.ts +42 -0
- package/codegen/orm/models/moduleInputRecord.js +77 -0
- package/codegen/orm/models/moduleOutput.d.ts +42 -0
- package/codegen/orm/models/moduleOutput.js +77 -0
- package/codegen/orm/models/permissionsModule.d.ts +42 -0
- package/codegen/orm/models/permissionsModule.js +77 -0
- package/codegen/orm/models/phoneNumbersModule.d.ts +42 -0
- package/codegen/orm/models/phoneNumbersModule.js +77 -0
- package/codegen/orm/models/policy.d.ts +42 -0
- package/codegen/orm/models/policy.js +77 -0
- package/codegen/orm/models/primaryKeyConstraint.d.ts +42 -0
- package/codegen/orm/models/primaryKeyConstraint.js +77 -0
- package/codegen/orm/models/procedure.d.ts +42 -0
- package/codegen/orm/models/procedure.js +77 -0
- package/codegen/orm/models/profilesModule.d.ts +42 -0
- package/codegen/orm/models/profilesModule.js +77 -0
- package/codegen/orm/models/rlsFunction.d.ts +42 -0
- package/codegen/orm/models/rlsFunction.js +77 -0
- package/codegen/orm/models/rlsModule.d.ts +42 -0
- package/codegen/orm/models/rlsModule.js +77 -0
- package/codegen/orm/models/schema.d.ts +42 -0
- package/codegen/orm/models/schema.js +77 -0
- package/codegen/orm/models/schemaGrant.d.ts +42 -0
- package/codegen/orm/models/schemaGrant.js +77 -0
- package/codegen/orm/models/secretsModule.d.ts +42 -0
- package/codegen/orm/models/secretsModule.js +77 -0
- package/codegen/orm/models/site.d.ts +42 -0
- package/codegen/orm/models/site.js +77 -0
- package/codegen/orm/models/siteMetadatum.d.ts +42 -0
- package/codegen/orm/models/siteMetadatum.js +77 -0
- package/codegen/orm/models/siteModule.d.ts +42 -0
- package/codegen/orm/models/siteModule.js +77 -0
- package/codegen/orm/models/siteTheme.d.ts +42 -0
- package/codegen/orm/models/siteTheme.js +77 -0
- package/codegen/orm/models/table.d.ts +42 -0
- package/codegen/orm/models/table.js +77 -0
- package/codegen/orm/models/tableGrant.d.ts +42 -0
- package/codegen/orm/models/tableGrant.js +77 -0
- package/codegen/orm/models/tokensModule.d.ts +42 -0
- package/codegen/orm/models/tokensModule.js +77 -0
- package/codegen/orm/models/trigger.d.ts +42 -0
- package/codegen/orm/models/trigger.js +77 -0
- package/codegen/orm/models/triggerFunction.d.ts +42 -0
- package/codegen/orm/models/triggerFunction.js +77 -0
- package/codegen/orm/models/uniqueConstraint.d.ts +42 -0
- package/codegen/orm/models/uniqueConstraint.js +77 -0
- package/codegen/orm/models/userAuthModule.d.ts +42 -0
- package/codegen/orm/models/userAuthModule.js +77 -0
- package/codegen/orm/models/usersModule.d.ts +42 -0
- package/codegen/orm/models/usersModule.js +77 -0
- package/codegen/orm/models/uuidModule.d.ts +42 -0
- package/codegen/orm/models/uuidModule.js +77 -0
- package/codegen/orm/mutation/index.d.ts +531 -0
- package/codegen/orm/mutation/index.js +596 -0
- package/codegen/orm/query/index.d.ts +274 -0
- package/codegen/orm/query/index.js +290 -0
- package/codegen/orm/query-builder.d.ts +80 -0
- package/codegen/orm/query-builder.js +249 -0
- package/codegen/orm/select-types.d.ts +50 -0
- package/codegen/orm/select-types.js +7 -0
- package/codegen/orm/types.d.ts +6 -0
- package/codegen/orm/types.js +23 -0
- package/esm/codegen/orm/client.js +70 -0
- package/esm/codegen/orm/index.js +162 -0
- package/esm/codegen/orm/input-types.js +6 -0
- package/esm/codegen/orm/models/api.js +73 -0
- package/esm/codegen/orm/models/apiExtension.js +73 -0
- package/esm/codegen/orm/models/apiModule.js +73 -0
- package/esm/codegen/orm/models/apiSchema.js +73 -0
- package/esm/codegen/orm/models/app.js +73 -0
- package/esm/codegen/orm/models/checkConstraint.js +73 -0
- package/esm/codegen/orm/models/connectedAccountsModule.js +73 -0
- package/esm/codegen/orm/models/cryptoAddressesModule.js +73 -0
- package/esm/codegen/orm/models/cryptoAuthModule.js +73 -0
- package/esm/codegen/orm/models/database.js +73 -0
- package/esm/codegen/orm/models/databaseExtension.js +73 -0
- package/esm/codegen/orm/models/databaseProvision.js +73 -0
- package/esm/codegen/orm/models/defaultIdsModule.js +73 -0
- package/esm/codegen/orm/models/denormalizedTableField.js +73 -0
- package/esm/codegen/orm/models/domain.js +73 -0
- package/esm/codegen/orm/models/emailsModule.js +73 -0
- package/esm/codegen/orm/models/encryptedSecretsModule.js +73 -0
- package/esm/codegen/orm/models/extension.js +73 -0
- package/esm/codegen/orm/models/field.js +73 -0
- package/esm/codegen/orm/models/fieldModule.js +73 -0
- package/esm/codegen/orm/models/foreignKeyConstraint.js +73 -0
- package/esm/codegen/orm/models/fullTextSearch.js +73 -0
- package/esm/codegen/orm/models/hierarchyModule.js +73 -0
- package/esm/codegen/orm/models/index.js +64 -0
- package/esm/codegen/orm/models/indexModel.js +73 -0
- package/esm/codegen/orm/models/invitesModule.js +73 -0
- package/esm/codegen/orm/models/levelsModule.js +73 -0
- package/esm/codegen/orm/models/limitFunction.js +73 -0
- package/esm/codegen/orm/models/limitsModule.js +73 -0
- package/esm/codegen/orm/models/membershipTypesModule.js +73 -0
- package/esm/codegen/orm/models/membershipsModule.js +73 -0
- package/esm/codegen/orm/models/module.js +73 -0
- package/esm/codegen/orm/models/moduleDefinition.js +73 -0
- package/esm/codegen/orm/models/moduleField.js +73 -0
- package/esm/codegen/orm/models/moduleInputRecord.js +73 -0
- package/esm/codegen/orm/models/moduleOutput.js +73 -0
- package/esm/codegen/orm/models/permissionsModule.js +73 -0
- package/esm/codegen/orm/models/phoneNumbersModule.js +73 -0
- package/esm/codegen/orm/models/policy.js +73 -0
- package/esm/codegen/orm/models/primaryKeyConstraint.js +73 -0
- package/esm/codegen/orm/models/procedure.js +73 -0
- package/esm/codegen/orm/models/profilesModule.js +73 -0
- package/esm/codegen/orm/models/rlsFunction.js +73 -0
- package/esm/codegen/orm/models/rlsModule.js +73 -0
- package/esm/codegen/orm/models/schema.js +73 -0
- package/esm/codegen/orm/models/schemaGrant.js +73 -0
- package/esm/codegen/orm/models/secretsModule.js +73 -0
- package/esm/codegen/orm/models/site.js +73 -0
- package/esm/codegen/orm/models/siteMetadatum.js +73 -0
- package/esm/codegen/orm/models/siteModule.js +73 -0
- package/esm/codegen/orm/models/siteTheme.js +73 -0
- package/esm/codegen/orm/models/table.js +73 -0
- package/esm/codegen/orm/models/tableGrant.js +73 -0
- package/esm/codegen/orm/models/tokensModule.js +73 -0
- package/esm/codegen/orm/models/trigger.js +73 -0
- package/esm/codegen/orm/models/triggerFunction.js +73 -0
- package/esm/codegen/orm/models/uniqueConstraint.js +73 -0
- package/esm/codegen/orm/models/userAuthModule.js +73 -0
- package/esm/codegen/orm/models/usersModule.js +73 -0
- package/esm/codegen/orm/models/uuidModule.js +73 -0
- package/esm/codegen/orm/mutation/index.js +593 -0
- package/esm/codegen/orm/query/index.js +287 -0
- package/esm/codegen/orm/query-builder.js +238 -0
- package/esm/codegen/orm/select-types.js +6 -0
- package/esm/codegen/orm/types.js +7 -0
- package/esm/middleware/api.js +10 -9
- package/esm/middleware/gql.js +118 -123
- package/esm/middleware/graphile.js +19 -3
- package/esm/scripts/codegen-schema.js +71 -0
- package/esm/server.js +21 -0
- package/middleware/api.js +9 -8
- package/middleware/gql.d.ts +25 -5
- package/middleware/gql.js +122 -127
- package/middleware/graphile.js +19 -3
- package/middleware/types.d.ts +1 -0
- package/package.json +15 -11
- package/scripts/codegen-schema.d.ts +1 -0
- package/scripts/codegen-schema.js +76 -0
- package/server.js +21 -0
- package/types.d.ts +2 -2
package/middleware/gql.js
CHANGED
|
@@ -1,131 +1,126 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
} # for now keep this for patches
|
|
102
|
-
apiModules {
|
|
103
|
-
nodes {
|
|
104
|
-
name
|
|
105
|
-
data
|
|
106
|
-
}
|
|
107
|
-
}
|
|
3
|
+
exports.buildListApis = exports.buildApiByDatabaseIdAndName = exports.buildDomainLookup = void 0;
|
|
4
|
+
const query_builder_1 = require("../codegen/orm/query-builder");
|
|
5
|
+
const apiSelect = {
|
|
6
|
+
databaseId: true,
|
|
7
|
+
dbname: true,
|
|
8
|
+
roleName: true,
|
|
9
|
+
anonRole: true,
|
|
10
|
+
isPublic: true,
|
|
11
|
+
domains: {
|
|
12
|
+
select: {
|
|
13
|
+
subdomain: true,
|
|
14
|
+
domain: true,
|
|
15
|
+
},
|
|
16
|
+
connection: true,
|
|
17
|
+
},
|
|
18
|
+
apiExtensions: {
|
|
19
|
+
select: { schemaName: true },
|
|
20
|
+
connection: true,
|
|
21
|
+
},
|
|
22
|
+
schemasByApiSchemaApiIdAndSchemaId: {
|
|
23
|
+
select: { schemaName: true },
|
|
24
|
+
connection: true,
|
|
25
|
+
},
|
|
26
|
+
rlsModule: {
|
|
27
|
+
select: {
|
|
28
|
+
privateSchema: { select: { schemaName: true } },
|
|
29
|
+
authenticateStrict: true,
|
|
30
|
+
authenticate: true,
|
|
31
|
+
currentRole: true,
|
|
32
|
+
currentRoleId: true,
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
database: {
|
|
36
|
+
select: {
|
|
37
|
+
sites: {
|
|
38
|
+
select: {
|
|
39
|
+
domains: {
|
|
40
|
+
select: { subdomain: true, domain: true },
|
|
41
|
+
connection: true,
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
connection: true,
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
apiModules: {
|
|
49
|
+
select: { name: true, data: true },
|
|
50
|
+
connection: true,
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
const domainSelect = {
|
|
54
|
+
domain: true,
|
|
55
|
+
subdomain: true,
|
|
56
|
+
api: { select: apiSelect },
|
|
57
|
+
};
|
|
58
|
+
const apisSelect = {
|
|
59
|
+
id: true,
|
|
60
|
+
databaseId: true,
|
|
61
|
+
name: true,
|
|
62
|
+
dbname: true,
|
|
63
|
+
roleName: true,
|
|
64
|
+
anonRole: true,
|
|
65
|
+
isPublic: true,
|
|
66
|
+
domains: {
|
|
67
|
+
select: { domain: true, subdomain: true },
|
|
68
|
+
connection: true,
|
|
69
|
+
},
|
|
70
|
+
database: {
|
|
71
|
+
select: {
|
|
72
|
+
sites: {
|
|
73
|
+
select: {
|
|
74
|
+
domains: {
|
|
75
|
+
select: { domain: true, subdomain: true },
|
|
76
|
+
connection: true,
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
connection: true,
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Build query for domain lookup with optional subdomain
|
|
86
|
+
* This uses domains connection instead of domainBySubdomainAndDomain
|
|
87
|
+
* because we need to handle null subdomain with condition filter
|
|
88
|
+
*/
|
|
89
|
+
const buildDomainLookup = (vars) => {
|
|
90
|
+
const where = {
|
|
91
|
+
domain: { equalTo: vars.domain },
|
|
92
|
+
};
|
|
93
|
+
if (vars.subdomain === null || vars.subdomain === undefined) {
|
|
94
|
+
where.subdomain = { isNull: true };
|
|
108
95
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
exports.ListOfAllDomainsOfDb = (0, graphql_tag_1.default) `
|
|
112
|
-
query ListApisByDatabaseId {
|
|
113
|
-
apis {
|
|
114
|
-
nodes {
|
|
115
|
-
id
|
|
116
|
-
databaseId
|
|
117
|
-
name
|
|
118
|
-
dbname
|
|
119
|
-
roleName
|
|
120
|
-
anonRole
|
|
121
|
-
isPublic
|
|
122
|
-
domains {
|
|
123
|
-
nodes {
|
|
124
|
-
domain
|
|
125
|
-
subdomain
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
96
|
+
else {
|
|
97
|
+
where.subdomain = { equalTo: vars.subdomain };
|
|
129
98
|
}
|
|
130
|
-
|
|
131
|
-
|
|
99
|
+
return (0, query_builder_1.buildFindFirstDocument)('DomainLookup', 'domains', domainSelect, { where }, 'DomainFilter');
|
|
100
|
+
};
|
|
101
|
+
exports.buildDomainLookup = buildDomainLookup;
|
|
102
|
+
/**
|
|
103
|
+
* Build query for API lookup by database ID and name
|
|
104
|
+
* Uses the generated apiByDatabaseIdAndName custom query
|
|
105
|
+
*/
|
|
106
|
+
const buildApiByDatabaseIdAndName = (vars) => {
|
|
107
|
+
// Import buildCustomDocument locally to avoid circular dependency
|
|
108
|
+
const { buildCustomDocument } = require('../codegen/orm/query-builder');
|
|
109
|
+
return buildCustomDocument('query', 'ApiByDatabaseIdAndName', 'apiByDatabaseIdAndName', apiSelect, vars, [
|
|
110
|
+
{ name: 'databaseId', type: 'UUID!' },
|
|
111
|
+
{ name: 'name', type: 'String!' },
|
|
112
|
+
]);
|
|
113
|
+
};
|
|
114
|
+
exports.buildApiByDatabaseIdAndName = buildApiByDatabaseIdAndName;
|
|
115
|
+
/**
|
|
116
|
+
* Build query to list all APIs
|
|
117
|
+
*/
|
|
118
|
+
const buildListApis = () => {
|
|
119
|
+
// Import buildCustomDocument locally to avoid circular dependency
|
|
120
|
+
const { buildCustomDocument } = require('../codegen/orm/query-builder');
|
|
121
|
+
return buildCustomDocument('query', 'ListApisByDatabaseId', 'apis', {
|
|
122
|
+
select: apisSelect,
|
|
123
|
+
connection: true,
|
|
124
|
+
}, undefined, []);
|
|
125
|
+
};
|
|
126
|
+
exports.buildListApis = buildListApis;
|
package/middleware/graphile.js
CHANGED
|
@@ -4,28 +4,37 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.graphile = void 0;
|
|
7
|
+
const logger_1 = require("@pgpmjs/logger");
|
|
7
8
|
const graphile_cache_1 = require("graphile-cache");
|
|
8
9
|
const graphile_settings_1 = require("graphile-settings");
|
|
9
10
|
const pg_cache_1 = require("pg-cache");
|
|
10
11
|
const postgraphile_1 = require("postgraphile");
|
|
11
12
|
require("./types"); // for Request type
|
|
12
13
|
const PublicKeySignature_1 = __importDefault(require("../plugins/PublicKeySignature"));
|
|
14
|
+
const log = new logger_1.Logger('graphile');
|
|
15
|
+
const reqLabel = (req) => req.requestId ? `[${req.requestId}]` : '[req]';
|
|
13
16
|
const graphile = (opts) => {
|
|
14
17
|
return async (req, res, next) => {
|
|
18
|
+
const label = reqLabel(req);
|
|
15
19
|
try {
|
|
16
20
|
const api = req.api;
|
|
17
21
|
if (!api) {
|
|
22
|
+
log.error(`${label} Missing API info`);
|
|
18
23
|
return res.status(500).send('Missing API info');
|
|
19
24
|
}
|
|
20
25
|
const key = req.svc_key;
|
|
21
26
|
if (!key) {
|
|
27
|
+
log.error(`${label} Missing service cache key`);
|
|
22
28
|
return res.status(500).send('Missing service cache key');
|
|
23
29
|
}
|
|
24
30
|
const { dbname, anonRole, roleName, schema } = api;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
31
|
+
const schemaLabel = schema?.join(',') || 'unknown';
|
|
32
|
+
const cached = graphile_cache_1.graphileCache.get(key);
|
|
33
|
+
if (cached) {
|
|
34
|
+
log.debug(`${label} PostGraphile cache hit key=${key} db=${dbname} schemas=${schemaLabel}`);
|
|
35
|
+
return cached.handler(req, res, next);
|
|
28
36
|
}
|
|
37
|
+
log.debug(`${label} PostGraphile cache miss key=${key} db=${dbname} schemas=${schemaLabel}`);
|
|
29
38
|
const options = (0, graphile_settings_1.getGraphileSettings)({
|
|
30
39
|
...opts,
|
|
31
40
|
graphile: {
|
|
@@ -35,12 +44,14 @@ const graphile = (opts) => {
|
|
|
35
44
|
});
|
|
36
45
|
const pubkey_challenge = api.apiModules.find((mod) => mod.name === 'pubkey_challenge');
|
|
37
46
|
if (pubkey_challenge && pubkey_challenge.data) {
|
|
47
|
+
log.info(`${label} Enabling PublicKeySignature plugin for ${dbname}`);
|
|
38
48
|
options.appendPlugins.push((0, PublicKeySignature_1.default)(pubkey_challenge.data));
|
|
39
49
|
}
|
|
40
50
|
options.appendPlugins = options.appendPlugins ?? [];
|
|
41
51
|
options.appendPlugins.push(...opts.graphile.appendPlugins);
|
|
42
52
|
options.pgSettings = async function pgSettings(request) {
|
|
43
53
|
const gqlReq = request;
|
|
54
|
+
const settingsLabel = reqLabel(gqlReq);
|
|
44
55
|
const context = {
|
|
45
56
|
[`jwt.claims.database_id`]: gqlReq.databaseId,
|
|
46
57
|
[`jwt.claims.ip_address`]: gqlReq.clientIp,
|
|
@@ -52,6 +63,7 @@ const graphile = (opts) => {
|
|
|
52
63
|
context['jwt.claims.user_agent'] = gqlReq.get('User-Agent');
|
|
53
64
|
}
|
|
54
65
|
if (gqlReq?.token?.user_id) {
|
|
66
|
+
log.debug(`${settingsLabel} pgSettings role=${roleName} db=${gqlReq.databaseId} ip=${gqlReq.clientIp}`);
|
|
55
67
|
return {
|
|
56
68
|
role: roleName,
|
|
57
69
|
[`jwt.claims.token_id`]: gqlReq.token.id,
|
|
@@ -59,6 +71,7 @@ const graphile = (opts) => {
|
|
|
59
71
|
...context,
|
|
60
72
|
};
|
|
61
73
|
}
|
|
74
|
+
log.debug(`${settingsLabel} pgSettings role=${anonRole} db=${gqlReq.databaseId} ip=${gqlReq.clientIp}`);
|
|
62
75
|
return { role: anonRole, ...context };
|
|
63
76
|
};
|
|
64
77
|
options.graphqlRoute = '/graphql';
|
|
@@ -71,6 +84,7 @@ const graphile = (opts) => {
|
|
|
71
84
|
...options,
|
|
72
85
|
...opts.graphile.overrideSettings,
|
|
73
86
|
};
|
|
87
|
+
log.info(`${label} Building PostGraphile handler key=${key} db=${dbname} schemas=${schemaLabel} role=${roleName} anon=${anonRole}`);
|
|
74
88
|
const pgPool = (0, pg_cache_1.getPgPool)({
|
|
75
89
|
...opts.pg,
|
|
76
90
|
database: dbname,
|
|
@@ -81,9 +95,11 @@ const graphile = (opts) => {
|
|
|
81
95
|
pgPoolKey: dbname,
|
|
82
96
|
handler,
|
|
83
97
|
});
|
|
98
|
+
log.info(`${label} Cached PostGraphile handler key=${key} db=${dbname}`);
|
|
84
99
|
return handler(req, res, next);
|
|
85
100
|
}
|
|
86
101
|
catch (e) {
|
|
102
|
+
log.error(`${label} PostGraphile middleware error`, e);
|
|
87
103
|
return res.status(500).send(e.message);
|
|
88
104
|
}
|
|
89
105
|
};
|
package/middleware/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@constructive-io/graphql-server",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.15.0",
|
|
4
4
|
"author": "Constructive <developers@constructive.io>",
|
|
5
5
|
"description": "Constructive GraphQL Server",
|
|
6
6
|
"main": "index.js",
|
|
@@ -29,7 +29,9 @@
|
|
|
29
29
|
"lint": "eslint . --fix",
|
|
30
30
|
"test": "jest --passWithNoTests",
|
|
31
31
|
"test:watch": "jest --watch",
|
|
32
|
-
"bucket:create": "ts-node src/scripts/create-bucket.ts"
|
|
32
|
+
"bucket:create": "ts-node src/scripts/create-bucket.ts",
|
|
33
|
+
"codegen:schema": "ts-node src/scripts/codegen-schema.ts",
|
|
34
|
+
"codegen": "npm run codegen:schema && graphql-codegen generate-orm --schema codegen/schema.graphql --output src/codegen/orm"
|
|
33
35
|
},
|
|
34
36
|
"keywords": [
|
|
35
37
|
"server",
|
|
@@ -52,15 +54,15 @@
|
|
|
52
54
|
"express": "^5.2.1",
|
|
53
55
|
"graphile-build": "^4.14.1",
|
|
54
56
|
"graphile-cache": "^1.6.14",
|
|
55
|
-
"graphile-i18n": "^0.4.
|
|
56
|
-
"graphile-meta-schema": "^0.5.
|
|
57
|
-
"graphile-plugin-connection-filter": "^2.6.
|
|
58
|
-
"graphile-plugin-connection-filter-postgis": "^1.3.
|
|
59
|
-
"graphile-plugin-fulltext-filter": "^2.3.
|
|
57
|
+
"graphile-i18n": "^0.4.8",
|
|
58
|
+
"graphile-meta-schema": "^0.5.8",
|
|
59
|
+
"graphile-plugin-connection-filter": "^2.6.8",
|
|
60
|
+
"graphile-plugin-connection-filter-postgis": "^1.3.8",
|
|
61
|
+
"graphile-plugin-fulltext-filter": "^2.3.8",
|
|
60
62
|
"graphile-query": "^2.4.7",
|
|
61
|
-
"graphile-search-plugin": "^0.4.
|
|
62
|
-
"graphile-settings": "^2.12.
|
|
63
|
-
"graphile-simple-inflector": "^0.4.
|
|
63
|
+
"graphile-search-plugin": "^0.4.9",
|
|
64
|
+
"graphile-settings": "^2.12.9",
|
|
65
|
+
"graphile-simple-inflector": "^0.4.9",
|
|
64
66
|
"graphile-utils": "^4.14.1",
|
|
65
67
|
"graphql": "15.10.1",
|
|
66
68
|
"graphql-tag": "2.12.6",
|
|
@@ -74,14 +76,16 @@
|
|
|
74
76
|
},
|
|
75
77
|
"devDependencies": {
|
|
76
78
|
"@aws-sdk/client-s3": "^3.958.0",
|
|
79
|
+
"@constructive-io/graphql-codegen": "2.23.2",
|
|
77
80
|
"@types/cors": "^2.8.17",
|
|
78
81
|
"@types/express": "^5.0.6",
|
|
79
82
|
"@types/graphql-upload": "^8.0.12",
|
|
80
83
|
"@types/pg": "^8.16.0",
|
|
81
84
|
"@types/request-ip": "^0.0.41",
|
|
85
|
+
"graphile-test": "2.13.8",
|
|
82
86
|
"makage": "^0.1.10",
|
|
83
87
|
"nodemon": "^3.1.10",
|
|
84
88
|
"ts-node": "^10.9.2"
|
|
85
89
|
},
|
|
86
|
-
"gitHead": "
|
|
90
|
+
"gitHead": "eff12e839462a1d5435f04318db1f44fc141e235"
|
|
87
91
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const graphql_env_1 = require("@constructive-io/graphql-env");
|
|
7
|
+
const logger_1 = require("@pgpmjs/logger");
|
|
8
|
+
const graphile_settings_1 = require("graphile-settings");
|
|
9
|
+
const pg_cache_1 = require("pg-cache");
|
|
10
|
+
const graphile_query_1 = require("graphile-query");
|
|
11
|
+
const graphql_1 = require("graphql");
|
|
12
|
+
const node_fs_1 = require("node:fs");
|
|
13
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
14
|
+
const log = new logger_1.Logger('codegen-schema');
|
|
15
|
+
const getSchemaOutputPath = () => process.env.CODEGEN_SCHEMA_OUT ??
|
|
16
|
+
node_path_1.default.resolve(__dirname, '../../codegen/schema.graphql');
|
|
17
|
+
(async () => {
|
|
18
|
+
try {
|
|
19
|
+
const opts = (0, graphql_env_1.getEnvOptions)();
|
|
20
|
+
const apiOpts = opts.api || {};
|
|
21
|
+
const metaSchemas = Array.isArray(apiOpts.metaSchemas)
|
|
22
|
+
? apiOpts.metaSchemas
|
|
23
|
+
: [];
|
|
24
|
+
let schemas;
|
|
25
|
+
let usingFallback = false;
|
|
26
|
+
const dbName = process.env.CODEGEN_DATABASE || process.env.PGDATABASE || 'constructive';
|
|
27
|
+
const pgConfig = { ...opts.pg, database: dbName };
|
|
28
|
+
log.info(`Target database for codegen: ${dbName}`);
|
|
29
|
+
if (metaSchemas.length) {
|
|
30
|
+
schemas = metaSchemas;
|
|
31
|
+
log.info(`Using meta schemas: ${schemas.join(', ')}`);
|
|
32
|
+
const pool = (0, pg_cache_1.getPgPool)(pgConfig);
|
|
33
|
+
const checkResult = await pool.query(`SELECT schema_name FROM information_schema.schemata
|
|
34
|
+
WHERE schema_name = ANY($1::text[])
|
|
35
|
+
ORDER BY schema_name`, [schemas]);
|
|
36
|
+
const foundSchemas = checkResult.rows.map((r) => r.schema_name);
|
|
37
|
+
const missing = schemas.filter((s) => !foundSchemas.includes(s));
|
|
38
|
+
if (missing.length > 0) {
|
|
39
|
+
log.warn(`Missing schemas: ${missing.join(', ')}. Falling back to 'public'.`);
|
|
40
|
+
schemas = ['public'];
|
|
41
|
+
usingFallback = true;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
schemas = ['public'];
|
|
46
|
+
log.info('No meta schemas configured, using: public');
|
|
47
|
+
usingFallback = true;
|
|
48
|
+
}
|
|
49
|
+
if (usingFallback) {
|
|
50
|
+
log.warn('Schema will be generated from public schema only. To generate full meta schema, ensure meta tables exist.');
|
|
51
|
+
}
|
|
52
|
+
const settings = (0, graphile_settings_1.getGraphileSettings)({
|
|
53
|
+
...opts,
|
|
54
|
+
pg: pgConfig,
|
|
55
|
+
graphile: {
|
|
56
|
+
...opts.graphile,
|
|
57
|
+
schema: schemas,
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
const pool = (0, pg_cache_1.getPgPool)(pgConfig);
|
|
61
|
+
log.debug(`Connecting to database: ${dbName}`);
|
|
62
|
+
log.debug(`Connecting to host: ${opts.pg?.host || '(default)'}`);
|
|
63
|
+
const dbInfo = await pool.query('SELECT current_database() AS current_database, current_user AS current_user');
|
|
64
|
+
log.info(`Connected to database: ${dbInfo.rows[0]?.current_database} as user: ${dbInfo.rows[0]?.current_user}`);
|
|
65
|
+
const graphqlSchema = await (0, graphile_query_1.getSchema)(pool, settings);
|
|
66
|
+
const sdl = (0, graphql_1.printSchema)(graphqlSchema);
|
|
67
|
+
const outputPath = getSchemaOutputPath();
|
|
68
|
+
await node_fs_1.promises.mkdir(node_path_1.default.dirname(outputPath), { recursive: true });
|
|
69
|
+
await node_fs_1.promises.writeFile(outputPath, sdl, 'utf8');
|
|
70
|
+
log.success(`Schema written to ${outputPath}`);
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
log.error('Failed to write schema', error?.stack || error);
|
|
74
|
+
process.exitCode = 1;
|
|
75
|
+
}
|
|
76
|
+
})();
|
package/server.js
CHANGED
|
@@ -8,6 +8,7 @@ const graphql_env_1 = require("@constructive-io/graphql-env");
|
|
|
8
8
|
const logger_1 = require("@pgpmjs/logger");
|
|
9
9
|
const server_utils_1 = require("@pgpmjs/server-utils");
|
|
10
10
|
const url_domains_1 = require("@constructive-io/url-domains");
|
|
11
|
+
const crypto_1 = require("crypto");
|
|
11
12
|
const express_1 = __importDefault(require("express"));
|
|
12
13
|
// @ts-ignore
|
|
13
14
|
const graphql_upload_1 = __importDefault(require("graphql-upload"));
|
|
@@ -35,6 +36,25 @@ class Server {
|
|
|
35
36
|
const app = (0, express_1.default)();
|
|
36
37
|
const api = (0, api_1.createApiMiddleware)(opts);
|
|
37
38
|
const authenticate = (0, auth_1.createAuthenticateMiddleware)(opts);
|
|
39
|
+
const requestLogger = (req, res, next) => {
|
|
40
|
+
const headerRequestId = req.header('x-request-id');
|
|
41
|
+
const reqId = headerRequestId || (0, crypto_1.randomUUID)();
|
|
42
|
+
const start = process.hrtime.bigint();
|
|
43
|
+
req.requestId = reqId;
|
|
44
|
+
const host = req.hostname || req.headers.host || 'unknown';
|
|
45
|
+
const ip = req.clientIp || req.ip;
|
|
46
|
+
log.debug(`[${reqId}] -> ${req.method} ${req.originalUrl} host=${host} ip=${ip}`);
|
|
47
|
+
res.on('finish', () => {
|
|
48
|
+
const durationMs = Number(process.hrtime.bigint() - start) / 1e6;
|
|
49
|
+
const apiInfo = req.api
|
|
50
|
+
? `db=${req.api.dbname} schemas=${req.api.schema?.join(',') || 'none'}`
|
|
51
|
+
: 'api=unresolved';
|
|
52
|
+
const authInfo = req.token ? 'auth=token' : 'auth=anon';
|
|
53
|
+
const svcInfo = req.svc_key ? `svc=${req.svc_key}` : 'svc=unset';
|
|
54
|
+
log.debug(`[${reqId}] <- ${res.statusCode} ${req.method} ${req.originalUrl} (${durationMs.toFixed(1)} ms) ${apiInfo} ${svcInfo} ${authInfo}`);
|
|
55
|
+
});
|
|
56
|
+
next();
|
|
57
|
+
};
|
|
38
58
|
// Log startup config in dev mode
|
|
39
59
|
if (isDev()) {
|
|
40
60
|
log.debug(`Database: ${opts.pg?.database}@${opts.pg?.host}:${opts.pg?.port}`);
|
|
@@ -57,6 +77,7 @@ class Server {
|
|
|
57
77
|
app.use(graphql_upload_1.default.graphqlUploadExpress());
|
|
58
78
|
app.use((0, url_domains_1.middleware)());
|
|
59
79
|
app.use(request_ip_1.default.mw());
|
|
80
|
+
app.use(requestLogger);
|
|
60
81
|
app.use(api);
|
|
61
82
|
app.use(authenticate);
|
|
62
83
|
app.use((0, graphile_1.graphile)(opts));
|
package/types.d.ts
CHANGED
|
@@ -58,8 +58,8 @@ export interface OldApiStructure {
|
|
|
58
58
|
dbname: string;
|
|
59
59
|
anonRole: string;
|
|
60
60
|
roleName: string;
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
schemasByApiSchemaApiIdAndSchemaId: SchemaNodes;
|
|
62
|
+
apiExtensions: SchemaNodes;
|
|
63
63
|
apiModules: ApiModuleNodes;
|
|
64
64
|
rlsModule?: RlsModule;
|
|
65
65
|
database?: Database;
|