text-to-map 1.1.46 → 1.1.48

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.
Files changed (97) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +69 -69
  3. package/dist/bin/address-points.d.ts +1 -1
  4. package/dist/bin/address-points.js +16 -16
  5. package/dist/bin/cities.d.ts +1 -1
  6. package/dist/bin/cities.js +10 -10
  7. package/dist/bin/clear-all.d.ts +1 -1
  8. package/dist/bin/clear-all.js +13 -13
  9. package/dist/bin/constants.d.ts +2 -2
  10. package/dist/bin/constants.js +4 -4
  11. package/dist/bin/generate-syntax-diagrams.d.ts +1 -1
  12. package/dist/bin/generate-syntax-diagrams.js +20 -20
  13. package/dist/bin/init-db.d.ts +1 -1
  14. package/dist/bin/init-db.js +8 -8
  15. package/dist/bin/knex.d.ts +1 -1
  16. package/dist/bin/knex.js +10 -10
  17. package/dist/bin/parse-ordinance.d.ts +1 -1
  18. package/dist/bin/parse-ordinance.js +74 -74
  19. package/dist/bin/polygons.d.ts +1 -1
  20. package/dist/bin/polygons.js +27 -27
  21. package/dist/bin/regions.d.ts +1 -1
  22. package/dist/bin/regions.js +10 -10
  23. package/dist/bin/schools.d.ts +1 -1
  24. package/dist/bin/schools.js +10 -10
  25. package/dist/bin/streets.d.ts +1 -1
  26. package/dist/bin/streets.js +19 -19
  27. package/dist/bin/sync-all.d.ts +1 -1
  28. package/dist/bin/sync-all.js +4 -4
  29. package/dist/db/address-points.d.ts +59 -59
  30. package/dist/db/address-points.js +406 -399
  31. package/dist/db/cities.d.ts +7 -7
  32. package/dist/db/cities.js +95 -95
  33. package/dist/db/db.d.ts +45 -37
  34. package/dist/db/db.js +212 -191
  35. package/dist/db/founders.d.ts +14 -14
  36. package/dist/db/founders.js +461 -461
  37. package/dist/db/meta.d.ts +4 -4
  38. package/dist/db/meta.js +26 -26
  39. package/dist/db/migrations/20230704125715_initial.js +304 -304
  40. package/dist/db/migrations/20230731232915_city_positions.js +13 -13
  41. package/dist/db/migrations/20240106224603_city_polygon.js +11 -11
  42. package/dist/db/migrations/20240320200534_district_polygon.js +11 -11
  43. package/dist/db/migrations/20250316162700_kindergartens.js +12 -12
  44. package/dist/db/regions.d.ts +31 -31
  45. package/dist/db/regions.js +81 -81
  46. package/dist/db/schools.d.ts +7 -7
  47. package/dist/db/schools.js +95 -95
  48. package/dist/db/street-sync.d.ts +6 -6
  49. package/dist/db/street-sync.js +24 -22
  50. package/dist/db/sync-log.d.ts +9 -9
  51. package/dist/db/sync-log.js +66 -66
  52. package/dist/db/types.d.ts +59 -59
  53. package/dist/db/types.js +26 -26
  54. package/dist/index.d.ts +23 -23
  55. package/dist/index.js +32 -32
  56. package/dist/open-data-sync/address-points.d.ts +2 -2
  57. package/dist/open-data-sync/address-points.js +68 -68
  58. package/dist/open-data-sync/cities.d.ts +2 -2
  59. package/dist/open-data-sync/cities.js +32 -32
  60. package/dist/open-data-sync/common.d.ts +2 -2
  61. package/dist/open-data-sync/common.js +22 -22
  62. package/dist/open-data-sync/regions.d.ts +2 -2
  63. package/dist/open-data-sync/regions.js +37 -37
  64. package/dist/open-data-sync/schools.d.ts +3 -3
  65. package/dist/open-data-sync/schools.js +207 -207
  66. package/dist/open-data-sync/streets.d.ts +2 -2
  67. package/dist/open-data-sync/streets.js +132 -132
  68. package/dist/smd-to-csv/json-to-csv.d.ts +1 -1
  69. package/dist/smd-to-csv/json-to-csv.js +154 -154
  70. package/dist/smd-to-csv/ordinance-to-csv-rules.d.ts +1 -1
  71. package/dist/smd-to-csv/ordinance-to-csv-rules.js +23 -23
  72. package/dist/smd-to-csv/txt-to-json.d.ts +1 -1
  73. package/dist/smd-to-csv/txt-to-json.js +92 -92
  74. package/dist/souradnice.csv +6260 -6260
  75. package/dist/street-markdown/municipality.d.ts +11 -11
  76. package/dist/street-markdown/municipality.js +116 -116
  77. package/dist/street-markdown/polygons.d.ts +7 -7
  78. package/dist/street-markdown/polygons.js +261 -261
  79. package/dist/street-markdown/roman-numerals.d.ts +1 -1
  80. package/dist/street-markdown/roman-numerals.js +68 -68
  81. package/dist/street-markdown/smd-line-parser.d.ts +4 -4
  82. package/dist/street-markdown/smd-line-parser.js +40 -40
  83. package/dist/street-markdown/smd-parser.d.ts +23 -23
  84. package/dist/street-markdown/smd-parser.js +393 -393
  85. package/dist/street-markdown/smd.d.ts +24 -24
  86. package/dist/street-markdown/smd.js +440 -440
  87. package/dist/street-markdown/token-definition.d.ts +25 -25
  88. package/dist/street-markdown/token-definition.js +168 -168
  89. package/dist/street-markdown/types.d.ts +148 -148
  90. package/dist/street-markdown/types.js +13 -13
  91. package/dist/utils/atom.d.ts +2 -2
  92. package/dist/utils/atom.js +57 -57
  93. package/dist/utils/helpers.d.ts +28 -28
  94. package/dist/utils/helpers.js +176 -176
  95. package/dist/utils/jtsk2wgs84.d.ts +17 -17
  96. package/dist/utils/jtsk2wgs84.js +82 -82
  97. package/package.json +109 -109
package/dist/db/db.js CHANGED
@@ -1,191 +1,212 @@
1
- import { configDotenv } from "dotenv";
2
- import knex from "knex";
3
- import { dirname, join } from "path";
4
- import { fileURLToPath } from "url";
5
- const __filename = fileURLToPath(import.meta.url);
6
- const __dirname = dirname(__filename);
7
- export var SupportedDbType;
8
- (function (SupportedDbType) {
9
- SupportedDbType["sqlite"] = "sqlite";
10
- SupportedDbType["postgres"] = "postgres";
11
- SupportedDbType["mysql"] = "mysql";
12
- })(SupportedDbType || (SupportedDbType = {}));
13
- const mysqlConnectionStringPattern = /^([^:]+):(\d+):([^:]+):([^:]+):([^:]+)$/;
14
- const DbClient = {
15
- [SupportedDbType.sqlite]: "better-sqlite3",
16
- [SupportedDbType.postgres]: "pg",
17
- [SupportedDbType.mysql]: "mysql",
18
- };
19
- const defaults = {
20
- dbType: SupportedDbType.sqlite,
21
- filePath: "address_points.db",
22
- initFilePath: join(__dirname, "..", "address_points_init.db"),
23
- verbose: false,
24
- };
25
- let _knexDb = undefined;
26
- let _knexDbConfig = undefined;
27
- export const getKnexDb = (config = {}) => {
28
- if (_knexDb === undefined) {
29
- _knexDbConfig = { ...defaults, ...getEnvConfig(), ...config };
30
- if (_knexDbConfig.dbType === SupportedDbType.sqlite) {
31
- _knexDb = knex({
32
- client: DbClient[SupportedDbType.sqlite],
33
- connection: {
34
- filename: _knexDbConfig.filePath,
35
- },
36
- pool: {
37
- afterCreate: (db, done) => {
38
- db.pragma("journal_mode = WAL;");
39
- done(false, done);
40
- },
41
- },
42
- useNullAsDefault: true,
43
- debug: _knexDbConfig.verbose,
44
- });
45
- }
46
- else if (_knexDbConfig.dbType === SupportedDbType.postgres) {
47
- _knexDb = knex({
48
- client: DbClient[SupportedDbType.postgres],
49
- connection: _knexDbConfig.pgConnectionString,
50
- useNullAsDefault: true,
51
- debug: _knexDbConfig.verbose,
52
- });
53
- }
54
- else if (_knexDbConfig.dbType === SupportedDbType.mysql) {
55
- const [host, port, user, password, database] = _knexDbConfig.mysqlConnectionString.split(":");
56
- _knexDb = knex({
57
- client: DbClient[SupportedDbType.mysql],
58
- connection: {
59
- host,
60
- port: Number(port),
61
- user,
62
- password,
63
- database,
64
- },
65
- useNullAsDefault: true,
66
- debug: _knexDbConfig.verbose,
67
- });
68
- }
69
- else {
70
- throw new Error(`Unsupported DB type: ${_knexDbConfig.dbType}`);
71
- }
72
- }
73
- return _knexDb;
74
- };
75
- export const isPostgres = (knex) => {
76
- return knex.client.config.client === DbClient[SupportedDbType.postgres];
77
- };
78
- export const isSqlite = (knex) => {
79
- return knex.client.config.client === DbClient[SupportedDbType.sqlite];
80
- };
81
- export const isMysql = (knex) => {
82
- return knex.client.config.client === DbClient[SupportedDbType.mysql];
83
- };
84
- const getMigrationConfig = () => {
85
- return { directory: join(__dirname, "migrations") };
86
- };
87
- export const initDb = async (config = {}) => {
88
- const knex = getKnexDb(config);
89
- await knex.migrate.latest(getMigrationConfig());
90
- return knex;
91
- };
92
- export const clearDb = async (config = {}) => {
93
- const knex = getKnexDb(config);
94
- await knex.migrate.rollback(getMigrationConfig(), true);
95
- await knex.migrate.latest(getMigrationConfig());
96
- return knex;
97
- };
98
- export const disconnectKnex = async () => {
99
- if (_knexDb) {
100
- await _knexDb.destroy();
101
- _knexDb = undefined;
102
- }
103
- };
104
- const getEnvConfig = () => {
105
- configDotenv({ path: ".env.local" });
106
- const envConfig = {};
107
- if (process.env.TEXTTOMAP_DB_TYPE &&
108
- Object.values(SupportedDbType).includes(process.env.TEXTTOMAP_DB_TYPE)) {
109
- envConfig.dbType = process.env.TEXTTOMAP_DB_TYPE;
110
- if (envConfig.dbType === SupportedDbType.postgres) {
111
- if (!process.env.TEXTTOMAP_PG_CONNECTION_STRING) {
112
- throw new Error("Environmental variable 'TEXTTOMAP_PG_CONNECTION_STRING' must be set for PostgreSQL.");
113
- }
114
- envConfig.pgConnectionString = process.env.TEXTTOMAP_PG_CONNECTION_STRING;
115
- }
116
- else if (envConfig.dbType === SupportedDbType.mysql) {
117
- if (!process.env.TEXTTOMAP_MYSQL_CONNECTION_DATA) {
118
- throw new Error("Environmental variable 'TEXTTOMAP_MYSQL_CONNECTION_DATA' must be set for MySQL or MariaDB.");
119
- }
120
- if (!mysqlConnectionStringPattern.test(process.env.TEXTTOMAP_MYSQL_CONNECTION_DATA)) {
121
- throw new Error("Environmental variable 'TEXTTOMAP_MYSQL_CONNECTION_DATA' must be in format 'host:port:user:password:database'.");
122
- }
123
- envConfig.mysqlConnectionString =
124
- process.env.TEXTTOMAP_MYSQL_CONNECTION_DATA;
125
- }
126
- else if (envConfig.dbType === SupportedDbType.sqlite) {
127
- if (process.env.TEXTTOMAP_SQLITE_PATH) {
128
- envConfig.filePath = process.env.TEXTTOMAP_SQLITE_PATH;
129
- }
130
- }
131
- }
132
- return envConfig;
133
- };
134
- export const nonEmptyOrNull = (value) => {
135
- return value ? value : null;
136
- };
137
- export const rawQuery = async (query, ...bindings) => {
138
- const knex = getKnexDb();
139
- const result = await knex.raw(query, ...bindings);
140
- return isMysql(knex) ? result[0] : result;
141
- };
142
- /**
143
- * Efficiently insert multiple rows. If preventDuplicatesByFirstColumn is true, the first
144
- * column should be unique (PK or UNIQUE).
145
- */
146
- export const insertMultipleRows = async (rows, table, columnNames, preventDuplicates = true) => {
147
- if (rows.length === 0) {
148
- return 0;
149
- }
150
- const insertPlaceholders = generate2DPlaceholders(columnNames.length, rows.length);
151
- const knex = getKnexDb();
152
- const onConfict = preventDuplicates && !isMysql(knex) ? `ON CONFLICT DO NOTHING` : "";
153
- await rawQuery(`INSERT ${isMysql(knex) ? "IGNORE" : ""} INTO ${table} (${columnNames.join(",")}) VALUES ${insertPlaceholders} ${onConfict}`, rows.flat());
154
- return rows.length;
155
- };
156
- /**
157
- * Insert a single row and return the autoincremented ID.
158
- */
159
- export const insertAutoincrementRow = async (row, table, columnNames) => {
160
- const data = columnNames.reduce((obj, columnName, index) => {
161
- obj[columnName] = row[index];
162
- return obj;
163
- }, {});
164
- const result = await getKnexDb().insert(data).into(table);
165
- return result ? Number(result) : null;
166
- };
167
- export const deleteMultipleRowsKnex = async (keys, table, keyColumnName) => {
168
- if (keys.length === 0) {
169
- return;
170
- }
171
- await getKnexDb().from(table).whereIn(keyColumnName, keys).del();
172
- };
173
- const generateRepetitiveString = (value, glue, n) => {
174
- return new Array(n).fill(value).join(glue);
175
- };
176
- export const generatePlaceholders = (n) => {
177
- return generateRepetitiveString("?", ",", n);
178
- };
179
- export const generate2DPlaceholders = (inner, outer) => {
180
- return generateRepetitiveString(`(${generatePlaceholders(inner)})`, ",", outer);
181
- };
182
- export const extractKeyValuesPairs = (array, keyIndex, valuesIndices) => {
183
- const object = array.reduce((acc, data) => {
184
- if (data[keyIndex]) {
185
- acc[data[keyIndex]] = valuesIndices.map((index) => nonEmptyOrNull(data[index]));
186
- }
187
- return acc;
188
- }, {});
189
- return Object.keys(object).map((key) => [key, ...object[key]]);
190
- };
191
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZGIvZGIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUN0QyxPQUFPLElBQWMsTUFBTSxNQUFNLENBQUM7QUFDbEMsT0FBTyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDckMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLEtBQUssQ0FBQztBQVdwQyxNQUFNLFVBQVUsR0FBRyxhQUFhLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNsRCxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7QUFFdEMsTUFBTSxDQUFOLElBQVksZUFJWDtBQUpELFdBQVksZUFBZTtJQUN6QixvQ0FBaUIsQ0FBQTtJQUNqQix3Q0FBcUIsQ0FBQTtJQUNyQixrQ0FBZSxDQUFBO0FBQ2pCLENBQUMsRUFKVyxlQUFlLEtBQWYsZUFBZSxRQUkxQjtBQUVELE1BQU0sNEJBQTRCLEdBQUcseUNBQXlDLENBQUM7QUFFL0UsTUFBTSxRQUFRLEdBQUc7SUFDZixDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsRUFBRSxnQkFBZ0I7SUFDMUMsQ0FBQyxlQUFlLENBQUMsUUFBUSxDQUFDLEVBQUUsSUFBSTtJQUNoQyxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsRUFBRSxPQUFPO0NBQ2pDLENBQUM7QUFFRixNQUFNLFFBQVEsR0FBYTtJQUN6QixNQUFNLEVBQUUsZUFBZSxDQUFDLE1BQU07SUFDOUIsUUFBUSxFQUFFLG1CQUFtQjtJQUM3QixZQUFZLEVBQUUsSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsd0JBQXdCLENBQUM7SUFDN0QsT0FBTyxFQUFFLEtBQUs7Q0FDZixDQUFDO0FBRUYsSUFBSSxPQUFPLEdBQVMsU0FBUyxDQUFDO0FBQzlCLElBQUks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Q0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqRSxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjb25maWdEb3RlbnYgfSBmcm9tIFwiZG90ZW52XCI7XHJcbmltcG9ydCBrbmV4LCB7IEtuZXggfSBmcm9tIFwia25leFwiO1xyXG5pbXBvcnQgeyBkaXJuYW1lLCBqb2luIH0gZnJvbSBcInBhdGhcIjtcclxuaW1wb3J0IHsgZmlsZVVSTFRvUGF0aCB9IGZyb20gXCJ1cmxcIjtcclxuXHJcbmludGVyZmFjZSBEYkNvbmZpZyB7XHJcbiAgZGJUeXBlOiBTdXBwb3J0ZWREYlR5cGU7XHJcbiAgcGdDb25uZWN0aW9uU3RyaW5nPzogc3RyaW5nO1xyXG4gIG15c3FsQ29ubmVjdGlvblN0cmluZz86IHN0cmluZztcclxuICBpbml0RmlsZVBhdGg6IHN0cmluZztcclxuICBmaWxlUGF0aD86IHN0cmluZztcclxuICB2ZXJib3NlOiBib29sZWFuO1xyXG59XHJcblxyXG5jb25zdCBfX2ZpbGVuYW1lID0gZmlsZVVSTFRvUGF0aChpbXBvcnQubWV0YS51cmwpO1xyXG5jb25zdCBfX2Rpcm5hbWUgPSBkaXJuYW1lKF9fZmlsZW5hbWUpO1xyXG5cclxuZXhwb3J0IGVudW0gU3VwcG9ydGVkRGJUeXBlIHtcclxuICBzcWxpdGUgPSBcInNxbGl0ZVwiLFxyXG4gIHBvc3RncmVzID0gXCJwb3N0Z3Jlc1wiLFxyXG4gIG15c3FsID0gXCJteXNxbFwiLFxyXG59XHJcblxyXG5jb25zdCBteXNxbENvbm5lY3Rpb25TdHJpbmdQYXR0ZXJuID0gL14oW146XSspOihcXGQrKTooW146XSspOihbXjpdKyk6KFteOl0rKSQvO1xyXG5cclxuY29uc3QgRGJDbGllbnQgPSB7XHJcbiAgW1N1cHBvcnRlZERiVHlwZS5zcWxpdGVdOiBcImJldHRlci1zcWxpdGUzXCIsXHJcbiAgW1N1cHBvcnRlZERiVHlwZS5wb3N0Z3Jlc106IFwicGdcIixcclxuICBbU3VwcG9ydGVkRGJUeXBlLm15c3FsXTogXCJteXNxbFwiLFxyXG59O1xyXG5cclxuY29uc3QgZGVmYXVsdHM6IERiQ29uZmlnID0ge1xyXG4gIGRiVHlwZTogU3VwcG9ydGVkRGJUeXBlLnNxbGl0ZSxcclxuICBmaWxlUGF0aDogXCJhZGRyZXNzX3BvaW50cy5kYlwiLFxyXG4gIGluaXRGaWxlUGF0aDogam9pbihfX2Rpcm5hbWUsIFwiLi5cIiwgXCJhZGRyZXNzX3BvaW50c19pbml0LmRiXCIpLFxyXG4gIHZlcmJvc2U6IGZhbHNlLFxyXG59O1xyXG5cclxubGV0IF9rbmV4RGI6IEtuZXggPSB1bmRlZmluZWQ7XHJcbmxldCBfa25leERiQ29uZmlnOiBEYkNvbmZpZyA9IHVuZGVmaW5lZDtcclxuXHJcbmV4cG9ydCBjb25zdCBnZXRLbmV4RGIgPSAoY29uZmlnOiBQYXJ0aWFsPERiQ29uZmlnPiA9IHt9KTogS25leCA9PiB7XHJcbiAgaWYgKF9rbmV4RGIgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgX2tuZXhEYkNvbmZpZyA9IHsgLi4uZGVmYXVsdHMsIC4uLmdldEVudkNvbmZpZygpLCAuLi5jb25maWcgfTtcclxuXHJcbiAgICBpZiAoX2tuZXhEYkNvbmZpZy5kYlR5cGUgPT09IFN1cHBvcnRlZERiVHlwZS5zcWxpdGUpIHtcclxuICAgICAgX2tuZXhEYiA9IGtuZXgoe1xyXG4gICAgICAgIGNsaWVudDogRGJDbGllbnRbU3VwcG9ydGVkRGJUeXBlLnNxbGl0ZV0sXHJcbiAgICAgICAgY29ubmVjdGlvbjoge1xyXG4gICAgICAgICAgZmlsZW5hbWU6IF9rbmV4RGJDb25maWcuZmlsZVBhdGgsXHJcbiAgICAgICAgfSxcclxuICAgICAgICBwb29sOiB7XHJcbiAgICAgICAgICBhZnRlckNyZWF0ZTogKGRiOiBhbnksIGRvbmU6IEZ1bmN0aW9uKSA9PiB7XHJcbiAgICAgICAgICAgIGRiLnByYWdtYShcImpvdXJuYWxfbW9kZSA9IFdBTDtcIik7XHJcbiAgICAgICAgICAgIGRvbmUoZmFsc2UsIGRvbmUpO1xyXG4gICAgICAgICAgfSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHVzZU51bGxBc0RlZmF1bHQ6IHRydWUsXHJcbiAgICAgICAgZGVidWc6IF9rbmV4RGJDb25maWcudmVyYm9zZSxcclxuICAgICAgfSk7XHJcbiAgICB9IGVsc2UgaWYgKF9rbmV4RGJDb25maWcuZGJUeXBlID09PSBTdXBwb3J0ZWREYlR5cGUucG9zdGdyZXMpIHtcclxuICAgICAgX2tuZXhEYiA9IGtuZXgoe1xyXG4gICAgICAgIGNsaWVudDogRGJDbGllbnRbU3VwcG9ydGVkRGJUeXBlLnBvc3RncmVzXSxcclxuICAgICAgICBjb25uZWN0aW9uOiBfa25leERiQ29uZmlnLnBnQ29ubmVjdGlvblN0cmluZyxcclxuICAgICAgICB1c2VOdWxsQXNEZWZhdWx0OiB0cnVlLFxyXG4gICAgICAgIGRlYnVnOiBfa25leERiQ29uZmlnLnZlcmJvc2UsXHJcbiAgICAgIH0pO1xyXG4gICAgfSBlbHNlIGlmIChfa25leERiQ29uZmlnLmRiVHlwZSA9PT0gU3VwcG9ydGVkRGJUeXBlLm15c3FsKSB7XHJcbiAgICAgIGNvbnN0IFtob3N0LCBwb3J0LCB1c2VyLCBwYXNzd29yZCwgZGF0YWJhc2VdID1cclxuICAgICAgICBfa25leERiQ29uZmlnLm15c3FsQ29ubmVjdGlvblN0cmluZy5zcGxpdChcIjpcIik7XHJcbiAgICAgIF9rbmV4RGIgPSBrbmV4KHtcclxuICAgICAgICBjbGllbnQ6IERiQ2xpZW50W1N1cHBvcnRlZERiVHlwZS5teXNxbF0sXHJcbiAgICAgICAgY29ubmVjdGlvbjoge1xyXG4gICAgICAgICAgaG9zdCxcclxuICAgICAgICAgIHBvcnQ6IE51bWJlcihwb3J0KSxcclxuICAgICAgICAgIHVzZXIsXHJcbiAgICAgICAgICBwYXNzd29yZCxcclxuICAgICAgICAgIGRhdGFiYXNlLFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgdXNlTnVsbEFzRGVmYXVsdDogdHJ1ZSxcclxuICAgICAgICBkZWJ1ZzogX2tuZXhEYkNvbmZpZy52ZXJib3NlLFxyXG4gICAgICB9KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgREIgdHlwZTogJHtfa25leERiQ29uZmlnLmRiVHlwZX1gKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJldHVybiBfa25leERiO1xyXG59O1xyXG5cclxuZXhwb3J0IGNvbnN0IGlzUG9zdGdyZXMgPSAoa25leDogS25leCk6IGJvb2xlYW4gPT4ge1xyXG4gIHJldHVybiBrbmV4LmNsaWVudC5jb25maWcuY2xpZW50ID09PSBEYkNsaWVudFtTdXBwb3J0ZWREYlR5cGUucG9zdGdyZXNdO1xyXG59O1xyXG5cclxuZXhwb3J0IGNvbnN0IGlzU3FsaXRlID0gKGtuZXg6IEtuZXgpOiBib29sZWFuID0+IHtcclxuICByZXR1cm4ga25leC5jbGllbnQuY29uZmlnLmNsaWVudCA9PT0gRGJDbGllbnRbU3VwcG9ydGVkRGJUeXBlLnNxbGl0ZV07XHJcbn07XHJcblxyXG5leHBvcnQgY29uc3QgaXNNeXNxbCA9IChrbmV4OiBLbmV4KTogYm9vbGVhbiA9PiB7XHJcbiAgcmV0dXJuIGtuZXguY2xpZW50LmNvbmZpZy5jbGllbnQgPT09IERiQ2xpZW50W1N1cHBvcnRlZERiVHlwZS5teXNxbF07XHJcbn07XHJcblxyXG5jb25zdCBnZXRNaWdyYXRpb25Db25maWcgPSAoKTogS25leC5NaWdyYXRvckNvbmZpZyA9PiB7XHJcbiAgcmV0dXJuIHsgZGlyZWN0b3J5OiBqb2luKF9fZGlybmFtZSwgXCJtaWdyYXRpb25zXCIpIH07XHJcbn07XHJcblxyXG5leHBvcnQgY29uc3QgaW5pdERiID0gYXN5bmMgKGNvbmZpZzogUGFydGlhbDxEYkNvbmZpZz4gPSB7fSk6IFByb21pc2U8S25leD4gPT4ge1xyXG4gIGNvbnN0IGtuZXggPSBnZXRLbmV4RGIoY29uZmlnKTtcclxuICBhd2FpdCBrbmV4Lm1pZ3JhdGUubGF0ZXN0KGdldE1pZ3JhdGlvbkNvbmZpZygpKTtcclxuICByZXR1cm4ga25leDtcclxufTtcclxuXHJcbmV4cG9ydCBjb25zdCBjbGVhckRiID0gYXN5bmMgKFxyXG4gIGNvbmZpZzogUGFydGlhbDxEYkNvbmZpZz4gPSB7fVxyXG4pOiBQcm9taXNlPEtuZXg+ID0+IHtcclxuICBjb25zdCBrbmV4ID0gZ2V0S25leERiKGNvbmZpZyk7XHJcbiAgYXdhaXQga25leC5taWdyYXRlLnJvbGxiYWNrKGdldE1pZ3JhdGlvbkNvbmZpZygpLCB0cnVlKTtcclxuICBhd2FpdCBrbmV4Lm1pZ3JhdGUubGF0ZXN0KGdldE1pZ3JhdGlvbkNvbmZpZygpKTtcclxuICByZXR1cm4ga25leDtcclxufTtcclxuXHJcbmV4cG9ydCBjb25zdCBkaXNjb25uZWN0S25leCA9IGFzeW5jICgpOiBQcm9taXNlPHZvaWQ+ID0+IHtcclxuICBpZiAoX2tuZXhEYikge1xyXG4gICAgYXdhaXQgX2tuZXhEYi5kZXN0cm95KCk7XHJcbiAgICBfa25leERiID0gdW5kZWZpbmVkO1xyXG4gIH1cclxufTtcclxuXHJcbmNvbnN0IGdldEVudkNvbmZpZyA9ICgpOiBQYXJ0aWFsPERiQ29uZmlnPiA9PiB7XHJcbiAgY29uZmlnRG90ZW52KHsgcGF0aDogXCIuZW52LmxvY2FsXCIgfSk7XHJcbiAgY29uc3QgZW52Q29uZmlnOiBQYXJ0aWFsPERiQ29uZmlnPiA9IHt9O1xyXG4gIGlmIChcclxuICAgIHByb2Nlc3MuZW52LlRFWFRUT01BUF9EQl9UWVBFICYmXHJcbiAgICBPYmplY3QudmFsdWVzKFN1cHBvcnRlZERiVHlwZSkuaW5jbHVkZXMoXHJcbiAgICAgIHByb2Nlc3MuZW52LlRFWFRUT01BUF9EQl9UWVBFIGFzIFN1cHBvcnRlZERiVHlwZVxyXG4gICAgKVxyXG4gICkge1xyXG4gICAgZW52Q29uZmlnLmRiVHlwZSA9IHByb2Nlc3MuZW52LlRFWFRUT01BUF9EQl9UWVBFIGFzIFN1cHBvcnRlZERiVHlwZTtcclxuICAgIGlmIChlbnZDb25maWcuZGJUeXBlID09PSBTdXBwb3J0ZWREYlR5cGUucG9zdGdyZXMpIHtcclxuICAgICAgaWYgKCFwcm9jZXNzLmVudi5URVhUVE9NQVBfUEdfQ09OTkVDVElPTl9TVFJJTkcpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXHJcbiAgICAgICAgICBcIkVudmlyb25tZW50YWwgdmFyaWFibGUgJ1RFWFRUT01BUF9QR19DT05ORUNUSU9OX1NUUklORycgbXVzdCBiZSBzZXQgZm9yIFBvc3RncmVTUUwuXCJcclxuICAgICAgICApO1xyXG4gICAgICB9XHJcbiAgICAgIGVudkNvbmZpZy5wZ0Nvbm5lY3Rpb25TdHJpbmcgPSBwcm9jZXNzLmVudi5URVhUVE9NQVBfUEdfQ09OTkVDVElPTl9TVFJJTkc7XHJcbiAgICB9IGVsc2UgaWYgKGVudkNvbmZpZy5kYlR5cGUgPT09IFN1cHBvcnRlZERiVHlwZS5teXNxbCkge1xyXG4gICAgICBpZiAoIXByb2Nlc3MuZW52LlRFWFRUT01BUF9NWVNRTF9DT05ORUNUSU9OX0RBVEEpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXHJcbiAgICAgICAgICBcIkVudmlyb25tZW50YWwgdmFyaWFibGUgJ1RFWFRUT01BUF9NWVNRTF9DT05ORUNUSU9OX0RBVEEnIG11c3QgYmUgc2V0IGZvciBNeVNRTCBvciBNYXJpYURCLlwiXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKFxyXG4gICAgICAgICFteXNxbENvbm5lY3Rpb25TdHJpbmdQYXR0ZXJuLnRlc3QoXHJcbiAgICAgICAgICBwcm9jZXNzLmVudi5URVhUVE9NQVBfTVlTUUxfQ09OTkVDVElPTl9EQVRBXHJcbiAgICAgICAgKVxyXG4gICAgICApIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXHJcbiAgICAgICAgICBcIkVudmlyb25tZW50YWwgdmFyaWFibGUgJ1RFWFRUT01BUF9NWVNRTF9DT05ORUNUSU9OX0RBVEEnIG11c3QgYmUgaW4gZm9ybWF0ICdob3N0OnBvcnQ6dXNlcjpwYXNzd29yZDpkYXRhYmFzZScuXCJcclxuICAgICAgICApO1xyXG4gICAgICB9XHJcbiAgICAgIGVudkNvbmZpZy5teXNxbENvbm5lY3Rpb25TdHJpbmcgPVxyXG4gICAgICAgIHByb2Nlc3MuZW52LlRFWFRUT01BUF9NWVNRTF9DT05ORUNUSU9OX0RBVEE7XHJcbiAgICB9IGVsc2UgaWYgKGVudkNvbmZpZy5kYlR5cGUgPT09IFN1cHBvcnRlZERiVHlwZS5zcWxpdGUpIHtcclxuICAgICAgaWYgKHByb2Nlc3MuZW52LlRFWFRUT01BUF9TUUxJVEVfUEFUSCkge1xyXG4gICAgICAgIGVudkNvbmZpZy5maWxlUGF0aCA9IHByb2Nlc3MuZW52LlRFWFRUT01BUF9TUUxJVEVfUEFUSDtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuICByZXR1cm4gZW52Q29uZmlnO1xyXG59O1xyXG5cclxuZXhwb3J0IGNvbnN0IG5vbkVtcHR5T3JOdWxsID0gKHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcgfCBudWxsID0+IHtcclxuICByZXR1cm4gdmFsdWUgPyB2YWx1ZSA6IG51bGw7XHJcbn07XHJcblxyXG5leHBvcnQgY29uc3QgcmF3UXVlcnkgPSBhc3luYyAoXHJcbiAgcXVlcnk6IHN0cmluZyxcclxuICAuLi5iaW5kaW5nczogcmVhZG9ubHkgS25leC5SYXdCaW5kaW5nW11cclxuKTogUHJvbWlzZTxhbnlbXT4gPT4ge1xyXG4gIGNvbnN0IGtuZXggPSBnZXRLbmV4RGIoKTtcclxuICBjb25zdCByZXN1bHQgPSBhd2FpdCBrbmV4LnJhdyhxdWVyeSwgLi4uYmluZGluZ3MpO1xyXG4gIHJldHVybiBpc015c3FsKGtuZXgpID8gcmVzdWx0WzBdIDogcmVzdWx0O1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIEVmZmljaWVudGx5IGluc2VydCBtdWx0aXBsZSByb3dzLiBJZiBwcmV2ZW50RHVwbGljYXRlc0J5Rmlyc3RDb2x1bW4gaXMgdHJ1ZSwgdGhlIGZpcnN0XHJcbiAqIGNvbHVtbiBzaG91bGQgYmUgdW5pcXVlIChQSyBvciBVTklRVUUpLlxyXG4gKi9cclxuZXhwb3J0IGNvbnN0IGluc2VydE11bHRpcGxlUm93cyA9IGFzeW5jIChcclxuICByb3dzOiBzdHJpbmdbXVtdLFxyXG4gIHRhYmxlOiBzdHJpbmcsXHJcbiAgY29sdW1uTmFtZXM6IHN0cmluZ1tdLFxyXG4gIHByZXZlbnREdXBsaWNhdGVzOiBib29sZWFuID0gdHJ1ZVxyXG4pOiBQcm9taXNlPG51bWJlcj4gPT4ge1xyXG4gIGlmIChyb3dzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgcmV0dXJuIDA7XHJcbiAgfVxyXG5cclxuICBjb25zdCBpbnNlcnRQbGFjZWhvbGRlcnMgPSBnZW5lcmF0ZTJEUGxhY2Vob2xkZXJzKFxyXG4gICAgY29sdW1uTmFtZXMubGVuZ3RoLFxyXG4gICAgcm93cy5sZW5ndGhcclxuICApO1xyXG5cclxuICBjb25zdCBrbmV4ID0gZ2V0S25leERiKCk7XHJcblxyXG4gIGNvbnN0IG9uQ29uZmljdCA9XHJcbiAgICBwcmV2ZW50RHVwbGljYXRlcyAmJiAhaXNNeXNxbChrbmV4KSA/IGBPTiBDT05GTElDVCBETyBOT1RISU5HYCA6IFwiXCI7XHJcblxyXG4gIGF3YWl0IHJhd1F1ZXJ5KFxyXG4gICAgYElOU0VSVCAke2lzTXlzcWwoa25leCkgPyBcIklHTk9SRVwiIDogXCJcIn0gSU5UTyAke3RhYmxlfSAoJHtjb2x1bW5OYW1lcy5qb2luKFxyXG4gICAgICBcIixcIlxyXG4gICAgKX0pIFZBTFVFUyAke2luc2VydFBsYWNlaG9sZGVyc30gJHtvbkNvbmZpY3R9YCxcclxuICAgIHJvd3MuZmxhdCgpXHJcbiAgKTtcclxuXHJcbiAgcmV0dXJuIHJvd3MubGVuZ3RoO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIEluc2VydCBhIHNpbmdsZSByb3cgYW5kIHJldHVybiB0aGUgYXV0b2luY3JlbWVudGVkIElELlxyXG4gKi9cclxuZXhwb3J0IGNvbnN0IGluc2VydEF1dG9pbmNyZW1lbnRSb3cgPSBhc3luYyAoXHJcbiAgcm93OiBhbnlbXSxcclxuICB0YWJsZTogc3RyaW5nLFxyXG4gIGNvbHVtbk5hbWVzOiBzdHJpbmdbXVxyXG4pOiBQcm9taXNlPG51bWJlciB8IG51bGw+ID0+IHtcclxuICBjb25zdCBkYXRhID0gY29sdW1uTmFtZXMucmVkdWNlKChvYmosIGNvbHVtbk5hbWUsIGluZGV4KSA9PiB7XHJcbiAgICBvYmpbY29sdW1uTmFtZV0gPSByb3dbaW5kZXhdO1xyXG4gICAgcmV0dXJuIG9iajtcclxuICB9LCB7fSk7XHJcblxyXG4gIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGdldEtuZXhEYigpLmluc2VydChkYXRhKS5pbnRvKHRhYmxlKTtcclxuXHJcbiAgcmV0dXJuIHJlc3VsdCA/IE51bWJlcihyZXN1bHQpIDogbnVsbDtcclxufTtcclxuXHJcbmV4cG9ydCBjb25zdCBkZWxldGVNdWx0aXBsZVJvd3NLbmV4ID0gYXN5bmMgKFxyXG4gIGtleXM6IHN0cmluZ1tdLFxyXG4gIHRhYmxlOiBzdHJpbmcsXHJcbiAga2V5Q29sdW1uTmFtZTogc3RyaW5nXHJcbik6IFByb21pc2U8dm9pZD4gPT4ge1xyXG4gIGlmIChrZXlzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuICBhd2FpdCBnZXRLbmV4RGIoKS5mcm9tKHRhYmxlKS53aGVyZUluKGtleUNvbHVtbk5hbWUsIGtleXMpLmRlbCgpO1xyXG59O1xyXG5cclxuY29uc3QgZ2VuZXJhdGVSZXBldGl0aXZlU3RyaW5nID0gKFxyXG4gIHZhbHVlOiBzdHJpbmcsXHJcbiAgZ2x1ZTogc3RyaW5nLFxyXG4gIG46IG51bWJlclxyXG4pOiBzdHJpbmcgPT4ge1xyXG4gIHJldHVybiBuZXcgQXJyYXkobikuZmlsbCh2YWx1ZSkuam9pbihnbHVlKTtcclxufTtcclxuXHJcbmV4cG9ydCBjb25zdCBnZW5lcmF0ZVBsYWNlaG9sZGVycyA9IChuOiBudW1iZXIpOiBzdHJpbmcgPT4ge1xyXG4gIHJldHVybiBnZW5lcmF0ZVJlcGV0aXRpdmVTdHJpbmcoXCI/XCIsIFwiLFwiLCBuKTtcclxufTtcclxuXHJcbmV4cG9ydCBjb25zdCBnZW5lcmF0ZTJEUGxhY2Vob2xkZXJzID0gKFxyXG4gIGlubmVyOiBudW1iZXIsXHJcbiAgb3V0ZXI6IG51bWJlclxyXG4pOiBzdHJpbmcgPT4ge1xyXG4gIHJldHVybiBnZW5lcmF0ZVJlcGV0aXRpdmVTdHJpbmcoXHJcbiAgICBgKCR7Z2VuZXJhdGVQbGFjZWhvbGRlcnMoaW5uZXIpfSlgLFxyXG4gICAgXCIsXCIsXHJcbiAgICBvdXRlclxyXG4gICk7XHJcbn07XHJcblxyXG5leHBvcnQgY29uc3QgZXh0cmFjdEtleVZhbHVlc1BhaXJzID0gKFxyXG4gIGFycmF5OiBzdHJpbmdbXVtdLFxyXG4gIGtleUluZGV4OiBudW1iZXIsXHJcbiAgdmFsdWVzSW5kaWNlczogbnVtYmVyW11cclxuKTogc3RyaW5nW11bXSA9PiB7XHJcbiAgY29uc3Qgb2JqZWN0ID0gYXJyYXkucmVkdWNlKChhY2M6IG9iamVjdCwgZGF0YTogc3RyaW5nW10pID0+IHtcclxuICAgIGlmIChkYXRhW2tleUluZGV4XSkge1xyXG4gICAgICBhY2NbZGF0YVtrZXlJbmRleF1dID0gdmFsdWVzSW5kaWNlcy5tYXAoKGluZGV4OiBudW1iZXIpID0+XHJcbiAgICAgICAgbm9uRW1wdHlPck51bGwoZGF0YVtpbmRleF0pXHJcbiAgICAgICk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gYWNjO1xyXG4gIH0sIHt9KTtcclxuXHJcbiAgcmV0dXJuIE9iamVjdC5rZXlzKG9iamVjdCkubWFwKChrZXkpID0+IFtrZXksIC4uLm9iamVjdFtrZXldXSk7XHJcbn07XHJcbiJdfQ==
1
+ import { configDotenv } from "dotenv";
2
+ import knex from "knex";
3
+ import { dirname, join } from "path";
4
+ import { fileURLToPath } from "url";
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = dirname(__filename);
7
+ export var SupportedDbType;
8
+ (function (SupportedDbType) {
9
+ SupportedDbType["sqlite"] = "sqlite";
10
+ SupportedDbType["postgres"] = "postgres";
11
+ SupportedDbType["mysql"] = "mysql";
12
+ })(SupportedDbType || (SupportedDbType = {}));
13
+ const mysqlConnectionStringPattern = /^([^:]+):(\d+):([^:]+):([^:]+):([^:]+)$/;
14
+ const DbClient = {
15
+ [SupportedDbType.sqlite]: "better-sqlite3",
16
+ [SupportedDbType.postgres]: "pg",
17
+ [SupportedDbType.mysql]: "mysql",
18
+ };
19
+ const defaults = {
20
+ dbType: SupportedDbType.sqlite,
21
+ filePath: "address_points.db",
22
+ initFilePath: join(__dirname, "..", "address_points_init.db"),
23
+ verbose: false,
24
+ };
25
+ let _knexDb = undefined;
26
+ let _knexDbConfig = undefined;
27
+ export const getKnexDb = (config = {}) => {
28
+ if (_knexDb === undefined) {
29
+ _knexDbConfig = { ...defaults, ...getEnvConfig(), ...config };
30
+ if (_knexDbConfig.dbType === SupportedDbType.sqlite) {
31
+ _knexDb = knex({
32
+ client: DbClient[SupportedDbType.sqlite],
33
+ connection: {
34
+ filename: _knexDbConfig.filePath,
35
+ },
36
+ pool: {
37
+ afterCreate: (db, done) => {
38
+ db.pragma("journal_mode = WAL;");
39
+ done(false, done);
40
+ },
41
+ },
42
+ useNullAsDefault: true,
43
+ debug: _knexDbConfig.verbose,
44
+ });
45
+ }
46
+ else if (_knexDbConfig.dbType === SupportedDbType.postgres) {
47
+ _knexDb = knex({
48
+ client: DbClient[SupportedDbType.postgres],
49
+ connection: _knexDbConfig.pgConnectionString,
50
+ useNullAsDefault: true,
51
+ debug: _knexDbConfig.verbose,
52
+ });
53
+ }
54
+ else if (_knexDbConfig.dbType === SupportedDbType.mysql) {
55
+ const [host, port, user, password, database] = _knexDbConfig.mysqlConnectionString.split(":");
56
+ _knexDb = knex({
57
+ client: DbClient[SupportedDbType.mysql],
58
+ connection: {
59
+ host,
60
+ port: Number(port),
61
+ user,
62
+ password,
63
+ database,
64
+ },
65
+ useNullAsDefault: true,
66
+ debug: _knexDbConfig.verbose,
67
+ });
68
+ }
69
+ else {
70
+ throw new Error(`Unsupported DB type: ${_knexDbConfig.dbType}`);
71
+ }
72
+ }
73
+ return _knexDb;
74
+ };
75
+ export const isPostgres = (knex) => {
76
+ return knex.client.config.client === DbClient[SupportedDbType.postgres];
77
+ };
78
+ export const isSqlite = (knex) => {
79
+ return knex.client.config.client === DbClient[SupportedDbType.sqlite];
80
+ };
81
+ export const isMysql = (knex) => {
82
+ return knex.client.config.client === DbClient[SupportedDbType.mysql];
83
+ };
84
+ const getMigrationConfig = () => {
85
+ return { directory: join(__dirname, "migrations") };
86
+ };
87
+ export const initDb = async (config = {}) => {
88
+ const knex = getKnexDb(config);
89
+ await knex.migrate.latest(getMigrationConfig());
90
+ return knex;
91
+ };
92
+ export const clearDb = async (config = {}) => {
93
+ const knex = getKnexDb(config);
94
+ await knex.migrate.rollback(getMigrationConfig(), true);
95
+ await knex.migrate.latest(getMigrationConfig());
96
+ return knex;
97
+ };
98
+ export const disconnectKnex = async () => {
99
+ if (_knexDb) {
100
+ await _knexDb.destroy();
101
+ _knexDb = undefined;
102
+ }
103
+ };
104
+ const getEnvConfig = () => {
105
+ configDotenv({ path: ".env.local" });
106
+ const envConfig = {};
107
+ if (process.env.TEXTTOMAP_DB_TYPE &&
108
+ Object.values(SupportedDbType).includes(process.env.TEXTTOMAP_DB_TYPE)) {
109
+ envConfig.dbType = process.env.TEXTTOMAP_DB_TYPE;
110
+ if (envConfig.dbType === SupportedDbType.postgres) {
111
+ if (!process.env.TEXTTOMAP_PG_CONNECTION_STRING) {
112
+ throw new Error("Environmental variable 'TEXTTOMAP_PG_CONNECTION_STRING' must be set for PostgreSQL.");
113
+ }
114
+ envConfig.pgConnectionString = process.env.TEXTTOMAP_PG_CONNECTION_STRING;
115
+ }
116
+ else if (envConfig.dbType === SupportedDbType.mysql) {
117
+ if (!process.env.TEXTTOMAP_MYSQL_CONNECTION_DATA) {
118
+ throw new Error("Environmental variable 'TEXTTOMAP_MYSQL_CONNECTION_DATA' must be set for MySQL or MariaDB.");
119
+ }
120
+ if (!mysqlConnectionStringPattern.test(process.env.TEXTTOMAP_MYSQL_CONNECTION_DATA)) {
121
+ throw new Error("Environmental variable 'TEXTTOMAP_MYSQL_CONNECTION_DATA' must be in format 'host:port:user:password:database'.");
122
+ }
123
+ envConfig.mysqlConnectionString =
124
+ process.env.TEXTTOMAP_MYSQL_CONNECTION_DATA;
125
+ }
126
+ else if (envConfig.dbType === SupportedDbType.sqlite) {
127
+ if (process.env.TEXTTOMAP_SQLITE_PATH) {
128
+ envConfig.filePath = process.env.TEXTTOMAP_SQLITE_PATH;
129
+ }
130
+ }
131
+ }
132
+ return envConfig;
133
+ };
134
+ export const nonEmptyOrNull = (value) => {
135
+ return value ? value : null;
136
+ };
137
+ export const rawQuery = async (query, ...bindings) => {
138
+ const knex = getKnexDb();
139
+ const result = await knex.raw(query, ...bindings);
140
+ return isMysql(knex) ? result[0] : result;
141
+ };
142
+ /**
143
+ * Efficiently insert multiple rows. If preventDuplicatesByFirstColumn is true, the first
144
+ * column should be unique (PK or UNIQUE).
145
+ */
146
+ /**
147
+ * Insert multiple rows. Existing rows (same primary key) are kept as they are,
148
+ * unless `upsert` is set - then their `upsert.updateColumns` are overwritten
149
+ * (e.g. a street renamed in RÚIAN keeps its code, only the name changes).
150
+ */
151
+ export const insertMultipleRows = async (rows, table, columnNames, preventDuplicates = true, upsert) => {
152
+ if (rows.length === 0) {
153
+ return 0;
154
+ }
155
+ const insertPlaceholders = generate2DPlaceholders(columnNames.length, rows.length);
156
+ const knex = getKnexDb();
157
+ let onConfict = "";
158
+ if (upsert && isMysql(knex)) {
159
+ onConfict = `ON DUPLICATE KEY UPDATE ${upsert.updateColumns
160
+ .map((c) => `${c} = VALUES(${c})`)
161
+ .join(", ")}`;
162
+ }
163
+ else if (upsert) {
164
+ // the WHERE clause skips rewriting rows that haven't changed
165
+ onConfict = `ON CONFLICT (${upsert.conflictColumns.join(",")}) DO UPDATE SET ${upsert.updateColumns
166
+ .map((c) => `${c} = excluded.${c}`)
167
+ .join(", ")} WHERE ${upsert.updateColumns
168
+ .map((c) => `${table}.${c} IS DISTINCT FROM excluded.${c}`)
169
+ .join(" OR ")}`;
170
+ }
171
+ else if (preventDuplicates && !isMysql(knex)) {
172
+ onConfict = `ON CONFLICT DO NOTHING`;
173
+ }
174
+ await rawQuery(`INSERT ${isMysql(knex) ? "IGNORE" : ""} INTO ${table} (${columnNames.join(",")}) VALUES ${insertPlaceholders} ${onConfict}`, rows.flat());
175
+ return rows.length;
176
+ };
177
+ /**
178
+ * Insert a single row and return the autoincremented ID.
179
+ */
180
+ export const insertAutoincrementRow = async (row, table, columnNames) => {
181
+ const data = columnNames.reduce((obj, columnName, index) => {
182
+ obj[columnName] = row[index];
183
+ return obj;
184
+ }, {});
185
+ const result = await getKnexDb().insert(data).into(table);
186
+ return result ? Number(result) : null;
187
+ };
188
+ export const deleteMultipleRowsKnex = async (keys, table, keyColumnName) => {
189
+ if (keys.length === 0) {
190
+ return;
191
+ }
192
+ await getKnexDb().from(table).whereIn(keyColumnName, keys).del();
193
+ };
194
+ const generateRepetitiveString = (value, glue, n) => {
195
+ return new Array(n).fill(value).join(glue);
196
+ };
197
+ export const generatePlaceholders = (n) => {
198
+ return generateRepetitiveString("?", ",", n);
199
+ };
200
+ export const generate2DPlaceholders = (inner, outer) => {
201
+ return generateRepetitiveString(`(${generatePlaceholders(inner)})`, ",", outer);
202
+ };
203
+ export const extractKeyValuesPairs = (array, keyIndex, valuesIndices) => {
204
+ const object = array.reduce((acc, data) => {
205
+ if (data[keyIndex]) {
206
+ acc[data[keyIndex]] = valuesIndices.map((index) => nonEmptyOrNull(data[index]));
207
+ }
208
+ return acc;
209
+ }, {});
210
+ return Object.keys(object).map((key) => [key, ...object[key]]);
211
+ };
212
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZGIvZGIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUN0QyxPQUFPLElBQWMsTUFBTSxNQUFNLENBQUM7QUFDbEMsT0FBTyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDckMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLEtBQUssQ0FBQztBQVdwQyxNQUFNLFVBQVUsR0FBRyxhQUFhLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNsRCxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7QUFFdEMsTUFBTSxDQUFOLElBQVksZUFJWDtBQUpELFdBQVksZUFBZTtJQUN6QixvQ0FBaUIsQ0FBQTtJQUNqQix3Q0FBcUIsQ0FBQTtJQUNyQixrQ0FBZSxDQUFBO0FBQ2pCLENBQUMsRUFKVyxlQUFlLEtBQWYsZUFBZSxRQUkxQjtBQUVELE1BQU0sNEJBQTRCLEdBQUcseUNBQXlDLENBQUM7QUFFL0UsTUFBTSxRQUFRLEdBQUc7SUFDZixDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsRUFBRSxnQkFBZ0I7SUFDMUMsQ0FBQyxlQUFlLENBQUMsUUFBUSxDQUFDLEVBQUUsSUFBSTtJQUNoQyxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsRUFBRSxPQUFPO0NBQ2pDLENBQUM7QUFFRixNQUFNLFFBQVEsR0FBYTtJQUN6QixNQUFNLEVBQUUsZUFBZSxDQUFDLE1BQU07SUFDOUIsUUFBUSxFQUFFLG1CQUFtQjtJQUM3QixZQUFZLEVBQUUsSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsd0JBQXdCLENBQUM7SUFDN0QsT0FBTyxFQUFFLEtBQUs7Q0FDZixDQUFDO0FBRUYsSUFBSSxPQUFPLEdBQVMsU0FBUyxDQUFDO0FBQzlCLElBQUks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RUYsTUFBTSxDQUFDLE1BQU0sc0JBQXNCLEdBQUcsQ0FDcEMsS0FBYSxFQUNiLEtBQWEsRUFDTCxFQUFFO0lBQ1YsT0FBTyx3QkFBd0IsQ0FDN0IsSUFBSSxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUNsQyxHQUFHLEVBQ0gsS0FBSyxDQUNOLENBQUM7QUFDSixDQUFDLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRyxDQUNuQyxLQUFpQixFQUNqQixRQUFnQixFQUNoQixhQUF1QixFQUNYLEVBQUU7SUFDZCxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBVyxFQUFFLElBQWMsRUFBRSxFQUFFO1FBQzFELElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFO1lBQ2xCLEdBQUcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsR0FBRyxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBYSxFQUFFLEVBQUUsQ0FDeEQsY0FBYyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUM1QixDQUFDO1NBQ0g7UUFDRCxPQUFPLEdBQUcsQ0FBQztJQUNiLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUVQLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqRSxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjb25maWdEb3RlbnYgfSBmcm9tIFwiZG90ZW52XCI7XG5pbXBvcnQga25leCwgeyBLbmV4IH0gZnJvbSBcImtuZXhcIjtcbmltcG9ydCB7IGRpcm5hbWUsIGpvaW4gfSBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHsgZmlsZVVSTFRvUGF0aCB9IGZyb20gXCJ1cmxcIjtcblxuaW50ZXJmYWNlIERiQ29uZmlnIHtcbiAgZGJUeXBlOiBTdXBwb3J0ZWREYlR5cGU7XG4gIHBnQ29ubmVjdGlvblN0cmluZz86IHN0cmluZztcbiAgbXlzcWxDb25uZWN0aW9uU3RyaW5nPzogc3RyaW5nO1xuICBpbml0RmlsZVBhdGg6IHN0cmluZztcbiAgZmlsZVBhdGg/OiBzdHJpbmc7XG4gIHZlcmJvc2U6IGJvb2xlYW47XG59XG5cbmNvbnN0IF9fZmlsZW5hbWUgPSBmaWxlVVJMVG9QYXRoKGltcG9ydC5tZXRhLnVybCk7XG5jb25zdCBfX2Rpcm5hbWUgPSBkaXJuYW1lKF9fZmlsZW5hbWUpO1xuXG5leHBvcnQgZW51bSBTdXBwb3J0ZWREYlR5cGUge1xuICBzcWxpdGUgPSBcInNxbGl0ZVwiLFxuICBwb3N0Z3JlcyA9IFwicG9zdGdyZXNcIixcbiAgbXlzcWwgPSBcIm15c3FsXCIsXG59XG5cbmNvbnN0IG15c3FsQ29ubmVjdGlvblN0cmluZ1BhdHRlcm4gPSAvXihbXjpdKyk6KFxcZCspOihbXjpdKyk6KFteOl0rKTooW146XSspJC87XG5cbmNvbnN0IERiQ2xpZW50ID0ge1xuICBbU3VwcG9ydGVkRGJUeXBlLnNxbGl0ZV06IFwiYmV0dGVyLXNxbGl0ZTNcIixcbiAgW1N1cHBvcnRlZERiVHlwZS5wb3N0Z3Jlc106IFwicGdcIixcbiAgW1N1cHBvcnRlZERiVHlwZS5teXNxbF06IFwibXlzcWxcIixcbn07XG5cbmNvbnN0IGRlZmF1bHRzOiBEYkNvbmZpZyA9IHtcbiAgZGJUeXBlOiBTdXBwb3J0ZWREYlR5cGUuc3FsaXRlLFxuICBmaWxlUGF0aDogXCJhZGRyZXNzX3BvaW50cy5kYlwiLFxuICBpbml0RmlsZVBhdGg6IGpvaW4oX19kaXJuYW1lLCBcIi4uXCIsIFwiYWRkcmVzc19wb2ludHNfaW5pdC5kYlwiKSxcbiAgdmVyYm9zZTogZmFsc2UsXG59O1xuXG5sZXQgX2tuZXhEYjogS25leCA9IHVuZGVmaW5lZDtcbmxldCBfa25leERiQ29uZmlnOiBEYkNvbmZpZyA9IHVuZGVmaW5lZDtcblxuZXhwb3J0IGNvbnN0IGdldEtuZXhEYiA9IChjb25maWc6IFBhcnRpYWw8RGJDb25maWc+ID0ge30pOiBLbmV4ID0+IHtcbiAgaWYgKF9rbmV4RGIgPT09IHVuZGVmaW5lZCkge1xuICAgIF9rbmV4RGJDb25maWcgPSB7IC4uLmRlZmF1bHRzLCAuLi5nZXRFbnZDb25maWcoKSwgLi4uY29uZmlnIH07XG5cbiAgICBpZiAoX2tuZXhEYkNvbmZpZy5kYlR5cGUgPT09IFN1cHBvcnRlZERiVHlwZS5zcWxpdGUpIHtcbiAgICAgIF9rbmV4RGIgPSBrbmV4KHtcbiAgICAgICAgY2xpZW50OiBEYkNsaWVudFtTdXBwb3J0ZWREYlR5cGUuc3FsaXRlXSxcbiAgICAgICAgY29ubmVjdGlvbjoge1xuICAgICAgICAgIGZpbGVuYW1lOiBfa25leERiQ29uZmlnLmZpbGVQYXRoLFxuICAgICAgICB9LFxuICAgICAgICBwb29sOiB7XG4gICAgICAgICAgYWZ0ZXJDcmVhdGU6IChkYjogYW55LCBkb25lOiBGdW5jdGlvbikgPT4ge1xuICAgICAgICAgICAgZGIucHJhZ21hKFwiam91cm5hbF9tb2RlID0gV0FMO1wiKTtcbiAgICAgICAgICAgIGRvbmUoZmFsc2UsIGRvbmUpO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIHVzZU51bGxBc0RlZmF1bHQ6IHRydWUsXG4gICAgICAgIGRlYnVnOiBfa25leERiQ29uZmlnLnZlcmJvc2UsXG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKF9rbmV4RGJDb25maWcuZGJUeXBlID09PSBTdXBwb3J0ZWREYlR5cGUucG9zdGdyZXMpIHtcbiAgICAgIF9rbmV4RGIgPSBrbmV4KHtcbiAgICAgICAgY2xpZW50OiBEYkNsaWVudFtTdXBwb3J0ZWREYlR5cGUucG9zdGdyZXNdLFxuICAgICAgICBjb25uZWN0aW9uOiBfa25leERiQ29uZmlnLnBnQ29ubmVjdGlvblN0cmluZyxcbiAgICAgICAgdXNlTnVsbEFzRGVmYXVsdDogdHJ1ZSxcbiAgICAgICAgZGVidWc6IF9rbmV4RGJDb25maWcudmVyYm9zZSxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAoX2tuZXhEYkNvbmZpZy5kYlR5cGUgPT09IFN1cHBvcnRlZERiVHlwZS5teXNxbCkge1xuICAgICAgY29uc3QgW2hvc3QsIHBvcnQsIHVzZXIsIHBhc3N3b3JkLCBkYXRhYmFzZV0gPVxuICAgICAgICBfa25leERiQ29uZmlnLm15c3FsQ29ubmVjdGlvblN0cmluZy5zcGxpdChcIjpcIik7XG4gICAgICBfa25leERiID0ga25leCh7XG4gICAgICAgIGNsaWVudDogRGJDbGllbnRbU3VwcG9ydGVkRGJUeXBlLm15c3FsXSxcbiAgICAgICAgY29ubmVjdGlvbjoge1xuICAgICAgICAgIGhvc3QsXG4gICAgICAgICAgcG9ydDogTnVtYmVyKHBvcnQpLFxuICAgICAgICAgIHVzZXIsXG4gICAgICAgICAgcGFzc3dvcmQsXG4gICAgICAgICAgZGF0YWJhc2UsXG4gICAgICAgIH0sXG4gICAgICAgIHVzZU51bGxBc0RlZmF1bHQ6IHRydWUsXG4gICAgICAgIGRlYnVnOiBfa25leERiQ29uZmlnLnZlcmJvc2UsXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBEQiB0eXBlOiAke19rbmV4RGJDb25maWcuZGJUeXBlfWApO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBfa25leERiO1xufTtcblxuZXhwb3J0IGNvbnN0IGlzUG9zdGdyZXMgPSAoa25leDogS25leCk6IGJvb2xlYW4gPT4ge1xuICByZXR1cm4ga25leC5jbGllbnQuY29uZmlnLmNsaWVudCA9PT0gRGJDbGllbnRbU3VwcG9ydGVkRGJUeXBlLnBvc3RncmVzXTtcbn07XG5cbmV4cG9ydCBjb25zdCBpc1NxbGl0ZSA9IChrbmV4OiBLbmV4KTogYm9vbGVhbiA9PiB7XG4gIHJldHVybiBrbmV4LmNsaWVudC5jb25maWcuY2xpZW50ID09PSBEYkNsaWVudFtTdXBwb3J0ZWREYlR5cGUuc3FsaXRlXTtcbn07XG5cbmV4cG9ydCBjb25zdCBpc015c3FsID0gKGtuZXg6IEtuZXgpOiBib29sZWFuID0+IHtcbiAgcmV0dXJuIGtuZXguY2xpZW50LmNvbmZpZy5jbGllbnQgPT09IERiQ2xpZW50W1N1cHBvcnRlZERiVHlwZS5teXNxbF07XG59O1xuXG5jb25zdCBnZXRNaWdyYXRpb25Db25maWcgPSAoKTogS25leC5NaWdyYXRvckNvbmZpZyA9PiB7XG4gIHJldHVybiB7IGRpcmVjdG9yeTogam9pbihfX2Rpcm5hbWUsIFwibWlncmF0aW9uc1wiKSB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGluaXREYiA9IGFzeW5jIChjb25maWc6IFBhcnRpYWw8RGJDb25maWc+ID0ge30pOiBQcm9taXNlPEtuZXg+ID0+IHtcbiAgY29uc3Qga25leCA9IGdldEtuZXhEYihjb25maWcpO1xuICBhd2FpdCBrbmV4Lm1pZ3JhdGUubGF0ZXN0KGdldE1pZ3JhdGlvbkNvbmZpZygpKTtcbiAgcmV0dXJuIGtuZXg7XG59O1xuXG5leHBvcnQgY29uc3QgY2xlYXJEYiA9IGFzeW5jIChcbiAgY29uZmlnOiBQYXJ0aWFsPERiQ29uZmlnPiA9IHt9XG4pOiBQcm9taXNlPEtuZXg+ID0+IHtcbiAgY29uc3Qga25leCA9IGdldEtuZXhEYihjb25maWcpO1xuICBhd2FpdCBrbmV4Lm1pZ3JhdGUucm9sbGJhY2soZ2V0TWlncmF0aW9uQ29uZmlnKCksIHRydWUpO1xuICBhd2FpdCBrbmV4Lm1pZ3JhdGUubGF0ZXN0KGdldE1pZ3JhdGlvbkNvbmZpZygpKTtcbiAgcmV0dXJuIGtuZXg7XG59O1xuXG5leHBvcnQgY29uc3QgZGlzY29ubmVjdEtuZXggPSBhc3luYyAoKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gIGlmIChfa25leERiKSB7XG4gICAgYXdhaXQgX2tuZXhEYi5kZXN0cm95KCk7XG4gICAgX2tuZXhEYiA9IHVuZGVmaW5lZDtcbiAgfVxufTtcblxuY29uc3QgZ2V0RW52Q29uZmlnID0gKCk6IFBhcnRpYWw8RGJDb25maWc+ID0+IHtcbiAgY29uZmlnRG90ZW52KHsgcGF0aDogXCIuZW52LmxvY2FsXCIgfSk7XG4gIGNvbnN0IGVudkNvbmZpZzogUGFydGlhbDxEYkNvbmZpZz4gPSB7fTtcbiAgaWYgKFxuICAgIHByb2Nlc3MuZW52LlRFWFRUT01BUF9EQl9UWVBFICYmXG4gICAgT2JqZWN0LnZhbHVlcyhTdXBwb3J0ZWREYlR5cGUpLmluY2x1ZGVzKFxuICAgICAgcHJvY2Vzcy5lbnYuVEVYVFRPTUFQX0RCX1RZUEUgYXMgU3VwcG9ydGVkRGJUeXBlXG4gICAgKVxuICApIHtcbiAgICBlbnZDb25maWcuZGJUeXBlID0gcHJvY2Vzcy5lbnYuVEVYVFRPTUFQX0RCX1RZUEUgYXMgU3VwcG9ydGVkRGJUeXBlO1xuICAgIGlmIChlbnZDb25maWcuZGJUeXBlID09PSBTdXBwb3J0ZWREYlR5cGUucG9zdGdyZXMpIHtcbiAgICAgIGlmICghcHJvY2Vzcy5lbnYuVEVYVFRPTUFQX1BHX0NPTk5FQ1RJT05fU1RSSU5HKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBcIkVudmlyb25tZW50YWwgdmFyaWFibGUgJ1RFWFRUT01BUF9QR19DT05ORUNUSU9OX1NUUklORycgbXVzdCBiZSBzZXQgZm9yIFBvc3RncmVTUUwuXCJcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGVudkNvbmZpZy5wZ0Nvbm5lY3Rpb25TdHJpbmcgPSBwcm9jZXNzLmVudi5URVhUVE9NQVBfUEdfQ09OTkVDVElPTl9TVFJJTkc7XG4gICAgfSBlbHNlIGlmIChlbnZDb25maWcuZGJUeXBlID09PSBTdXBwb3J0ZWREYlR5cGUubXlzcWwpIHtcbiAgICAgIGlmICghcHJvY2Vzcy5lbnYuVEVYVFRPTUFQX01ZU1FMX0NPTk5FQ1RJT05fREFUQSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgXCJFbnZpcm9ubWVudGFsIHZhcmlhYmxlICdURVhUVE9NQVBfTVlTUUxfQ09OTkVDVElPTl9EQVRBJyBtdXN0IGJlIHNldCBmb3IgTXlTUUwgb3IgTWFyaWFEQi5cIlxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgICFteXNxbENvbm5lY3Rpb25TdHJpbmdQYXR0ZXJuLnRlc3QoXG4gICAgICAgICAgcHJvY2Vzcy5lbnYuVEVYVFRPTUFQX01ZU1FMX0NPTk5FQ1RJT05fREFUQVxuICAgICAgICApXG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIFwiRW52aXJvbm1lbnRhbCB2YXJpYWJsZSAnVEVYVFRPTUFQX01ZU1FMX0NPTk5FQ1RJT05fREFUQScgbXVzdCBiZSBpbiBmb3JtYXQgJ2hvc3Q6cG9ydDp1c2VyOnBhc3N3b3JkOmRhdGFiYXNlJy5cIlxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgZW52Q29uZmlnLm15c3FsQ29ubmVjdGlvblN0cmluZyA9XG4gICAgICAgIHByb2Nlc3MuZW52LlRFWFRUT01BUF9NWVNRTF9DT05ORUNUSU9OX0RBVEE7XG4gICAgfSBlbHNlIGlmIChlbnZDb25maWcuZGJUeXBlID09PSBTdXBwb3J0ZWREYlR5cGUuc3FsaXRlKSB7XG4gICAgICBpZiAocHJvY2Vzcy5lbnYuVEVYVFRPTUFQX1NRTElURV9QQVRIKSB7XG4gICAgICAgIGVudkNvbmZpZy5maWxlUGF0aCA9IHByb2Nlc3MuZW52LlRFWFRUT01BUF9TUUxJVEVfUEFUSDtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIGVudkNvbmZpZztcbn07XG5cbmV4cG9ydCBjb25zdCBub25FbXB0eU9yTnVsbCA9ICh2YWx1ZTogc3RyaW5nKTogc3RyaW5nIHwgbnVsbCA9PiB7XG4gIHJldHVybiB2YWx1ZSA/IHZhbHVlIDogbnVsbDtcbn07XG5cbmV4cG9ydCBjb25zdCByYXdRdWVyeSA9IGFzeW5jIChcbiAgcXVlcnk6IHN0cmluZyxcbiAgLi4uYmluZGluZ3M6IHJlYWRvbmx5IEtuZXguUmF3QmluZGluZ1tdXG4pOiBQcm9taXNlPGFueVtdPiA9PiB7XG4gIGNvbnN0IGtuZXggPSBnZXRLbmV4RGIoKTtcbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQga25leC5yYXcocXVlcnksIC4uLmJpbmRpbmdzKTtcbiAgcmV0dXJuIGlzTXlzcWwoa25leCkgPyByZXN1bHRbMF0gOiByZXN1bHQ7XG59O1xuXG4vKipcbiAqIEVmZmljaWVudGx5IGluc2VydCBtdWx0aXBsZSByb3dzLiBJZiBwcmV2ZW50RHVwbGljYXRlc0J5Rmlyc3RDb2x1bW4gaXMgdHJ1ZSwgdGhlIGZpcnN0XG4gKiBjb2x1bW4gc2hvdWxkIGJlIHVuaXF1ZSAoUEsgb3IgVU5JUVVFKS5cbiAqL1xuLyoqXG4gKiBJbnNlcnQgbXVsdGlwbGUgcm93cy4gRXhpc3Rpbmcgcm93cyAoc2FtZSBwcmltYXJ5IGtleSkgYXJlIGtlcHQgYXMgdGhleSBhcmUsXG4gKiB1bmxlc3MgYHVwc2VydGAgaXMgc2V0IC0gdGhlbiB0aGVpciBgdXBzZXJ0LnVwZGF0ZUNvbHVtbnNgIGFyZSBvdmVyd3JpdHRlblxuICogKGUuZy4gYSBzdHJlZXQgcmVuYW1lZCBpbiBSw5pJQU4ga2VlcHMgaXRzIGNvZGUsIG9ubHkgdGhlIG5hbWUgY2hhbmdlcykuXG4gKi9cbmV4cG9ydCBjb25zdCBpbnNlcnRNdWx0aXBsZVJvd3MgPSBhc3luYyAoXG4gIHJvd3M6IHN0cmluZ1tdW10sXG4gIHRhYmxlOiBzdHJpbmcsXG4gIGNvbHVtbk5hbWVzOiBzdHJpbmdbXSxcbiAgcHJldmVudER1cGxpY2F0ZXM6IGJvb2xlYW4gPSB0cnVlLFxuICB1cHNlcnQ/OiB7IGNvbmZsaWN0Q29sdW1uczogc3RyaW5nW107IHVwZGF0ZUNvbHVtbnM6IHN0cmluZ1tdIH1cbik6IFByb21pc2U8bnVtYmVyPiA9PiB7XG4gIGlmIChyb3dzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiAwO1xuICB9XG5cbiAgY29uc3QgaW5zZXJ0UGxhY2Vob2xkZXJzID0gZ2VuZXJhdGUyRFBsYWNlaG9sZGVycyhcbiAgICBjb2x1bW5OYW1lcy5sZW5ndGgsXG4gICAgcm93cy5sZW5ndGhcbiAgKTtcblxuICBjb25zdCBrbmV4ID0gZ2V0S25leERiKCk7XG5cbiAgbGV0IG9uQ29uZmljdCA9IFwiXCI7XG4gIGlmICh1cHNlcnQgJiYgaXNNeXNxbChrbmV4KSkge1xuICAgIG9uQ29uZmljdCA9IGBPTiBEVVBMSUNBVEUgS0VZIFVQREFURSAke3Vwc2VydC51cGRhdGVDb2x1bW5zXG4gICAgICAubWFwKChjKSA9PiBgJHtjfSA9IFZBTFVFUygke2N9KWApXG4gICAgICAuam9pbihcIiwgXCIpfWA7XG4gIH0gZWxzZSBpZiAodXBzZXJ0KSB7XG4gICAgLy8gdGhlIFdIRVJFIGNsYXVzZSBza2lwcyByZXdyaXRpbmcgcm93cyB0aGF0IGhhdmVuJ3QgY2hhbmdlZFxuICAgIG9uQ29uZmljdCA9IGBPTiBDT05GTElDVCAoJHt1cHNlcnQuY29uZmxpY3RDb2x1bW5zLmpvaW4oXG4gICAgICBcIixcIlxuICAgICl9KSBETyBVUERBVEUgU0VUICR7dXBzZXJ0LnVwZGF0ZUNvbHVtbnNcbiAgICAgIC5tYXAoKGMpID0+IGAke2N9ID0gZXhjbHVkZWQuJHtjfWApXG4gICAgICAuam9pbihcIiwgXCIpfSBXSEVSRSAke3Vwc2VydC51cGRhdGVDb2x1bW5zXG4gICAgICAubWFwKChjKSA9PiBgJHt0YWJsZX0uJHtjfSBJUyBESVNUSU5DVCBGUk9NIGV4Y2x1ZGVkLiR7Y31gKVxuICAgICAgLmpvaW4oXCIgT1IgXCIpfWA7XG4gIH0gZWxzZSBpZiAocHJldmVudER1cGxpY2F0ZXMgJiYgIWlzTXlzcWwoa25leCkpIHtcbiAgICBvbkNvbmZpY3QgPSBgT04gQ09ORkxJQ1QgRE8gTk9USElOR2A7XG4gIH1cblxuICBhd2FpdCByYXdRdWVyeShcbiAgICBgSU5TRVJUICR7aXNNeXNxbChrbmV4KSA/IFwiSUdOT1JFXCIgOiBcIlwifSBJTlRPICR7dGFibGV9ICgke2NvbHVtbk5hbWVzLmpvaW4oXG4gICAgICBcIixcIlxuICAgICl9KSBWQUxVRVMgJHtpbnNlcnRQbGFjZWhvbGRlcnN9ICR7b25Db25maWN0fWAsXG4gICAgcm93cy5mbGF0KClcbiAgKTtcblxuICByZXR1cm4gcm93cy5sZW5ndGg7XG59O1xuXG4vKipcbiAqIEluc2VydCBhIHNpbmdsZSByb3cgYW5kIHJldHVybiB0aGUgYXV0b2luY3JlbWVudGVkIElELlxuICovXG5leHBvcnQgY29uc3QgaW5zZXJ0QXV0b2luY3JlbWVudFJvdyA9IGFzeW5jIChcbiAgcm93OiBhbnlbXSxcbiAgdGFibGU6IHN0cmluZyxcbiAgY29sdW1uTmFtZXM6IHN0cmluZ1tdXG4pOiBQcm9taXNlPG51bWJlciB8IG51bGw+ID0+IHtcbiAgY29uc3QgZGF0YSA9IGNvbHVtbk5hbWVzLnJlZHVjZSgob2JqLCBjb2x1bW5OYW1lLCBpbmRleCkgPT4ge1xuICAgIG9ialtjb2x1bW5OYW1lXSA9IHJvd1tpbmRleF07XG4gICAgcmV0dXJuIG9iajtcbiAgfSwge30pO1xuXG4gIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGdldEtuZXhEYigpLmluc2VydChkYXRhKS5pbnRvKHRhYmxlKTtcblxuICByZXR1cm4gcmVzdWx0ID8gTnVtYmVyKHJlc3VsdCkgOiBudWxsO1xufTtcblxuZXhwb3J0IGNvbnN0IGRlbGV0ZU11bHRpcGxlUm93c0tuZXggPSBhc3luYyAoXG4gIGtleXM6IHN0cmluZ1tdLFxuICB0YWJsZTogc3RyaW5nLFxuICBrZXlDb2x1bW5OYW1lOiBzdHJpbmdcbik6IFByb21pc2U8dm9pZD4gPT4ge1xuICBpZiAoa2V5cy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm47XG4gIH1cbiAgYXdhaXQgZ2V0S25leERiKCkuZnJvbSh0YWJsZSkud2hlcmVJbihrZXlDb2x1bW5OYW1lLCBrZXlzKS5kZWwoKTtcbn07XG5cbmNvbnN0IGdlbmVyYXRlUmVwZXRpdGl2ZVN0cmluZyA9IChcbiAgdmFsdWU6IHN0cmluZyxcbiAgZ2x1ZTogc3RyaW5nLFxuICBuOiBudW1iZXJcbik6IHN0cmluZyA9PiB7XG4gIHJldHVybiBuZXcgQXJyYXkobikuZmlsbCh2YWx1ZSkuam9pbihnbHVlKTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZW5lcmF0ZVBsYWNlaG9sZGVycyA9IChuOiBudW1iZXIpOiBzdHJpbmcgPT4ge1xuICByZXR1cm4gZ2VuZXJhdGVSZXBldGl0aXZlU3RyaW5nKFwiP1wiLCBcIixcIiwgbik7XG59O1xuXG5leHBvcnQgY29uc3QgZ2VuZXJhdGUyRFBsYWNlaG9sZGVycyA9IChcbiAgaW5uZXI6IG51bWJlcixcbiAgb3V0ZXI6IG51bWJlclxuKTogc3RyaW5nID0+IHtcbiAgcmV0dXJuIGdlbmVyYXRlUmVwZXRpdGl2ZVN0cmluZyhcbiAgICBgKCR7Z2VuZXJhdGVQbGFjZWhvbGRlcnMoaW5uZXIpfSlgLFxuICAgIFwiLFwiLFxuICAgIG91dGVyXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3QgZXh0cmFjdEtleVZhbHVlc1BhaXJzID0gKFxuICBhcnJheTogc3RyaW5nW11bXSxcbiAga2V5SW5kZXg6IG51bWJlcixcbiAgdmFsdWVzSW5kaWNlczogbnVtYmVyW11cbik6IHN0cmluZ1tdW10gPT4ge1xuICBjb25zdCBvYmplY3QgPSBhcnJheS5yZWR1Y2UoKGFjYzogb2JqZWN0LCBkYXRhOiBzdHJpbmdbXSkgPT4ge1xuICAgIGlmIChkYXRhW2tleUluZGV4XSkge1xuICAgICAgYWNjW2RhdGFba2V5SW5kZXhdXSA9IHZhbHVlc0luZGljZXMubWFwKChpbmRleDogbnVtYmVyKSA9PlxuICAgICAgICBub25FbXB0eU9yTnVsbChkYXRhW2luZGV4XSlcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBhY2M7XG4gIH0sIHt9KTtcblxuICByZXR1cm4gT2JqZWN0LmtleXMob2JqZWN0KS5tYXAoKGtleSkgPT4gW2tleSwgLi4ub2JqZWN0W2tleV1dKTtcbn07XG4iXX0=
@@ -1,14 +1,14 @@
1
- import { DbMunicipalityResult, MunicipalityPartResult, SmdError } from "../street-markdown/types";
2
- import { Founder, MunicipalityType, SchoolType } from "./types";
3
- export declare const insertFounders: (founders: Founder[]) => Promise<number>;
4
- export declare const getFounderById: (id: number, schoolType: SchoolType) => Promise<{
5
- founder: Founder;
6
- errors: SmdError[];
7
- }>;
8
- export declare const findFounder: (nameWithHashtag: string, schoolType: SchoolType) => Promise<{
9
- founder: Founder;
10
- errors: SmdError[];
11
- }>;
12
- export declare const getFounderCityCode: (type: MunicipalityType, code: number) => Promise<number>;
13
- export declare const findMunicipalityPartByName: (name: string, cityCode: number) => Promise<MunicipalityPartResult>;
14
- export declare const findMunicipalityByNameAndType: (name: string, type: MunicipalityType, founder: Founder) => Promise<DbMunicipalityResult>;
1
+ import { DbMunicipalityResult, MunicipalityPartResult, SmdError } from "../street-markdown/types";
2
+ import { Founder, MunicipalityType, SchoolType } from "./types";
3
+ export declare const insertFounders: (founders: Founder[]) => Promise<number>;
4
+ export declare const getFounderById: (id: number, schoolType: SchoolType) => Promise<{
5
+ founder: Founder;
6
+ errors: SmdError[];
7
+ }>;
8
+ export declare const findFounder: (nameWithHashtag: string, schoolType: SchoolType) => Promise<{
9
+ founder: Founder;
10
+ errors: SmdError[];
11
+ }>;
12
+ export declare const getFounderCityCode: (type: MunicipalityType, code: number) => Promise<number>;
13
+ export declare const findMunicipalityPartByName: (name: string, cityCode: number) => Promise<MunicipalityPartResult>;
14
+ export declare const findMunicipalityByNameAndType: (name: string, type: MunicipalityType, founder: Founder) => Promise<DbMunicipalityResult>;