graphile-i18n 0.0.2 → 0.1.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.
- package/LICENSE +3 -1
- package/README.md +128 -34
- package/env.d.ts +5 -0
- package/env.js +17 -0
- package/esm/env.js +14 -0
- package/esm/index.js +5 -0
- package/esm/middleware.js +57 -0
- package/esm/plugin.js +147 -0
- package/index.d.ts +5 -0
- package/index.js +15 -0
- package/middleware.d.ts +26 -0
- package/middleware.js +65 -0
- package/package.json +33 -56
- package/plugin.d.ts +10 -0
- package/plugin.js +153 -0
- package/main/env.js +0 -22
- package/main/index.js +0 -37
- package/main/middleware.js +0 -95
- package/main/plugin.js +0 -206
- package/module/env.js +0 -9
- package/module/index.js +0 -4
- package/module/middleware.js +0 -60
- package/module/plugin.js +0 -173
package/package.json
CHANGED
|
@@ -1,38 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "graphile-i18n",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Graphile i18n plugin",
|
|
5
|
-
"author": "
|
|
6
|
-
"homepage": "https://github.com/
|
|
7
|
-
"license": "
|
|
8
|
-
"main": "
|
|
9
|
-
"module": "
|
|
10
|
-
"
|
|
11
|
-
"lib": "src",
|
|
12
|
-
"test": "__tests__"
|
|
13
|
-
},
|
|
14
|
-
"files": [
|
|
15
|
-
"main",
|
|
16
|
-
"module"
|
|
17
|
-
],
|
|
5
|
+
"author": "Dan Lynch <pyramation@gmail.com>",
|
|
6
|
+
"homepage": "https://github.com/launchql/launchql",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"main": "index.js",
|
|
9
|
+
"module": "esm/index.js",
|
|
10
|
+
"types": "index.d.ts",
|
|
18
11
|
"scripts": {
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"dev": "
|
|
24
|
-
"
|
|
25
|
-
"lint": "eslint src --fix",
|
|
12
|
+
"clean": "makage clean",
|
|
13
|
+
"copy": "makage assets",
|
|
14
|
+
"prepack": "pnpm run build",
|
|
15
|
+
"build": "makage build",
|
|
16
|
+
"build:dev": "makage build --dev",
|
|
17
|
+
"lint": "eslint . --fix",
|
|
26
18
|
"test": "jest",
|
|
27
|
-
"test:watch": "jest --watch"
|
|
28
|
-
"test:debug": "node --inspect node_modules/.bin/jest --runInBand"
|
|
19
|
+
"test:watch": "jest --watch"
|
|
29
20
|
},
|
|
30
21
|
"publishConfig": {
|
|
31
|
-
"access": "public"
|
|
22
|
+
"access": "public",
|
|
23
|
+
"directory": "dist"
|
|
32
24
|
},
|
|
33
25
|
"repository": {
|
|
34
26
|
"type": "git",
|
|
35
|
-
"url": "https://github.com/
|
|
27
|
+
"url": "https://github.com/launchql/launchql"
|
|
36
28
|
},
|
|
37
29
|
"keywords": [
|
|
38
30
|
"postgraphile",
|
|
@@ -42,41 +34,26 @@
|
|
|
42
34
|
"postgres",
|
|
43
35
|
"graphql"
|
|
44
36
|
],
|
|
45
|
-
"resolutions": {
|
|
46
|
-
"graphql": "15.5.2"
|
|
47
|
-
},
|
|
48
37
|
"bugs": {
|
|
49
|
-
"url": "https://github.com/
|
|
38
|
+
"url": "https://github.com/launchql/launchql/issues"
|
|
50
39
|
},
|
|
51
40
|
"devDependencies": {
|
|
52
|
-
"@
|
|
53
|
-
"@
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"@babel/plugin-proposal-object-rest-spread": "7.11.0",
|
|
58
|
-
"@babel/plugin-transform-runtime": "7.11.5",
|
|
59
|
-
"@babel/preset-env": "7.11.5",
|
|
60
|
-
"babel-core": "7.0.0-bridge.0",
|
|
61
|
-
"babel-eslint": "10.1.0",
|
|
62
|
-
"babel-jest": "25.1.0",
|
|
63
|
-
"babel-watch": "^7.0.0",
|
|
64
|
-
"cross-env": "^7.0.2",
|
|
65
|
-
"eslint": "6.8.0",
|
|
66
|
-
"eslint-config-prettier": "^6.10.0",
|
|
67
|
-
"eslint-plugin-prettier": "^3.1.2",
|
|
68
|
-
"graphile-test": "^0.1.1",
|
|
69
|
-
"jest": "^24.5.0",
|
|
70
|
-
"jest-in-case": "^1.0.2",
|
|
71
|
-
"prettier": "^2.1.2",
|
|
72
|
-
"regenerator-runtime": "^0.13.7"
|
|
41
|
+
"@types/accept-language-parser": "^1.5.4",
|
|
42
|
+
"@types/pg": "^8.15.2",
|
|
43
|
+
"graphile-test": "^2.8.5",
|
|
44
|
+
"makage": "^0.1.6",
|
|
45
|
+
"pgsql-test": "^2.14.8"
|
|
73
46
|
},
|
|
74
47
|
"dependencies": {
|
|
75
|
-
"@babel/runtime": "^7.11.2",
|
|
76
48
|
"accept-language-parser": "^1.5.0",
|
|
77
49
|
"dataloader": "^2.0.0",
|
|
78
|
-
"envalid": "^
|
|
79
|
-
"graphile-build": "^4.
|
|
80
|
-
"graphile-
|
|
81
|
-
|
|
82
|
-
|
|
50
|
+
"envalid": "^8.0.0",
|
|
51
|
+
"graphile-build": "^4.14.1",
|
|
52
|
+
"graphile-build-pg": "^4.14.1",
|
|
53
|
+
"graphile-utils": "^4.14.1",
|
|
54
|
+
"graphql": "15.10.1",
|
|
55
|
+
"graphql-tag": "2.12.6",
|
|
56
|
+
"pg": "^8.16.0"
|
|
57
|
+
},
|
|
58
|
+
"gitHead": "e4643c07b6a961b964bbb132308366fc549504a1"
|
|
59
|
+
}
|
package/plugin.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Plugin } from 'graphile-build';
|
|
2
|
+
export interface LangPluginOptions {
|
|
3
|
+
langPluginLanguageCodeColumn?: string;
|
|
4
|
+
langPluginLanguageCodeGqlField?: string;
|
|
5
|
+
langPluginAllowedTypes?: string[];
|
|
6
|
+
langPluginDefaultLanguages?: string[];
|
|
7
|
+
}
|
|
8
|
+
export declare const LangPlugin: Plugin;
|
|
9
|
+
export { additionalGraphQLContextFromRequest, makeLanguageDataLoaderForTable } from './middleware';
|
|
10
|
+
export default LangPlugin;
|
package/plugin.js
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.makeLanguageDataLoaderForTable = exports.additionalGraphQLContextFromRequest = exports.LangPlugin = void 0;
|
|
4
|
+
const middleware_1 = require("./middleware");
|
|
5
|
+
const defaultLanguageLoaderFactory = (0, middleware_1.makeLanguageDataLoaderForTable)();
|
|
6
|
+
const escapeIdentifier = (str) => `"${str.replace(/"/g, '""')}"`;
|
|
7
|
+
const hasI18nTag = (table) => Object.prototype.hasOwnProperty.call(table.tags, 'i18n');
|
|
8
|
+
const getPrimaryKeyInfo = (table) => {
|
|
9
|
+
const identifier = table.primaryKeyConstraint?.keyAttributes?.[0]?.name;
|
|
10
|
+
const idType = table.primaryKeyConstraint?.keyAttributes?.[0]?.type?.name;
|
|
11
|
+
return { identifier, idType };
|
|
12
|
+
};
|
|
13
|
+
const LangPlugin = (builder, options) => {
|
|
14
|
+
const { langPluginLanguageCodeColumn = 'lang_code', langPluginLanguageCodeGqlField = 'langCode', langPluginAllowedTypes = ['citext', 'text'], langPluginDefaultLanguages = ['en'] } = options;
|
|
15
|
+
builder.hook('build', (build) => {
|
|
16
|
+
const introspection = build.pgIntrospectionResultsByKind;
|
|
17
|
+
const inflection = build.inflection;
|
|
18
|
+
const tablesWithLanguageTables = introspection.class.filter(hasI18nTag);
|
|
19
|
+
const tablesWithLanguageTablesIdInfo = tablesWithLanguageTables.reduce((memo, table) => {
|
|
20
|
+
const keyInfo = getPrimaryKeyInfo(table);
|
|
21
|
+
if (table.tags.i18n) {
|
|
22
|
+
memo[table.tags.i18n] = keyInfo;
|
|
23
|
+
}
|
|
24
|
+
return memo;
|
|
25
|
+
}, {});
|
|
26
|
+
const languageVariationTables = tablesWithLanguageTables.map((table) => introspection.class.find((candidate) => candidate.name === table.tags.i18n &&
|
|
27
|
+
candidate.namespaceName === table.namespaceName));
|
|
28
|
+
const i18nTables = {};
|
|
29
|
+
const tables = {};
|
|
30
|
+
tablesWithLanguageTables.forEach((table) => {
|
|
31
|
+
const i18nTableName = table.tags.i18n;
|
|
32
|
+
i18nTables[i18nTableName] = {
|
|
33
|
+
table: table.name,
|
|
34
|
+
key: null,
|
|
35
|
+
connection: inflection.connection(inflection.tableType(table)),
|
|
36
|
+
attrs: {},
|
|
37
|
+
fields: {},
|
|
38
|
+
keyInfo: tablesWithLanguageTablesIdInfo[i18nTableName] ?? {}
|
|
39
|
+
};
|
|
40
|
+
tables[table.name] = i18nTableName;
|
|
41
|
+
});
|
|
42
|
+
languageVariationTables.forEach((table) => {
|
|
43
|
+
if (!table)
|
|
44
|
+
return;
|
|
45
|
+
const foreignConstraintsThatMatter = table.constraints
|
|
46
|
+
.filter((constraint) => constraint.type === 'f')
|
|
47
|
+
.filter((constraint) => constraint.foreignClass.name === i18nTables[table.name].table);
|
|
48
|
+
if (foreignConstraintsThatMatter.length !== 1) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const foreignKeyConstraint = foreignConstraintsThatMatter[0];
|
|
52
|
+
if (!foreignKeyConstraint || foreignKeyConstraint.keyAttributes.length !== 1) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
i18nTables[table.name].key = foreignKeyConstraint.keyAttributes[0].name;
|
|
56
|
+
const { identifier } = i18nTables[table.name].keyInfo;
|
|
57
|
+
if (!identifier)
|
|
58
|
+
return;
|
|
59
|
+
table.attributes.forEach((attr) => {
|
|
60
|
+
if ([langPluginLanguageCodeColumn, identifier].includes(attr.name))
|
|
61
|
+
return;
|
|
62
|
+
if (langPluginAllowedTypes.includes(attr.type.name)) {
|
|
63
|
+
i18nTables[table.name].fields[inflection.column(attr)] = {
|
|
64
|
+
type: attr.type.name,
|
|
65
|
+
attr: attr.name,
|
|
66
|
+
isNotNull: attr.isNotNull,
|
|
67
|
+
column: inflection.column(attr)
|
|
68
|
+
};
|
|
69
|
+
i18nTables[table.name].attrs[attr.name] = {
|
|
70
|
+
type: attr.type.name,
|
|
71
|
+
attr: attr.name,
|
|
72
|
+
column: inflection.column(attr)
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
return build.extend(build, { i18n: { i18nTables, tables } });
|
|
78
|
+
});
|
|
79
|
+
builder.hook('GraphQLObjectType:fields', (fields, build, context) => {
|
|
80
|
+
const { graphql: { GraphQLString, GraphQLObjectType, GraphQLNonNull }, i18n: { i18nTables, tables } } = build;
|
|
81
|
+
const { scope: { pgIntrospection: table, isPgRowType }, fieldWithHooks } = context;
|
|
82
|
+
if (!isPgRowType || !table || table.kind !== 'class') {
|
|
83
|
+
return fields;
|
|
84
|
+
}
|
|
85
|
+
const variationsTableName = tables[table.name];
|
|
86
|
+
if (!variationsTableName) {
|
|
87
|
+
return fields;
|
|
88
|
+
}
|
|
89
|
+
const i18nTable = i18nTables[variationsTableName];
|
|
90
|
+
const { identifier, idType } = i18nTable.keyInfo;
|
|
91
|
+
if (!identifier || !idType) {
|
|
92
|
+
return fields;
|
|
93
|
+
}
|
|
94
|
+
const { key, fields: i18nFields } = i18nTable;
|
|
95
|
+
const localeFieldName = 'localeStrings';
|
|
96
|
+
const localeFieldsConfig = Object.keys(i18nFields).reduce((memo, field) => {
|
|
97
|
+
memo[field] = {
|
|
98
|
+
type: i18nFields[field].isNotNull
|
|
99
|
+
? new GraphQLNonNull(GraphQLString)
|
|
100
|
+
: GraphQLString,
|
|
101
|
+
description: `Locale for ${field}`
|
|
102
|
+
};
|
|
103
|
+
return memo;
|
|
104
|
+
}, {
|
|
105
|
+
langCode: {
|
|
106
|
+
type: GraphQLString
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
const localeFieldsType = new GraphQLObjectType({
|
|
110
|
+
name: `${context.Self.name}LocaleStrings`,
|
|
111
|
+
description: `Locales for ${context.Self.name}`,
|
|
112
|
+
fields: localeFieldsConfig
|
|
113
|
+
});
|
|
114
|
+
return build.extend(fields, {
|
|
115
|
+
[localeFieldName]: fieldWithHooks(localeFieldName, (fieldContext) => {
|
|
116
|
+
const { addDataGenerator } = fieldContext;
|
|
117
|
+
addDataGenerator(() => ({
|
|
118
|
+
pgQuery: (queryBuilder) => {
|
|
119
|
+
queryBuilder.select(build.pgSql.fragment `${queryBuilder.getTableAlias()}.${build.pgSql.identifier(identifier)}`, identifier);
|
|
120
|
+
}
|
|
121
|
+
}));
|
|
122
|
+
const coalescedFields = Object.keys(i18nFields).map((field) => {
|
|
123
|
+
const columnName = i18nFields[field].attr;
|
|
124
|
+
const escColumnName = escapeIdentifier(columnName);
|
|
125
|
+
const escFieldName = escapeIdentifier(field);
|
|
126
|
+
return `coalesce(v.${escColumnName}, b.${escColumnName}) as ${escFieldName}`;
|
|
127
|
+
});
|
|
128
|
+
const props = {
|
|
129
|
+
table,
|
|
130
|
+
coalescedFields,
|
|
131
|
+
variationsTableName,
|
|
132
|
+
key
|
|
133
|
+
};
|
|
134
|
+
return {
|
|
135
|
+
description: `Locales for ${context.Self.name}`,
|
|
136
|
+
type: new GraphQLNonNull(localeFieldsType),
|
|
137
|
+
async resolve(source, _args, gqlContext) {
|
|
138
|
+
const languageCodes = gqlContext.langCodes ?? langPluginDefaultLanguages;
|
|
139
|
+
const getLoader = gqlContext.getLanguageDataLoader ??
|
|
140
|
+
defaultLanguageLoaderFactory;
|
|
141
|
+
const dataloader = getLoader(props, gqlContext.pgClient, languageCodes, identifier, idType, langPluginLanguageCodeColumn, langPluginLanguageCodeGqlField);
|
|
142
|
+
return dataloader.load(source.id);
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
}, 'Adding the language code field from the lang plugin')
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
};
|
|
149
|
+
exports.LangPlugin = LangPlugin;
|
|
150
|
+
var middleware_2 = require("./middleware");
|
|
151
|
+
Object.defineProperty(exports, "additionalGraphQLContextFromRequest", { enumerable: true, get: function () { return middleware_2.additionalGraphQLContextFromRequest; } });
|
|
152
|
+
Object.defineProperty(exports, "makeLanguageDataLoaderForTable", { enumerable: true, get: function () { return middleware_2.makeLanguageDataLoaderForTable; } });
|
|
153
|
+
exports.default = exports.LangPlugin;
|
package/main/env.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports["default"] = void 0;
|
|
7
|
-
|
|
8
|
-
var _envalid = require("envalid");
|
|
9
|
-
|
|
10
|
-
var array = (0, _envalid.makeValidator)(function (x) {
|
|
11
|
-
return x.split(',');
|
|
12
|
-
}, '');
|
|
13
|
-
|
|
14
|
-
var _default = (0, _envalid.cleanEnv)(process.env, {
|
|
15
|
-
ACCEPTED_LANGUAGES: array({
|
|
16
|
-
"default": 'en,es'
|
|
17
|
-
})
|
|
18
|
-
}, {
|
|
19
|
-
dotEnvPath: null
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
exports["default"] = _default;
|
package/main/index.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
var _exportNames = {};
|
|
7
|
-
exports["default"] = void 0;
|
|
8
|
-
|
|
9
|
-
var _plugin = require("./plugin");
|
|
10
|
-
|
|
11
|
-
Object.keys(_plugin).forEach(function (key) {
|
|
12
|
-
if (key === "default" || key === "__esModule") return;
|
|
13
|
-
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
14
|
-
if (key in exports && exports[key] === _plugin[key]) return;
|
|
15
|
-
Object.defineProperty(exports, key, {
|
|
16
|
-
enumerable: true,
|
|
17
|
-
get: function get() {
|
|
18
|
-
return _plugin[key];
|
|
19
|
-
}
|
|
20
|
-
});
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
var _middleware = require("./middleware");
|
|
24
|
-
|
|
25
|
-
Object.keys(_middleware).forEach(function (key) {
|
|
26
|
-
if (key === "default" || key === "__esModule") return;
|
|
27
|
-
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
28
|
-
if (key in exports && exports[key] === _middleware[key]) return;
|
|
29
|
-
Object.defineProperty(exports, key, {
|
|
30
|
-
enumerable: true,
|
|
31
|
-
get: function get() {
|
|
32
|
-
return _middleware[key];
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
});
|
|
36
|
-
var _default = _plugin.LangPlugin;
|
|
37
|
-
exports["default"] = _default;
|
package/main/middleware.js
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
-
|
|
5
|
-
Object.defineProperty(exports, "__esModule", {
|
|
6
|
-
value: true
|
|
7
|
-
});
|
|
8
|
-
exports.makeLanguageDataLoaderForTable = exports.additionalGraphQLContextFromRequest = void 0;
|
|
9
|
-
|
|
10
|
-
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
11
|
-
|
|
12
|
-
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
13
|
-
|
|
14
|
-
var _dataloader = _interopRequireDefault(require("dataloader"));
|
|
15
|
-
|
|
16
|
-
var _acceptLanguageParser = _interopRequireDefault(require("accept-language-parser"));
|
|
17
|
-
|
|
18
|
-
var _env = _interopRequireDefault(require("./env"));
|
|
19
|
-
|
|
20
|
-
var escapeIdentifier = function escapeIdentifier(str) {
|
|
21
|
-
return "\"".concat(str.replace(/"/g, '""'), "\"");
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
var makeLanguageDataLoaderForTable = function makeLanguageDataLoaderForTable(_req) {
|
|
25
|
-
var cache = new Map();
|
|
26
|
-
return function (props, pgClient, languageCodes, identifer, idType, sqlField, gqlField) {
|
|
27
|
-
var dataLoader = cache.get(props);
|
|
28
|
-
|
|
29
|
-
if (!dataLoader) {
|
|
30
|
-
var table = props.table,
|
|
31
|
-
coalescedFields = props.coalescedFields,
|
|
32
|
-
variationsTableName = props.variationsTableName,
|
|
33
|
-
key = props.key;
|
|
34
|
-
var schemaName = escapeIdentifier(table.namespaceName);
|
|
35
|
-
var baseTable = escapeIdentifier(table.name);
|
|
36
|
-
var variationTable = escapeIdentifier(variationsTableName);
|
|
37
|
-
var joinKey = escapeIdentifier(key);
|
|
38
|
-
var fields = coalescedFields.join(', ');
|
|
39
|
-
var b = [schemaName, baseTable].join('.');
|
|
40
|
-
var v = [schemaName, variationTable].join('.');
|
|
41
|
-
dataLoader = new _dataloader["default"]( /*#__PURE__*/function () {
|
|
42
|
-
var _ref = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(ids) {
|
|
43
|
-
var _yield$pgClient$query, rows;
|
|
44
|
-
|
|
45
|
-
return _regenerator["default"].wrap(function _callee$(_context) {
|
|
46
|
-
while (1) {
|
|
47
|
-
switch (_context.prev = _context.next) {
|
|
48
|
-
case 0:
|
|
49
|
-
_context.next = 2;
|
|
50
|
-
return pgClient.query("\n select *\n from unnest($1::".concat(idType, "[]) ids(").concat(identifer, ")\n inner join lateral (\n select b.").concat(identifer, ", v.").concat(sqlField, " as \"").concat(gqlField, "\", ").concat(fields, "\n from ").concat(b, " b\n left join ").concat(v, " v\n on (v.").concat(joinKey, " = b.").concat(identifer, " and array_position($2, ").concat(sqlField, ") is not null)\n where b.").concat(identifer, " = ids.").concat(identifer, "\n order by array_position($2, ").concat(sqlField, ") asc nulls last\n limit 1\n ) tmp on (true)\n "), [ids, languageCodes]);
|
|
51
|
-
|
|
52
|
-
case 2:
|
|
53
|
-
_yield$pgClient$query = _context.sent;
|
|
54
|
-
rows = _yield$pgClient$query.rows;
|
|
55
|
-
return _context.abrupt("return", ids.map(function (id) {
|
|
56
|
-
return rows.find(function (r) {
|
|
57
|
-
return r.id === id;
|
|
58
|
-
});
|
|
59
|
-
}));
|
|
60
|
-
|
|
61
|
-
case 5:
|
|
62
|
-
case "end":
|
|
63
|
-
return _context.stop();
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}, _callee);
|
|
67
|
-
}));
|
|
68
|
-
|
|
69
|
-
return function (_x) {
|
|
70
|
-
return _ref.apply(this, arguments);
|
|
71
|
-
};
|
|
72
|
-
}());
|
|
73
|
-
cache.set(props, dataLoader);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return dataLoader;
|
|
77
|
-
};
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
exports.makeLanguageDataLoaderForTable = makeLanguageDataLoaderForTable;
|
|
81
|
-
|
|
82
|
-
var additionalGraphQLContextFromRequest = function additionalGraphQLContextFromRequest(req, res) {
|
|
83
|
-
var language = _acceptLanguageParser["default"].pick(_env["default"].ACCEPTED_LANGUAGES, req.get('accept-language')); // Accept-Language: *
|
|
84
|
-
// Accept-Language: en-US,en;q=0.5
|
|
85
|
-
// Accept-Language: fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
return {
|
|
89
|
-
langCodes: [language],
|
|
90
|
-
// in future make fallback languages
|
|
91
|
-
getLanguageDataLoader: makeLanguageDataLoaderForTable(req)
|
|
92
|
-
};
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
exports.additionalGraphQLContextFromRequest = additionalGraphQLContextFromRequest;
|
package/main/plugin.js
DELETED
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
-
|
|
5
|
-
Object.defineProperty(exports, "__esModule", {
|
|
6
|
-
value: true
|
|
7
|
-
});
|
|
8
|
-
exports.LangPlugin = void 0;
|
|
9
|
-
|
|
10
|
-
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
11
|
-
|
|
12
|
-
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
13
|
-
|
|
14
|
-
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
15
|
-
|
|
16
|
-
var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral"));
|
|
17
|
-
|
|
18
|
-
var _templateObject;
|
|
19
|
-
|
|
20
|
-
var escapeIdentifier = function escapeIdentifier(str) {
|
|
21
|
-
return "\"".concat(str.replace(/"/g, '""'), "\"");
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
var LangPlugin = function LangPlugin(builder, options) {
|
|
25
|
-
var _options$langPluginLa = options.langPluginLanguageCodeColumn,
|
|
26
|
-
langPluginLanguageCodeColumn = _options$langPluginLa === void 0 ? 'lang_code' : _options$langPluginLa,
|
|
27
|
-
_options$langPluginLa2 = options.langPluginLanguageCodeGqlField,
|
|
28
|
-
langPluginLanguageCodeGqlField = _options$langPluginLa2 === void 0 ? 'langCode' : _options$langPluginLa2,
|
|
29
|
-
_options$langPluginAl = options.langPluginAllowedTypes,
|
|
30
|
-
langPluginAllowedTypes = _options$langPluginAl === void 0 ? ['citext', 'text'] : _options$langPluginAl,
|
|
31
|
-
_options$langPluginDe = options.langPluginDefaultLanguages,
|
|
32
|
-
langPluginDefaultLanguages = _options$langPluginDe === void 0 ? ['en'] : _options$langPluginDe;
|
|
33
|
-
builder.hook('build', function (build) {
|
|
34
|
-
var sql = build.pgSql;
|
|
35
|
-
/** @type {import('graphile-build-pg').PgIntrospectionResultsByKind} */
|
|
36
|
-
|
|
37
|
-
var introspection = build.pgIntrospectionResultsByKind;
|
|
38
|
-
var inflection = build.inflection;
|
|
39
|
-
var tablesWithLanguageTables = introspection["class"].filter(function (table) {
|
|
40
|
-
return table.tags.hasOwnProperty('i18n');
|
|
41
|
-
});
|
|
42
|
-
var tablesWithLanguageTablesIdInfo = introspection["class"].filter(function (table) {
|
|
43
|
-
return table.tags.hasOwnProperty('i18n');
|
|
44
|
-
}).map(function (table) {
|
|
45
|
-
return {
|
|
46
|
-
identifier: table.primaryKeyConstraint.keyAttributes[0].name,
|
|
47
|
-
idType: table.primaryKeyConstraint.keyAttributes[0].type.name
|
|
48
|
-
};
|
|
49
|
-
});
|
|
50
|
-
var languageVariationTables = tablesWithLanguageTables.map(function (table) {
|
|
51
|
-
return introspection["class"].find(function (t) {
|
|
52
|
-
return t.name === table.tags.i18n && t.namespaceName === table.namespaceName;
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
var i18nTables = {};
|
|
56
|
-
var tables = {};
|
|
57
|
-
tablesWithLanguageTables.forEach(function (table, i) {
|
|
58
|
-
i18nTables[table.tags.i18n] = {
|
|
59
|
-
table: table.name,
|
|
60
|
-
key: null,
|
|
61
|
-
// action_id
|
|
62
|
-
connection: inflection.connection(inflection.tableType(table)),
|
|
63
|
-
attrs: {},
|
|
64
|
-
fields: {},
|
|
65
|
-
keyInfo: tablesWithLanguageTablesIdInfo[i]
|
|
66
|
-
};
|
|
67
|
-
tables[table.name] = table.tags.i18n;
|
|
68
|
-
});
|
|
69
|
-
languageVariationTables.forEach(function (table) {
|
|
70
|
-
var foreignConstraintsThatMatter = table.constraints.filter(function (c) {
|
|
71
|
-
return c.type === 'f';
|
|
72
|
-
}).filter(function (c) {
|
|
73
|
-
return c.foreignClass.name === i18nTables[table.name].table;
|
|
74
|
-
});
|
|
75
|
-
if (foreignConstraintsThatMatter.length !== 1) throw new Error('lang table only supports one foreign key to parent table');
|
|
76
|
-
if (foreignConstraintsThatMatter[0].keyAttributes.length !== 1) throw new Error('lang table only supports one non compound foreign key to parent table');
|
|
77
|
-
i18nTables[table.name].key = foreignConstraintsThatMatter[0].keyAttributes[0].name;
|
|
78
|
-
var _i18nTables$table$nam = i18nTables[table.name].keyInfo,
|
|
79
|
-
identifier = _i18nTables$table$nam.identifier,
|
|
80
|
-
idType = _i18nTables$table$nam.idType;
|
|
81
|
-
table.attributes.forEach(function (attr) {
|
|
82
|
-
if ([langPluginLanguageCodeColumn, identifier].includes(attr.name)) return;
|
|
83
|
-
|
|
84
|
-
if (langPluginAllowedTypes.includes(attr.type.name)) {
|
|
85
|
-
i18nTables[table.name].fields[inflection.column(attr)] = {
|
|
86
|
-
type: attr.type.name,
|
|
87
|
-
attr: attr.name,
|
|
88
|
-
isNotNull: attr.isNotNull,
|
|
89
|
-
column: inflection.column(attr)
|
|
90
|
-
};
|
|
91
|
-
i18nTables[table.name].attrs[attr.name] = {
|
|
92
|
-
type: attr.type.name,
|
|
93
|
-
attr: attr.name,
|
|
94
|
-
column: inflection.column(attr)
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
return build.extend(build, {
|
|
100
|
-
i18n: {
|
|
101
|
-
i18nTables: i18nTables,
|
|
102
|
-
tables: tables
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
|
-
builder.hook('GraphQLObjectType:fields', function (fields, build, context) {
|
|
107
|
-
var _build$graphql = build.graphql,
|
|
108
|
-
GraphQLString = _build$graphql.GraphQLString,
|
|
109
|
-
GraphQLObjectType = _build$graphql.GraphQLObjectType,
|
|
110
|
-
GraphQLNonNull = _build$graphql.GraphQLNonNull,
|
|
111
|
-
_build$i18n = build.i18n,
|
|
112
|
-
i18nTables = _build$i18n.i18nTables,
|
|
113
|
-
tables = _build$i18n.tables,
|
|
114
|
-
sql = build.pgSql;
|
|
115
|
-
var _context$scope = context.scope,
|
|
116
|
-
table = _context$scope.pgIntrospection,
|
|
117
|
-
isPgRowType = _context$scope.isPgRowType,
|
|
118
|
-
fieldWithHooks = context.fieldWithHooks;
|
|
119
|
-
|
|
120
|
-
if (!isPgRowType || !table || table.kind !== 'class') {
|
|
121
|
-
return fields;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
var variationsTableName = tables[table.name];
|
|
125
|
-
|
|
126
|
-
if (!variationsTableName) {
|
|
127
|
-
return fields;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
var i18nTable = i18nTables[variationsTableName];
|
|
131
|
-
var _i18nTable$keyInfo = i18nTable.keyInfo,
|
|
132
|
-
identifier = _i18nTable$keyInfo.identifier,
|
|
133
|
-
idType = _i18nTable$keyInfo.idType;
|
|
134
|
-
var key = i18nTable.key,
|
|
135
|
-
connection = i18nTable.connection,
|
|
136
|
-
attrs = i18nTable.attrs,
|
|
137
|
-
i18nFields = i18nTable.fields;
|
|
138
|
-
var localeFieldName = 'localeStrings';
|
|
139
|
-
var localeFieldsType = new GraphQLObjectType({
|
|
140
|
-
name: "".concat(context.Self.name, "LocaleStrings"),
|
|
141
|
-
description: "Locales for ".concat(context.Self.name),
|
|
142
|
-
fields: Object.keys(i18nFields).reduce(function (memo, field) {
|
|
143
|
-
memo[field] = {
|
|
144
|
-
type: i18nFields[field].isNotNull ? new GraphQLNonNull(GraphQLString) : GraphQLString,
|
|
145
|
-
description: "Locale for ".concat(field)
|
|
146
|
-
};
|
|
147
|
-
return memo;
|
|
148
|
-
}, {
|
|
149
|
-
langCode: {
|
|
150
|
-
type: GraphQLString // MUST BE NULLABLE
|
|
151
|
-
|
|
152
|
-
}
|
|
153
|
-
})
|
|
154
|
-
});
|
|
155
|
-
return build.extend(fields, (0, _defineProperty2["default"])({}, localeFieldName, fieldWithHooks(localeFieldName, function (fieldContext) {
|
|
156
|
-
var addDataGenerator = fieldContext.addDataGenerator;
|
|
157
|
-
addDataGenerator(function (parsedResolveInfoFragment) {
|
|
158
|
-
return {
|
|
159
|
-
pgQuery: function pgQuery(queryBuilder) {
|
|
160
|
-
queryBuilder.select(sql.fragment(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2["default"])(["", ".", ""])), queryBuilder.getTableAlias(), sql.identifier(identifier)), identifier);
|
|
161
|
-
}
|
|
162
|
-
};
|
|
163
|
-
});
|
|
164
|
-
var coalescedFields = Object.keys(i18nFields).map(function (field) {
|
|
165
|
-
var columnName = i18nFields[field].attr;
|
|
166
|
-
var escColumnName = escapeIdentifier(columnName);
|
|
167
|
-
var escFieldName = escapeIdentifier(field);
|
|
168
|
-
return "coalesce(v.".concat(escColumnName, ", b.").concat(escColumnName, ") as ").concat(escFieldName);
|
|
169
|
-
});
|
|
170
|
-
var props = {
|
|
171
|
-
table: table,
|
|
172
|
-
coalescedFields: coalescedFields,
|
|
173
|
-
variationsTableName: variationsTableName,
|
|
174
|
-
key: key
|
|
175
|
-
};
|
|
176
|
-
return {
|
|
177
|
-
description: "Locales for ".concat(context.Self.name),
|
|
178
|
-
type: new GraphQLNonNull(localeFieldsType),
|
|
179
|
-
resolve: function resolve(_ref, args, context) {
|
|
180
|
-
return (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee() {
|
|
181
|
-
var _context$langCodes;
|
|
182
|
-
|
|
183
|
-
var id, languageCodes, dataloader;
|
|
184
|
-
return _regenerator["default"].wrap(function _callee$(_context) {
|
|
185
|
-
while (1) {
|
|
186
|
-
switch (_context.prev = _context.next) {
|
|
187
|
-
case 0:
|
|
188
|
-
id = _ref.id;
|
|
189
|
-
languageCodes = (_context$langCodes = context.langCodes) !== null && _context$langCodes !== void 0 ? _context$langCodes : langPluginDefaultLanguages;
|
|
190
|
-
dataloader = context.getLanguageDataLoader(props, context.pgClient, languageCodes, identifier, idType, langPluginLanguageCodeColumn, langPluginLanguageCodeGqlField);
|
|
191
|
-
return _context.abrupt("return", dataloader.load(id));
|
|
192
|
-
|
|
193
|
-
case 4:
|
|
194
|
-
case "end":
|
|
195
|
-
return _context.stop();
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}, _callee);
|
|
199
|
-
}))();
|
|
200
|
-
}
|
|
201
|
-
};
|
|
202
|
-
}, 'Adding the language code field from the lang plugin')));
|
|
203
|
-
});
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
exports.LangPlugin = LangPlugin;
|
package/module/env.js
DELETED
package/module/index.js
DELETED