@ganju/utils 0.0.20 → 0.0.22
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/dist/constants.d.ts +16 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +43 -0
- package/dist/data.d.ts +7 -5
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +27 -3
- package/dist/dataApi.d.ts +82 -6
- package/dist/dataApi.d.ts.map +1 -1
- package/dist/dataApi.js +47 -4
- package/dist/dataAttachment.d.ts +8 -0
- package/dist/dataAttachment.d.ts.map +1 -0
- package/dist/dataAttachment.js +19 -0
- package/dist/dataCompiler.d.ts +4 -0
- package/dist/dataCompiler.d.ts.map +1 -1
- package/dist/dataCompiler.js +27 -2
- package/dist/dataDdl.d.ts.map +1 -1
- package/dist/dataDdl.js +5 -0
- package/dist/dataEngine.d.ts +25 -3
- package/dist/dataEngine.d.ts.map +1 -1
- package/dist/dataEngine.js +508 -14
- package/dist/dataImport.d.ts +3 -0
- package/dist/dataImport.d.ts.map +1 -1
- package/dist/dataImport.js +12 -2
- package/dist/dataIndexAdvice.d.ts +36 -0
- package/dist/dataIndexAdvice.d.ts.map +1 -0
- package/dist/dataIndexAdvice.js +89 -0
- package/dist/dataRpc.d.ts +20 -1
- package/dist/dataRpc.d.ts.map +1 -1
- package/dist/dataSheet.d.ts +34 -0
- package/dist/dataSheet.d.ts.map +1 -0
- package/dist/dataSheet.js +100 -0
- package/dist/dataTools.js +3 -3
- package/dist/dataTriggers.d.ts +66 -4
- package/dist/dataTriggers.d.ts.map +1 -1
- package/dist/dataTriggers.js +446 -20
- package/dist/dataTypes.d.ts +69 -0
- package/dist/dataTypes.d.ts.map +1 -1
- package/dist/dataTypes.js +21 -1
- package/dist/index.d.ts +91 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/localizeDataError.d.ts.map +1 -1
- package/dist/localizeDataError.js +109 -3
- package/dist/schema.d.ts +67 -6
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +57 -2
- package/dist/untrustedContent.d.ts +7 -0
- package/dist/untrustedContent.d.ts.map +1 -1
- package/dist/untrustedContent.js +13 -1
- package/dist/whatsappWebhook.d.ts +28 -0
- package/dist/whatsappWebhook.d.ts.map +1 -0
- package/dist/whatsappWebhook.js +30 -0
- package/package.json +1 -1
- package/src/constants.ts +46 -0
- package/src/data.ts +33 -3
- package/src/dataApi.ts +54 -4
- package/src/dataAttachment.ts +23 -0
- package/src/dataCompiler.ts +41 -1
- package/src/dataDdl.ts +7 -0
- package/src/dataEngine.ts +680 -15
- package/src/dataImport.ts +16 -1
- package/src/dataIndexAdvice.ts +127 -0
- package/src/dataRpc.ts +27 -2
- package/src/dataSheet.ts +147 -0
- package/src/dataTools.ts +3 -3
- package/src/dataTriggers.ts +599 -20
- package/src/dataTypes.ts +108 -0
- package/src/index.ts +15 -0
- package/src/localizeDataError.ts +183 -4
- package/src/schema.ts +60 -2
- package/src/untrustedContent.ts +15 -0
- package/src/whatsappWebhook.ts +55 -0
package/dist/constants.d.ts
CHANGED
|
@@ -105,6 +105,22 @@ export declare const constants: {
|
|
|
105
105
|
DATA_DELETE_GRACE_DAYS: number;
|
|
106
106
|
DATA_PURGE_BATCH: number;
|
|
107
107
|
DATA_ACTIVITY_THROTTLE_MS: number;
|
|
108
|
+
DATA_INDEX_ADVICE_WINDOW_DAYS: number;
|
|
109
|
+
DATA_INDEX_ADVICE_MIN_QUERIES: number;
|
|
110
|
+
DATA_INDEX_ADVICE_MIN_ROWS_READ: number;
|
|
111
|
+
DATA_INDEX_ADVICE_MIN_READ_RATIO: number;
|
|
112
|
+
DATA_INDEX_UNUSED_WINDOW_DAYS: number;
|
|
113
|
+
DATA_INDEX_UNUSED_MIN_ROWS_WRITTEN: number;
|
|
114
|
+
DATA_QUERY_STAT_KEEP_DAYS: number;
|
|
115
|
+
DATA_INDEX_ADVICE_ADD: "add";
|
|
116
|
+
DATA_INDEX_ADVICE_UNUSED: "unused";
|
|
117
|
+
DATA_INDEX_ADVICE_OPEN: "open";
|
|
118
|
+
DATA_INDEX_ADVICE_DISMISSED: "dismissed";
|
|
119
|
+
DATA_DAILY_JOB_HOUR_UTC: number;
|
|
120
|
+
DATA_ABANDON_WARN_DAYS: number;
|
|
121
|
+
DATA_ABANDON_REMIND_DAYS: number;
|
|
122
|
+
DATA_ABANDON_DELETE_DAYS: number;
|
|
123
|
+
DATA_ABANDON_EXPORT_KEEP_DAYS: number;
|
|
108
124
|
ARTIFACT_DATABASE_STATUS_CREATING: "CREATING";
|
|
109
125
|
ARTIFACT_DATABASE_STATUS_READY: "READY";
|
|
110
126
|
ARTIFACT_DATABASE_STATUS_FAILED: "FAILED";
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAsKA,QAAA,MAAM,yBAAyB,EAAiB,UAAU,CAAC;AAC3D,QAAA,MAAM,+BAA+B,EAAuB,gBAAgB,CAAC;AAC7E,QAAA,MAAM,8BAA8B,EAAsB,eAAe,CAAC;AAC1E,QAAA,MAAM,wBAAwB,EAAgB,SAAS,CAAC;AAuCxD,QAAA,MAAM,sBAAsB,EAAiB,UAAU,CAAC;AACxD,QAAA,MAAM,4BAA4B,EAAuB,gBAAgB,CAAC;AAC1E,QAAA,MAAM,oBAAoB,EAAe,QAAQ,CAAC;AAClD,QAAA,MAAM,oBAAoB,EAAe,QAAQ,CAAC;AA+FlD,QAAA,MAAM,4BAA4B,EAAc,OAAO,CAAC;AACxD,QAAA,MAAM,6BAA6B,EAAe,QAAQ,CAAC;AA2V3D,QAAA,MAAM,sBAAsB,EAAkB,WAAW,CAAC;AAC1D,QAAA,MAAM,mBAAmB,EAAe,QAAQ,CAAC;AAGjD,QAAA,MAAM,mBAAmB,EAAe,QAAQ,CAAC;AAocjD,MAAM,MAAM,mBAAmB,GAC3B;IACE,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GACD;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAC3D;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9D;IACE,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GACD;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"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"}
|
package/dist/constants.js
CHANGED
|
@@ -1899,6 +1899,33 @@ const DATA_PURGE_BATCH = 20;
|
|
|
1899
1899
|
// last_read_at / last_write_at move at most this often, so they aren't a
|
|
1900
1900
|
// Postgres write per query.
|
|
1901
1901
|
const DATA_ACTIVITY_THROTTLE_MS = 60 * 60 * 1000;
|
|
1902
|
+
// Index advice. A column is worth an index when, over a week, at least 50
|
|
1903
|
+
// queries filtered or sorted on it and they read on average 1,000 rows and
|
|
1904
|
+
// 20 rows for every row returned. An index no query used in 30 days on a
|
|
1905
|
+
// table written at least 1,000 rows (and more rows written than queries) is
|
|
1906
|
+
// flagged as unused. Never dropped automatically.
|
|
1907
|
+
const DATA_INDEX_ADVICE_WINDOW_DAYS = 7;
|
|
1908
|
+
const DATA_INDEX_ADVICE_MIN_QUERIES = 50;
|
|
1909
|
+
const DATA_INDEX_ADVICE_MIN_ROWS_READ = 1_000;
|
|
1910
|
+
const DATA_INDEX_ADVICE_MIN_READ_RATIO = 20;
|
|
1911
|
+
const DATA_INDEX_UNUSED_WINDOW_DAYS = 30;
|
|
1912
|
+
const DATA_INDEX_UNUSED_MIN_ROWS_WRITTEN = 1_000;
|
|
1913
|
+
// Daily stats are kept past the longest window, then removed.
|
|
1914
|
+
const DATA_QUERY_STAT_KEEP_DAYS = 35;
|
|
1915
|
+
const DATA_INDEX_ADVICE_ADD = 'add';
|
|
1916
|
+
const DATA_INDEX_ADVICE_UNUSED = 'unused';
|
|
1917
|
+
const DATA_INDEX_ADVICE_OPEN = 'open';
|
|
1918
|
+
const DATA_INDEX_ADVICE_DISMISSED = 'dismissed';
|
|
1919
|
+
// The daily jobs (index advice and the abandoned-database flow) run on the
|
|
1920
|
+
// hourly cron at this UTC hour.
|
|
1921
|
+
const DATA_DAILY_JOB_HOUR_UTC = 13;
|
|
1922
|
+
// Days on Free before a database is warned about, reminded about, and listed
|
|
1923
|
+
// for Ganju to delete by hand.
|
|
1924
|
+
const DATA_ABANDON_WARN_DAYS = 30;
|
|
1925
|
+
const DATA_ABANDON_REMIND_DAYS = 41;
|
|
1926
|
+
const DATA_ABANDON_DELETE_DAYS = 44;
|
|
1927
|
+
// How long the export taken before a database is deleted is kept.
|
|
1928
|
+
const DATA_ABANDON_EXPORT_KEEP_DAYS = 90;
|
|
1902
1929
|
const PLAN_LIMITS = {
|
|
1903
1930
|
FREE: {
|
|
1904
1931
|
maxProjects: 1,
|
|
@@ -2190,6 +2217,22 @@ exports.constants = {
|
|
|
2190
2217
|
DATA_DELETE_GRACE_DAYS,
|
|
2191
2218
|
DATA_PURGE_BATCH,
|
|
2192
2219
|
DATA_ACTIVITY_THROTTLE_MS,
|
|
2220
|
+
DATA_INDEX_ADVICE_WINDOW_DAYS,
|
|
2221
|
+
DATA_INDEX_ADVICE_MIN_QUERIES,
|
|
2222
|
+
DATA_INDEX_ADVICE_MIN_ROWS_READ,
|
|
2223
|
+
DATA_INDEX_ADVICE_MIN_READ_RATIO,
|
|
2224
|
+
DATA_INDEX_UNUSED_WINDOW_DAYS,
|
|
2225
|
+
DATA_INDEX_UNUSED_MIN_ROWS_WRITTEN,
|
|
2226
|
+
DATA_QUERY_STAT_KEEP_DAYS,
|
|
2227
|
+
DATA_INDEX_ADVICE_ADD,
|
|
2228
|
+
DATA_INDEX_ADVICE_UNUSED,
|
|
2229
|
+
DATA_INDEX_ADVICE_OPEN,
|
|
2230
|
+
DATA_INDEX_ADVICE_DISMISSED,
|
|
2231
|
+
DATA_DAILY_JOB_HOUR_UTC,
|
|
2232
|
+
DATA_ABANDON_WARN_DAYS,
|
|
2233
|
+
DATA_ABANDON_REMIND_DAYS,
|
|
2234
|
+
DATA_ABANDON_DELETE_DAYS,
|
|
2235
|
+
DATA_ABANDON_EXPORT_KEEP_DAYS,
|
|
2193
2236
|
ARTIFACT_DATABASE_STATUS_CREATING,
|
|
2194
2237
|
ARTIFACT_DATABASE_STATUS_READY,
|
|
2195
2238
|
ARTIFACT_DATABASE_STATUS_FAILED,
|
package/dist/data.d.ts
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
export * from './dataTypes';
|
|
2
2
|
export { DATA_IDENTIFIER_PATTERN, DATA_SYSTEM_COLUMNS, DATA_HIDDEN_COLUMNS, identifierIssue, isValidIdentifier } from './dataIdentifiers';
|
|
3
3
|
export { createTableSql, columnDefinitionSql, desiredIndexes, desiredTriggers, ftsCreateSql, ftsTableName, searchableColumns, sqlLiteral } from './dataDdl';
|
|
4
|
-
export { chunkRows, rowsPerInsert, ftsMatch, keysetCondition, encodeCursor, decodeCursor, isSensitiveWrite, tidyArgs, zoned } from './dataCompiler';
|
|
4
|
+
export { chunkRows, rowsPerInsert, ftsMatch, keysetCondition, encodeCursor, decodeCursor, isSensitiveWrite, fileUriOf, unknownFileUris, tidyArgs, zoned } from './dataCompiler';
|
|
5
5
|
export type { SqlValue, KeysetCursor, SortKey } from './dataCompiler';
|
|
6
|
-
export { INTERNAL_MIGRATIONS, INTERNAL_SCHEMA_VERSION, hasInternalTables, getMeta, setMeta, migrateInternal, loadSchema, toTableInput, normaliseColumn, translateSqliteError, describe, query, write, rowHistory, pruneHistory, deleteImpact, createTable, updateTable, dropTable, addColumn, updateColumn, dropColumn, columnChangeNeedsRebuild, dropColumnNeedsRebuild, readTableCopy, clearFailedTableCopy, copyTableStep, writeReachesCopy, assertActor, assertWritable, exportRows } from './dataEngine';
|
|
7
|
-
export type { SqlRow, SqlRunner } from './dataEngine';
|
|
6
|
+
export { INTERNAL_MIGRATIONS, INTERNAL_SCHEMA_VERSION, hasInternalTables, getMeta, setMeta, migrateInternal, loadSchema, toTableInput, normaliseColumn, translateSqliteError, describe, query, write, rowHistory, pruneHistory, deleteImpact, fileLinks, replaceFileLinks, createTable, updateTable, dropTable, addColumn, updateColumn, dropColumn, columnChangeNeedsRebuild, dropColumnNeedsRebuild, readTableCopy, clearFailedTableCopy, copyTableStep, writeReachesCopy, assertActor, assertWritable, assertNotSynced, syncRows, recordSyncFailure, exportRows } from './dataEngine';
|
|
7
|
+
export type { SqlRow, SqlRunner, SheetSyncArgs } from './dataEngine';
|
|
8
|
+
export { adviseIndexes, adviceDoubled } from './dataIndexAdvice';
|
|
9
|
+
export type { IndexAdviceCandidate, IndexAdviceInput, IndexAdviceStat } from './dataIndexAdvice';
|
|
8
10
|
export { DATA_QUERY_PARAM_TYPES, DATA_MAX_QUERIES, DATA_MAX_QUERY_SQL, DATA_MAX_QUERY_PARAMS, DATA_DEFAULT_QUERY_ROWS, compileQuerySql, checkQueryPlan, listQueries, queriesFor, saveQuery, dropQuery, runQuery } from './dataQueries';
|
|
9
11
|
export type { DataQuery, DataQueryInput, DataQueryParam, DataQueryParamType } from './dataQueries';
|
|
10
12
|
export type { ProjectDatabaseRpc, DatabaseInfo, ExportFile, ExportFormat, ExportState, RestoreResult } from './dataRpc';
|
|
11
13
|
export { DATA_TOOL_DESCRIBE, DATA_TOOL_QUERY, DATA_TOOL_WRITE, DATA_TOOL_ADMIN, DATA_TOOL_NAMES, DATA_TOOL_TITLES, DATA_TOOL_MAX_LIMIT, DATA_ADMIN_ACTIONS, hasDataToolTables, dataToolDefinitions, dataAdminToolDefinition } from './dataTools';
|
|
12
14
|
export type { DataToolDefinition, DataAdminAction } from './dataTools';
|
|
13
|
-
export { DATA_TRIGGER_EVENTS, DATA_TRIGGER_ACTIONS, DATA_MAX_TRIGGERS, DATA_TRIGGER_MAX_DEPTH, DATA_TRIGGER_DEFAULT_RATE, DATA_TRIGGER_MAX_RATE, DATA_OUTBOX_BATCH, DATA_TRIGGER_MAX_MESSAGE_BYTES, utf8Bytes, conditionMatches, renderTriggerText, normaliseTrigger, listTriggers, getTrigger, saveTrigger, dropTrigger, setTriggerEnabled, replaceManagedTriggers, collectTriggerEvents, readOutbox, deleteOutbox, outboxSize, clearOutbox, triggersUsingColumn, renameColumnInTriggers } from './dataTriggers';
|
|
14
|
-
export type { DataTrigger, DataTriggerAction, DataTriggerActionType, DataTriggerCondition, DataTriggerEvent, DataTriggerEventMessage, DataTriggerInput, DataTriggerTemplate, DataTriggerTest, DataTriggerWithSecret, SavedTrigger } from './dataTriggers';
|
|
15
|
+
export { DATA_TRIGGER_EVENTS, DATA_CHANGE_EVENTS, DATA_TRIGGER_ACTIONS, DATA_MAX_TRIGGERS, DATA_TRIGGER_MAX_DEPTH, DATA_TRIGGER_DEFAULT_RATE, DATA_TRIGGER_MAX_RATE, DATA_OUTBOX_BATCH, DATA_TRIGGER_MAX_MESSAGE_BYTES, DATA_TIME_SCAN_MS, DATA_TIME_MIN_MINUTES, DATA_TIME_MAX_MINUTES, DATA_MAX_TIME_TRIGGERS, DATA_TIME_EVENTS_PER_SCAN, DATA_TIME_EVENTS_PER_DAY, utf8Bytes, conditionMatches, renderTriggerText, renderCustomerMessage, readEventRow, normaliseTrigger, normaliseCustomerAction, listTriggers, getTrigger, saveTrigger, dropTrigger, setTriggerEnabled, replaceManagedTriggers, collectTriggerEvents, readOutbox, deleteOutbox, outboxSize, clearOutbox, triggersUsingColumn, renameColumnInTriggers, timeTriggersCountingFrom, syncTimeIndexes, hasTimeTriggers, scanTimeTriggers } from './dataTriggers';
|
|
16
|
+
export type { DataTrigger, DataTriggerAction, DataTriggerActionType, DataTriggerCondition, DataTriggerCustomerMessage, DataTriggerEvent, DataTriggerEventMessage, DataTriggerInput, DataTriggerSchedule, DataTriggerTemplate, DataTriggerTest, DataTriggerWithSecret, SavedTrigger, TimeScanResult } from './dataTriggers';
|
|
15
17
|
//# sourceMappingURL=data.d.ts.map
|
package/dist/data.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../src/data.ts"],"names":[],"mappings":"AAEA,cAAc,aAAa,CAAC;AAC5B,OAAO,EACL,uBAAuB,EACvB,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,iBAAiB,EAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,UAAU,EACX,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,SAAS,EACT,aAAa,EACb,QAAQ,EACR,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,QAAQ,EACR,KAAK,EACN,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,iBAAiB,EACjB,OAAO,EACP,OAAO,EACP,eAAe,EACf,UAAU,EACV,YAAY,EACZ,eAAe,EACf,oBAAoB,EACpB,QAAQ,EACR,KAAK,EACL,KAAK,EACL,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,WAAW,EACX,SAAS,EACT,SAAS,EACT,YAAY,EACZ,UAAU,EACV,wBAAwB,EACxB,sBAAsB,EACtB,aAAa,EACb,oBAAoB,EACpB,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,UAAU,EACX,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../src/data.ts"],"names":[],"mappings":"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"}
|
package/dist/data.js
CHANGED
|
@@ -14,9 +14,9 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.
|
|
18
|
-
exports.
|
|
19
|
-
exports.renameColumnInTriggers = void 0;
|
|
17
|
+
exports.dropColumnNeedsRebuild = exports.columnChangeNeedsRebuild = exports.dropColumn = exports.updateColumn = exports.addColumn = exports.dropTable = exports.updateTable = exports.createTable = exports.replaceFileLinks = exports.fileLinks = exports.deleteImpact = exports.pruneHistory = exports.rowHistory = exports.write = exports.query = exports.describe = exports.translateSqliteError = exports.normaliseColumn = exports.toTableInput = exports.loadSchema = exports.migrateInternal = exports.setMeta = exports.getMeta = exports.hasInternalTables = exports.INTERNAL_SCHEMA_VERSION = exports.INTERNAL_MIGRATIONS = exports.zoned = exports.tidyArgs = exports.unknownFileUris = exports.fileUriOf = exports.isSensitiveWrite = exports.decodeCursor = exports.encodeCursor = exports.keysetCondition = exports.ftsMatch = exports.rowsPerInsert = exports.chunkRows = exports.sqlLiteral = exports.searchableColumns = exports.ftsTableName = exports.ftsCreateSql = exports.desiredTriggers = exports.desiredIndexes = exports.columnDefinitionSql = exports.createTableSql = exports.isValidIdentifier = exports.identifierIssue = exports.DATA_HIDDEN_COLUMNS = exports.DATA_SYSTEM_COLUMNS = exports.DATA_IDENTIFIER_PATTERN = void 0;
|
|
18
|
+
exports.DATA_TIME_EVENTS_PER_DAY = exports.DATA_TIME_EVENTS_PER_SCAN = exports.DATA_MAX_TIME_TRIGGERS = exports.DATA_TIME_MAX_MINUTES = exports.DATA_TIME_MIN_MINUTES = exports.DATA_TIME_SCAN_MS = exports.DATA_TRIGGER_MAX_MESSAGE_BYTES = exports.DATA_OUTBOX_BATCH = exports.DATA_TRIGGER_MAX_RATE = exports.DATA_TRIGGER_DEFAULT_RATE = exports.DATA_TRIGGER_MAX_DEPTH = exports.DATA_MAX_TRIGGERS = exports.DATA_TRIGGER_ACTIONS = exports.DATA_CHANGE_EVENTS = exports.DATA_TRIGGER_EVENTS = exports.dataAdminToolDefinition = exports.dataToolDefinitions = exports.hasDataToolTables = exports.DATA_ADMIN_ACTIONS = exports.DATA_TOOL_MAX_LIMIT = exports.DATA_TOOL_TITLES = exports.DATA_TOOL_NAMES = exports.DATA_TOOL_ADMIN = exports.DATA_TOOL_WRITE = exports.DATA_TOOL_QUERY = exports.DATA_TOOL_DESCRIBE = exports.runQuery = exports.dropQuery = exports.saveQuery = exports.queriesFor = exports.listQueries = exports.checkQueryPlan = exports.compileQuerySql = exports.DATA_DEFAULT_QUERY_ROWS = exports.DATA_MAX_QUERY_PARAMS = exports.DATA_MAX_QUERY_SQL = exports.DATA_MAX_QUERIES = exports.DATA_QUERY_PARAM_TYPES = exports.adviceDoubled = exports.adviseIndexes = exports.exportRows = exports.recordSyncFailure = exports.syncRows = exports.assertNotSynced = exports.assertWritable = exports.assertActor = exports.writeReachesCopy = exports.copyTableStep = exports.clearFailedTableCopy = exports.readTableCopy = void 0;
|
|
19
|
+
exports.scanTimeTriggers = exports.hasTimeTriggers = exports.syncTimeIndexes = exports.timeTriggersCountingFrom = exports.renameColumnInTriggers = exports.triggersUsingColumn = exports.clearOutbox = exports.outboxSize = exports.deleteOutbox = exports.readOutbox = exports.collectTriggerEvents = exports.replaceManagedTriggers = exports.setTriggerEnabled = exports.dropTrigger = exports.saveTrigger = exports.getTrigger = exports.listTriggers = exports.normaliseCustomerAction = exports.normaliseTrigger = exports.readEventRow = exports.renderCustomerMessage = exports.renderTriggerText = exports.conditionMatches = exports.utf8Bytes = void 0;
|
|
20
20
|
// Entry point for `@ganju/utils/data`: everything a project's database and
|
|
21
21
|
// its callers share, without pulling in the rest of the package.
|
|
22
22
|
__exportStar(require("./dataTypes"), exports);
|
|
@@ -43,6 +43,8 @@ Object.defineProperty(exports, "keysetCondition", { enumerable: true, get: funct
|
|
|
43
43
|
Object.defineProperty(exports, "encodeCursor", { enumerable: true, get: function () { return dataCompiler_1.encodeCursor; } });
|
|
44
44
|
Object.defineProperty(exports, "decodeCursor", { enumerable: true, get: function () { return dataCompiler_1.decodeCursor; } });
|
|
45
45
|
Object.defineProperty(exports, "isSensitiveWrite", { enumerable: true, get: function () { return dataCompiler_1.isSensitiveWrite; } });
|
|
46
|
+
Object.defineProperty(exports, "fileUriOf", { enumerable: true, get: function () { return dataCompiler_1.fileUriOf; } });
|
|
47
|
+
Object.defineProperty(exports, "unknownFileUris", { enumerable: true, get: function () { return dataCompiler_1.unknownFileUris; } });
|
|
46
48
|
Object.defineProperty(exports, "tidyArgs", { enumerable: true, get: function () { return dataCompiler_1.tidyArgs; } });
|
|
47
49
|
Object.defineProperty(exports, "zoned", { enumerable: true, get: function () { return dataCompiler_1.zoned; } });
|
|
48
50
|
var dataEngine_1 = require("./dataEngine");
|
|
@@ -62,6 +64,8 @@ Object.defineProperty(exports, "write", { enumerable: true, get: function () { r
|
|
|
62
64
|
Object.defineProperty(exports, "rowHistory", { enumerable: true, get: function () { return dataEngine_1.rowHistory; } });
|
|
63
65
|
Object.defineProperty(exports, "pruneHistory", { enumerable: true, get: function () { return dataEngine_1.pruneHistory; } });
|
|
64
66
|
Object.defineProperty(exports, "deleteImpact", { enumerable: true, get: function () { return dataEngine_1.deleteImpact; } });
|
|
67
|
+
Object.defineProperty(exports, "fileLinks", { enumerable: true, get: function () { return dataEngine_1.fileLinks; } });
|
|
68
|
+
Object.defineProperty(exports, "replaceFileLinks", { enumerable: true, get: function () { return dataEngine_1.replaceFileLinks; } });
|
|
65
69
|
Object.defineProperty(exports, "createTable", { enumerable: true, get: function () { return dataEngine_1.createTable; } });
|
|
66
70
|
Object.defineProperty(exports, "updateTable", { enumerable: true, get: function () { return dataEngine_1.updateTable; } });
|
|
67
71
|
Object.defineProperty(exports, "dropTable", { enumerable: true, get: function () { return dataEngine_1.dropTable; } });
|
|
@@ -76,7 +80,13 @@ Object.defineProperty(exports, "copyTableStep", { enumerable: true, get: functio
|
|
|
76
80
|
Object.defineProperty(exports, "writeReachesCopy", { enumerable: true, get: function () { return dataEngine_1.writeReachesCopy; } });
|
|
77
81
|
Object.defineProperty(exports, "assertActor", { enumerable: true, get: function () { return dataEngine_1.assertActor; } });
|
|
78
82
|
Object.defineProperty(exports, "assertWritable", { enumerable: true, get: function () { return dataEngine_1.assertWritable; } });
|
|
83
|
+
Object.defineProperty(exports, "assertNotSynced", { enumerable: true, get: function () { return dataEngine_1.assertNotSynced; } });
|
|
84
|
+
Object.defineProperty(exports, "syncRows", { enumerable: true, get: function () { return dataEngine_1.syncRows; } });
|
|
85
|
+
Object.defineProperty(exports, "recordSyncFailure", { enumerable: true, get: function () { return dataEngine_1.recordSyncFailure; } });
|
|
79
86
|
Object.defineProperty(exports, "exportRows", { enumerable: true, get: function () { return dataEngine_1.exportRows; } });
|
|
87
|
+
var dataIndexAdvice_1 = require("./dataIndexAdvice");
|
|
88
|
+
Object.defineProperty(exports, "adviseIndexes", { enumerable: true, get: function () { return dataIndexAdvice_1.adviseIndexes; } });
|
|
89
|
+
Object.defineProperty(exports, "adviceDoubled", { enumerable: true, get: function () { return dataIndexAdvice_1.adviceDoubled; } });
|
|
80
90
|
var dataQueries_1 = require("./dataQueries");
|
|
81
91
|
Object.defineProperty(exports, "DATA_QUERY_PARAM_TYPES", { enumerable: true, get: function () { return dataQueries_1.DATA_QUERY_PARAM_TYPES; } });
|
|
82
92
|
Object.defineProperty(exports, "DATA_MAX_QUERIES", { enumerable: true, get: function () { return dataQueries_1.DATA_MAX_QUERIES; } });
|
|
@@ -104,6 +114,7 @@ Object.defineProperty(exports, "dataToolDefinitions", { enumerable: true, get: f
|
|
|
104
114
|
Object.defineProperty(exports, "dataAdminToolDefinition", { enumerable: true, get: function () { return dataTools_1.dataAdminToolDefinition; } });
|
|
105
115
|
var dataTriggers_1 = require("./dataTriggers");
|
|
106
116
|
Object.defineProperty(exports, "DATA_TRIGGER_EVENTS", { enumerable: true, get: function () { return dataTriggers_1.DATA_TRIGGER_EVENTS; } });
|
|
117
|
+
Object.defineProperty(exports, "DATA_CHANGE_EVENTS", { enumerable: true, get: function () { return dataTriggers_1.DATA_CHANGE_EVENTS; } });
|
|
107
118
|
Object.defineProperty(exports, "DATA_TRIGGER_ACTIONS", { enumerable: true, get: function () { return dataTriggers_1.DATA_TRIGGER_ACTIONS; } });
|
|
108
119
|
Object.defineProperty(exports, "DATA_MAX_TRIGGERS", { enumerable: true, get: function () { return dataTriggers_1.DATA_MAX_TRIGGERS; } });
|
|
109
120
|
Object.defineProperty(exports, "DATA_TRIGGER_MAX_DEPTH", { enumerable: true, get: function () { return dataTriggers_1.DATA_TRIGGER_MAX_DEPTH; } });
|
|
@@ -111,10 +122,19 @@ Object.defineProperty(exports, "DATA_TRIGGER_DEFAULT_RATE", { enumerable: true,
|
|
|
111
122
|
Object.defineProperty(exports, "DATA_TRIGGER_MAX_RATE", { enumerable: true, get: function () { return dataTriggers_1.DATA_TRIGGER_MAX_RATE; } });
|
|
112
123
|
Object.defineProperty(exports, "DATA_OUTBOX_BATCH", { enumerable: true, get: function () { return dataTriggers_1.DATA_OUTBOX_BATCH; } });
|
|
113
124
|
Object.defineProperty(exports, "DATA_TRIGGER_MAX_MESSAGE_BYTES", { enumerable: true, get: function () { return dataTriggers_1.DATA_TRIGGER_MAX_MESSAGE_BYTES; } });
|
|
125
|
+
Object.defineProperty(exports, "DATA_TIME_SCAN_MS", { enumerable: true, get: function () { return dataTriggers_1.DATA_TIME_SCAN_MS; } });
|
|
126
|
+
Object.defineProperty(exports, "DATA_TIME_MIN_MINUTES", { enumerable: true, get: function () { return dataTriggers_1.DATA_TIME_MIN_MINUTES; } });
|
|
127
|
+
Object.defineProperty(exports, "DATA_TIME_MAX_MINUTES", { enumerable: true, get: function () { return dataTriggers_1.DATA_TIME_MAX_MINUTES; } });
|
|
128
|
+
Object.defineProperty(exports, "DATA_MAX_TIME_TRIGGERS", { enumerable: true, get: function () { return dataTriggers_1.DATA_MAX_TIME_TRIGGERS; } });
|
|
129
|
+
Object.defineProperty(exports, "DATA_TIME_EVENTS_PER_SCAN", { enumerable: true, get: function () { return dataTriggers_1.DATA_TIME_EVENTS_PER_SCAN; } });
|
|
130
|
+
Object.defineProperty(exports, "DATA_TIME_EVENTS_PER_DAY", { enumerable: true, get: function () { return dataTriggers_1.DATA_TIME_EVENTS_PER_DAY; } });
|
|
114
131
|
Object.defineProperty(exports, "utf8Bytes", { enumerable: true, get: function () { return dataTriggers_1.utf8Bytes; } });
|
|
115
132
|
Object.defineProperty(exports, "conditionMatches", { enumerable: true, get: function () { return dataTriggers_1.conditionMatches; } });
|
|
116
133
|
Object.defineProperty(exports, "renderTriggerText", { enumerable: true, get: function () { return dataTriggers_1.renderTriggerText; } });
|
|
134
|
+
Object.defineProperty(exports, "renderCustomerMessage", { enumerable: true, get: function () { return dataTriggers_1.renderCustomerMessage; } });
|
|
135
|
+
Object.defineProperty(exports, "readEventRow", { enumerable: true, get: function () { return dataTriggers_1.readEventRow; } });
|
|
117
136
|
Object.defineProperty(exports, "normaliseTrigger", { enumerable: true, get: function () { return dataTriggers_1.normaliseTrigger; } });
|
|
137
|
+
Object.defineProperty(exports, "normaliseCustomerAction", { enumerable: true, get: function () { return dataTriggers_1.normaliseCustomerAction; } });
|
|
118
138
|
Object.defineProperty(exports, "listTriggers", { enumerable: true, get: function () { return dataTriggers_1.listTriggers; } });
|
|
119
139
|
Object.defineProperty(exports, "getTrigger", { enumerable: true, get: function () { return dataTriggers_1.getTrigger; } });
|
|
120
140
|
Object.defineProperty(exports, "saveTrigger", { enumerable: true, get: function () { return dataTriggers_1.saveTrigger; } });
|
|
@@ -128,3 +148,7 @@ Object.defineProperty(exports, "outboxSize", { enumerable: true, get: function (
|
|
|
128
148
|
Object.defineProperty(exports, "clearOutbox", { enumerable: true, get: function () { return dataTriggers_1.clearOutbox; } });
|
|
129
149
|
Object.defineProperty(exports, "triggersUsingColumn", { enumerable: true, get: function () { return dataTriggers_1.triggersUsingColumn; } });
|
|
130
150
|
Object.defineProperty(exports, "renameColumnInTriggers", { enumerable: true, get: function () { return dataTriggers_1.renameColumnInTriggers; } });
|
|
151
|
+
Object.defineProperty(exports, "timeTriggersCountingFrom", { enumerable: true, get: function () { return dataTriggers_1.timeTriggersCountingFrom; } });
|
|
152
|
+
Object.defineProperty(exports, "syncTimeIndexes", { enumerable: true, get: function () { return dataTriggers_1.syncTimeIndexes; } });
|
|
153
|
+
Object.defineProperty(exports, "hasTimeTriggers", { enumerable: true, get: function () { return dataTriggers_1.hasTimeTriggers; } });
|
|
154
|
+
Object.defineProperty(exports, "scanTimeTriggers", { enumerable: true, get: function () { return dataTriggers_1.scanTimeTriggers; } });
|
package/dist/dataApi.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export interface DataApiRoute {
|
|
|
10
10
|
body?: z.ZodType;
|
|
11
11
|
query?: z.ZodObject;
|
|
12
12
|
returns: string;
|
|
13
|
-
status?: 200 | 201;
|
|
13
|
+
status?: 200 | 201 | 202;
|
|
14
14
|
file?: boolean;
|
|
15
15
|
}
|
|
16
16
|
export declare const DATA_API_ROUTES: {
|
|
@@ -19,7 +19,7 @@ export declare const DATA_API_ROUTES: {
|
|
|
19
19
|
readonly path: "";
|
|
20
20
|
readonly tag: "Database";
|
|
21
21
|
readonly summary: "The project's database";
|
|
22
|
-
readonly description: "Its status and size, and its tables when it is ready. `database` is null when the project has none.";
|
|
22
|
+
readonly description: "Its status and size, and its tables when it is ready, with `indexAdvice`: the open index suggestions. `database` is null when the project has none.";
|
|
23
23
|
readonly returns: "{ database }";
|
|
24
24
|
};
|
|
25
25
|
readonly create: {
|
|
@@ -94,6 +94,22 @@ export declare const DATA_API_ROUTES: {
|
|
|
94
94
|
readonly description: "A column change on a table over 100,000 rows copies it in the background; table changes, and writes that would change its rows, wait until it finishes (`copy` on `GET` shows how far it got). A copy that failed left the table as it was and stays in `copy` with its `error` until dismissed, or until the next column change.";
|
|
95
95
|
readonly returns: "{ copy: null }";
|
|
96
96
|
};
|
|
97
|
+
readonly applyIndexAdvice: {
|
|
98
|
+
readonly method: "post";
|
|
99
|
+
readonly path: "/advice/:adviceId";
|
|
100
|
+
readonly tag: "Tables";
|
|
101
|
+
readonly summary: "Add a suggested index";
|
|
102
|
+
readonly description: "`GET` lists the open suggestions in `indexAdvice`: a column filtered or sorted on by 50 or more queries in a week that each read 1,000 or more rows, 20 for every row returned. This marks the column filterable, which indexes it, and records it in the change log. A suggestion of kind `unused` is only a flag; it can't be applied here, only dismissed.";
|
|
103
|
+
readonly returns: "{ table }";
|
|
104
|
+
};
|
|
105
|
+
readonly dismissIndexAdvice: {
|
|
106
|
+
readonly method: "delete";
|
|
107
|
+
readonly path: "/advice/:adviceId";
|
|
108
|
+
readonly tag: "Tables";
|
|
109
|
+
readonly summary: "Dismiss an index suggestion";
|
|
110
|
+
readonly description: "It stays dismissed until its numbers double (queries, rows read per query, or rows written for an unused index).";
|
|
111
|
+
readonly returns: "{ dismissed: true }";
|
|
112
|
+
};
|
|
97
113
|
readonly listTables: {
|
|
98
114
|
readonly method: "get";
|
|
99
115
|
readonly path: "/table";
|
|
@@ -113,12 +129,17 @@ export declare const DATA_API_ROUTES: {
|
|
|
113
129
|
displayColumn: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
114
130
|
access: z.ZodOptional<z.ZodEnum<{
|
|
115
131
|
none: "none";
|
|
116
|
-
read: "read";
|
|
117
132
|
add: "add";
|
|
133
|
+
read: "read";
|
|
118
134
|
full: "full";
|
|
119
135
|
}>>;
|
|
120
136
|
customerScoped: z.ZodOptional<z.ZodBoolean>;
|
|
121
137
|
history: z.ZodOptional<z.ZodBoolean>;
|
|
138
|
+
source: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
139
|
+
uri: z.ZodString;
|
|
140
|
+
sheet: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
141
|
+
key: z.ZodString;
|
|
142
|
+
}, z.core.$strict>>>;
|
|
122
143
|
columns: z.ZodArray<z.ZodObject<{
|
|
123
144
|
name: z.ZodString;
|
|
124
145
|
type: z.ZodEnum<{
|
|
@@ -163,15 +184,21 @@ export declare const DATA_API_ROUTES: {
|
|
|
163
184
|
readonly path: "/table/:table";
|
|
164
185
|
readonly tag: "Tables";
|
|
165
186
|
readonly summary: "Rename a table or change its settings";
|
|
187
|
+
readonly description: "`source` (`{ uri, sheet?, key }`) keeps the table's rows in step with a spreadsheet or CSV in the project's knowledge, matched by `key`, a unique column: the sheet wins, and row writes to the table are refused until `source` is set back to null. It syncs when the file changes and from `POST …/sync`; `sync` on the table says how the last one went.";
|
|
166
188
|
readonly body: z.ZodObject<{
|
|
167
189
|
name: z.ZodOptional<z.ZodString>;
|
|
190
|
+
source: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
191
|
+
uri: z.ZodString;
|
|
192
|
+
sheet: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
193
|
+
key: z.ZodString;
|
|
194
|
+
}, z.core.$strict>>>>;
|
|
168
195
|
label: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
|
|
169
196
|
description: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
|
|
170
197
|
displayColumn: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
|
|
171
198
|
access: z.ZodOptional<z.ZodOptional<z.ZodEnum<{
|
|
172
199
|
none: "none";
|
|
173
|
-
read: "read";
|
|
174
200
|
add: "add";
|
|
201
|
+
read: "read";
|
|
175
202
|
full: "full";
|
|
176
203
|
}>>>;
|
|
177
204
|
customerScoped: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
|
|
@@ -179,6 +206,15 @@ export declare const DATA_API_ROUTES: {
|
|
|
179
206
|
}, z.core.$strict>;
|
|
180
207
|
readonly returns: "{ table }";
|
|
181
208
|
};
|
|
209
|
+
readonly syncTable: {
|
|
210
|
+
readonly method: "post";
|
|
211
|
+
readonly path: "/table/:table/sync";
|
|
212
|
+
readonly tag: "Tables";
|
|
213
|
+
readonly summary: "Sync a table from its sheet now";
|
|
214
|
+
readonly description: "Queues a sync of a table that has a `source`: a Google Drive or OneDrive file is fetched again first if it changed. New keys are inserted, rows that differ updated (actor `system:sheet-sync`, so triggers fire), rows whose key is gone deleted. A sheet that doesn't fit (a missing key column, a repeated key, a value a column won't take) changes nothing; the table's `sync` says why.";
|
|
215
|
+
readonly returns: "{ queued: true }";
|
|
216
|
+
readonly status: 202;
|
|
217
|
+
};
|
|
182
218
|
readonly dropTable: {
|
|
183
219
|
readonly method: "delete";
|
|
184
220
|
readonly path: "/table/:table";
|
|
@@ -289,7 +325,7 @@ export declare const DATA_API_ROUTES: {
|
|
|
289
325
|
readonly path: "/table/:table/row";
|
|
290
326
|
readonly tag: "Rows";
|
|
291
327
|
readonly summary: "List, filter and search rows";
|
|
292
|
-
readonly description: "Up to 500 rows or 1 MB a page; `nextCursor` reads the next. `where` is JSON, e.g. `{\"status\":\"open\",\"price\":{\"lt\":30000}}`. `sort` is a list of columns, `-` for descending. `q` searches the searchable columns.";
|
|
328
|
+
readonly description: "Up to 500 rows or 1 MB a page; `nextCursor` reads the next. `where` is JSON, e.g. `{\"status\":\"open\",\"price\":{\"lt\":30000}}`. `sort` is a list of columns, `-` for descending. `q` searches the searchable columns. A relation comes back as `{ id, label }`; a file column as `{ uri, id, title, mimeType }`, or `{ uri, missing: true }` when no resource has the uri any more. Writes take a file column's uri.";
|
|
293
329
|
readonly query: z.ZodObject<{
|
|
294
330
|
where: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<unknown, string>>>;
|
|
295
331
|
sort: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string[], string>>>;
|
|
@@ -476,7 +512,7 @@ export declare const DATA_API_ROUTES: {
|
|
|
476
512
|
readonly path: "/trigger";
|
|
477
513
|
readonly tag: "Triggers";
|
|
478
514
|
readonly summary: "Save a trigger";
|
|
479
|
-
readonly description: "Runs one action when rows of `table` are inserted, updated or deleted, and `when` holds: `{ \"status\": { \"changedTo\": \"READY\" } }` fires on the transition only; `changedFrom`, `changed: true` and `equals` test a column too, and `all` / `any` combine them. The action is one of `function` (a function of this project, given `{ event, table, row, previous, actor, eventId, triggerId }`), `webhook` (an https URL, sent a POST signed in `x-ganju-signature`), `chat` (`{ channelId, chatId, text }`), `email` (`{ to, subject, text }`) or `customer` (`{ text, template? }`, to the row's customer on a customer-scoped table). Texts take `{{field}}` from the row, inserted as plain text. Saving under an existing name replaces it, unless `replace` is false; with no `name`, it always creates a new trigger, named from the table, event and action and numbered past those taken. Left out, `enabled` keeps a saved trigger on or off as it was. A new webhook answers with its signing `secret`, shown this once. An `email` goes to the organization's members; any other address is sent a link to confirm first, and those still waiting come back as `confirming`. Delivery is at least once: every event carries an `eventId`.";
|
|
515
|
+
readonly description: "Runs one action when rows of `table` are inserted, updated or deleted, and `when` holds: `{ \"status\": { \"changedTo\": \"READY\" } }` fires on the transition only; `changedFrom`, `changed: true` and `equals` test a column too, and `all` / `any` combine them. With `\"on\": \"time\"` it fires instead once a row comes due, with nothing written: `after` is `{ column, minutes }`, the column `created_at`, `updated_at` or a date or datetime column (a date counts from midnight in the database's time zone) and `minutes` 5 to 43,200, negative on a date or datetime for before it. Its `when` tests `equals` only, read when the row comes due; rows already due when it is saved don't fire, and each row fires once per due time (an `updated_at` trigger again after the next change). Due rows are looked for every 5 minutes, up to 100 events per trigger per scan; a database holds up to 10 time triggers, and the database's time triggers share 2,000 events a day (UTC): past that, each time trigger with another row due that day is turned off and the organization's admins are emailed. A time trigger is also turned off when its runs are paused (the plan no longer includes Data, or the month's trigger runs reached the plan's limit). The action is one of `function` (a function of this project, given `{ event, table, row, previous, actor, eventId, triggerId, dueAt? }`), `webhook` (an https URL, sent a POST signed in `x-ganju-signature`), `chat` (`{ channelId, chatId, text }`), `email` (`{ to, subject, text }`) or `customer` (`{ text, template? }`, to the row's customer on a customer-scoped table). Texts take `{{field}}` from the row, inserted as plain text. Saving under an existing name replaces it, unless `replace` is false; with no `name`, it always creates a new trigger, named from the table, event and action and numbered past those taken. Left out, `enabled` keeps a saved trigger on or off as it was. A new webhook answers with its signing `secret`, shown this once. An `email` goes to the organization's members; any other address is sent a link to confirm first, and those still waiting come back as `confirming`. Delivery is at least once: every event carries an `eventId`.";
|
|
480
516
|
readonly body: z.ZodObject<{
|
|
481
517
|
name: z.ZodOptional<z.ZodString>;
|
|
482
518
|
description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
@@ -485,7 +521,12 @@ export declare const DATA_API_ROUTES: {
|
|
|
485
521
|
insert: "insert";
|
|
486
522
|
update: "update";
|
|
487
523
|
delete: "delete";
|
|
524
|
+
time: "time";
|
|
488
525
|
}>;
|
|
526
|
+
after: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
527
|
+
column: z.ZodString;
|
|
528
|
+
minutes: z.ZodNumber;
|
|
529
|
+
}, z.core.$strict>>>;
|
|
489
530
|
when: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
490
531
|
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
491
532
|
replace: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -547,7 +588,12 @@ export declare const DATA_API_ROUTES: {
|
|
|
547
588
|
insert: "insert";
|
|
548
589
|
update: "update";
|
|
549
590
|
delete: "delete";
|
|
591
|
+
time: "time";
|
|
550
592
|
}>;
|
|
593
|
+
after: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
594
|
+
column: z.ZodString;
|
|
595
|
+
minutes: z.ZodNumber;
|
|
596
|
+
}, z.core.$strict>>>;
|
|
551
597
|
when: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
552
598
|
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
553
599
|
replace: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -576,6 +622,36 @@ export declare const DATA_API_ROUTES: {
|
|
|
576
622
|
}, z.core.$strict>;
|
|
577
623
|
readonly returns: "{ triggers, removed, secrets, confirming? }";
|
|
578
624
|
};
|
|
625
|
+
readonly listTestRecipients: {
|
|
626
|
+
readonly method: "get";
|
|
627
|
+
readonly path: "/trigger/test-send";
|
|
628
|
+
readonly tag: "Triggers";
|
|
629
|
+
readonly summary: "Where a test send can go";
|
|
630
|
+
readonly description: "The caller's own chats with this project's bots: the ones they linked to their Ganju account by sending `/link` to the bot. Empty when there are none.";
|
|
631
|
+
readonly returns: "{ recipients }";
|
|
632
|
+
};
|
|
633
|
+
readonly testSend: {
|
|
634
|
+
readonly method: "post";
|
|
635
|
+
readonly path: "/trigger/test-send";
|
|
636
|
+
readonly tag: "Triggers";
|
|
637
|
+
readonly summary: "Send a test of a customer message";
|
|
638
|
+
readonly description: "Sends a `customer` action, saved or not, to the caller's own chat with the bot instead of the row's customer: built from the row `rowId` (the table's newest row by default), the same as a real run. `participantId` picks one of `GET /trigger/test-send`'s recipients when there are several. With `asTemplate`, a WhatsApp template goes out even inside the 24-hour window. Not a run: it isn't listed with any trigger's runs and doesn't count toward the daily limit per customer. Five a minute per user. A channel's refusal (the template not approved, outside the window with no template, the daily limit) comes back as the error.";
|
|
639
|
+
readonly body: z.ZodObject<{
|
|
640
|
+
table: z.ZodString;
|
|
641
|
+
customer: z.ZodObject<{
|
|
642
|
+
text: z.ZodString;
|
|
643
|
+
template: z.ZodOptional<z.ZodObject<{
|
|
644
|
+
name: z.ZodString;
|
|
645
|
+
language: z.ZodString;
|
|
646
|
+
params: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
647
|
+
}, z.core.$strict>>;
|
|
648
|
+
}, z.core.$strict>;
|
|
649
|
+
rowId: z.ZodOptional<z.ZodNumber>;
|
|
650
|
+
participantId: z.ZodOptional<z.ZodString>;
|
|
651
|
+
asTemplate: z.ZodOptional<z.ZodBoolean>;
|
|
652
|
+
}, z.core.$strict>;
|
|
653
|
+
readonly returns: "{ sent, text, template, rowId, recipient }";
|
|
654
|
+
};
|
|
579
655
|
readonly listTriggerRuns: {
|
|
580
656
|
readonly method: "get";
|
|
581
657
|
readonly path: "/trigger/:name/run";
|
package/dist/dataApi.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataApi.d.ts","sourceRoot":"","sources":["../src/dataApi.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,aAAa,mEACwC,CAAC;AAEnE,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEhE,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,aAAa,CAAC;IAEtB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,EACC,UAAU,GACV,QAAQ,GACR,MAAM,GACN,SAAS,GACT,UAAU,GACV,oBAAoB,CAAC;IACzB,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IAEpB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC;
|
|
1
|
+
{"version":3,"file":"dataApi.d.ts","sourceRoot":"","sources":["../src/dataApi.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,aAAa,mEACwC,CAAC;AAEnE,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEhE,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,aAAa,CAAC;IAEtB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,EACC,UAAU,GACV,QAAQ,GACR,MAAM,GACN,SAAS,GACT,UAAU,GACV,oBAAoB,CAAC;IACzB,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IAEpB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;IAEzB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAiCD,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoZqB,CAAC;AAElD,MAAM,MAAM,cAAc,GAAG,MAAM,OAAO,eAAe,CAAC;AAmB1D;;;GAGG;AACH,eAAO,MAAM,WAAW,GAAI,WAAW,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8G5C,CAAC"}
|
package/dist/dataApi.js
CHANGED
|
@@ -7,14 +7,14 @@ exports.dataOpenApi = exports.DATA_API_ROUTES = exports.DATA_API_BASE = void 0;
|
|
|
7
7
|
const zod_1 = require("zod");
|
|
8
8
|
const schema_1 = require("./schema");
|
|
9
9
|
exports.DATA_API_BASE = '/organization/:organizationId/project/:projectId/artifact/data';
|
|
10
|
-
const { DATA_DATABASE_CREATE, DATA_DATABASE_DELETE, DATA_DATABASE_PATCH, DATA_TABLE_INPUT, DATA_TABLE_PATCH, DATA_COLUMN_INPUT, DATA_COLUMN_PATCH, DATA_TABLE_DROP_BODY, DATA_ROW_LIST_QUERY, DATA_ROW_GET_QUERY, DATA_ROW_CREATE_BODY, DATA_ROW_UPDATE_BODY, DATA_ROW_DELETE_BODY, DATA_DELETE_PREVIEW_BODY, DATA_WRITE_BODY, DATA_ROW_HISTORY_QUERY, DATA_RESTORE_POINT_BODY, DATA_EXPORT_BODY, DATA_EXPORT_QUERY, DATA_EXPORT_FILE_QUERY, DATA_CHANGE_LIST_QUERY, DATA_QUERY_INPUT, DATA_QUERY_RUN_BODY, DATA_TRIGGER_INPUT, DATA_TRIGGER_PATCH, DATA_TRIGGER_DEPLOY_BODY, DATA_TRIGGER_RUN_LIST_QUERY } = schema_1.Schema;
|
|
10
|
+
const { DATA_DATABASE_CREATE, DATA_DATABASE_DELETE, DATA_DATABASE_PATCH, DATA_TABLE_INPUT, DATA_TABLE_PATCH, DATA_COLUMN_INPUT, DATA_COLUMN_PATCH, DATA_TABLE_DROP_BODY, DATA_ROW_LIST_QUERY, DATA_ROW_GET_QUERY, DATA_ROW_CREATE_BODY, DATA_ROW_UPDATE_BODY, DATA_ROW_DELETE_BODY, DATA_DELETE_PREVIEW_BODY, DATA_WRITE_BODY, DATA_ROW_HISTORY_QUERY, DATA_RESTORE_POINT_BODY, DATA_EXPORT_BODY, DATA_EXPORT_QUERY, DATA_EXPORT_FILE_QUERY, DATA_CHANGE_LIST_QUERY, DATA_QUERY_INPUT, DATA_QUERY_RUN_BODY, DATA_TRIGGER_INPUT, DATA_TRIGGER_PATCH, DATA_TRIGGER_DEPLOY_BODY, DATA_TRIGGER_TEST_SEND_BODY, DATA_TRIGGER_RUN_LIST_QUERY } = schema_1.Schema;
|
|
11
11
|
exports.DATA_API_ROUTES = {
|
|
12
12
|
getDatabase: {
|
|
13
13
|
method: 'get',
|
|
14
14
|
path: '',
|
|
15
15
|
tag: 'Database',
|
|
16
16
|
summary: "The project's database",
|
|
17
|
-
description: 'Its status and size, and its tables when it is ready. `database` is null when the project has none.',
|
|
17
|
+
description: 'Its status and size, and its tables when it is ready, with `indexAdvice`: the open index suggestions. `database` is null when the project has none.',
|
|
18
18
|
returns: '{ database }'
|
|
19
19
|
},
|
|
20
20
|
create: {
|
|
@@ -78,6 +78,22 @@ exports.DATA_API_ROUTES = {
|
|
|
78
78
|
description: 'A column change on a table over 100,000 rows copies it in the background; table changes, and writes that would change its rows, wait until it finishes (`copy` on `GET` shows how far it got). A copy that failed left the table as it was and stays in `copy` with its `error` until dismissed, or until the next column change.',
|
|
79
79
|
returns: '{ copy: null }'
|
|
80
80
|
},
|
|
81
|
+
applyIndexAdvice: {
|
|
82
|
+
method: 'post',
|
|
83
|
+
path: '/advice/:adviceId',
|
|
84
|
+
tag: 'Tables',
|
|
85
|
+
summary: 'Add a suggested index',
|
|
86
|
+
description: "`GET` lists the open suggestions in `indexAdvice`: a column filtered or sorted on by 50 or more queries in a week that each read 1,000 or more rows, 20 for every row returned. This marks the column filterable, which indexes it, and records it in the change log. A suggestion of kind `unused` is only a flag; it can't be applied here, only dismissed.",
|
|
87
|
+
returns: '{ table }'
|
|
88
|
+
},
|
|
89
|
+
dismissIndexAdvice: {
|
|
90
|
+
method: 'delete',
|
|
91
|
+
path: '/advice/:adviceId',
|
|
92
|
+
tag: 'Tables',
|
|
93
|
+
summary: 'Dismiss an index suggestion',
|
|
94
|
+
description: 'It stays dismissed until its numbers double (queries, rows read per query, or rows written for an unused index).',
|
|
95
|
+
returns: '{ dismissed: true }'
|
|
96
|
+
},
|
|
81
97
|
listTables: {
|
|
82
98
|
method: 'get',
|
|
83
99
|
path: '/table',
|
|
@@ -99,9 +115,19 @@ exports.DATA_API_ROUTES = {
|
|
|
99
115
|
path: '/table/:table',
|
|
100
116
|
tag: 'Tables',
|
|
101
117
|
summary: 'Rename a table or change its settings',
|
|
118
|
+
description: "`source` (`{ uri, sheet?, key }`) keeps the table's rows in step with a spreadsheet or CSV in the project's knowledge, matched by `key`, a unique column: the sheet wins, and row writes to the table are refused until `source` is set back to null. It syncs when the file changes and from `POST …/sync`; `sync` on the table says how the last one went.",
|
|
102
119
|
body: DATA_TABLE_PATCH,
|
|
103
120
|
returns: '{ table }'
|
|
104
121
|
},
|
|
122
|
+
syncTable: {
|
|
123
|
+
method: 'post',
|
|
124
|
+
path: '/table/:table/sync',
|
|
125
|
+
tag: 'Tables',
|
|
126
|
+
summary: 'Sync a table from its sheet now',
|
|
127
|
+
description: "Queues a sync of a table that has a `source`: a Google Drive or OneDrive file is fetched again first if it changed. New keys are inserted, rows that differ updated (actor `system:sheet-sync`, so triggers fire), rows whose key is gone deleted. A sheet that doesn't fit (a missing key column, a repeated key, a value a column won't take) changes nothing; the table's `sync` says why.",
|
|
128
|
+
returns: '{ queued: true }',
|
|
129
|
+
status: 202
|
|
130
|
+
},
|
|
105
131
|
dropTable: {
|
|
106
132
|
method: 'delete',
|
|
107
133
|
path: '/table/:table',
|
|
@@ -142,7 +168,7 @@ exports.DATA_API_ROUTES = {
|
|
|
142
168
|
path: '/table/:table/row',
|
|
143
169
|
tag: 'Rows',
|
|
144
170
|
summary: 'List, filter and search rows',
|
|
145
|
-
description: 'Up to 500 rows or 1 MB a page; `nextCursor` reads the next. `where` is JSON, e.g. `{"status":"open","price":{"lt":30000}}`. `sort` is a list of columns, `-` for descending. `q` searches the searchable columns.',
|
|
171
|
+
description: 'Up to 500 rows or 1 MB a page; `nextCursor` reads the next. `where` is JSON, e.g. `{"status":"open","price":{"lt":30000}}`. `sort` is a list of columns, `-` for descending. `q` searches the searchable columns. A relation comes back as `{ id, label }`; a file column as `{ uri, id, title, mimeType }`, or `{ uri, missing: true }` when no resource has the uri any more. Writes take a file column\'s uri.',
|
|
146
172
|
query: DATA_ROW_LIST_QUERY,
|
|
147
173
|
returns: '{ table, rows, total?, nextCursor? }'
|
|
148
174
|
},
|
|
@@ -255,7 +281,7 @@ exports.DATA_API_ROUTES = {
|
|
|
255
281
|
path: '/trigger',
|
|
256
282
|
tag: 'Triggers',
|
|
257
283
|
summary: 'Save a trigger',
|
|
258
|
-
description: 'Runs one action when rows of `table` are inserted, updated or deleted, and `when` holds: `{ "status": { "changedTo": "READY" } }` fires on the transition only; `changedFrom`, `changed: true` and `equals` test a column too, and `all` / `any` combine them. The action is one of `function` (a function of this project, given `{ event, table, row, previous, actor, eventId, triggerId }`), `webhook` (an https URL, sent a POST signed in `x-ganju-signature`), `chat` (`{ channelId, chatId, text }`), `email` (`{ to, subject, text }`) or `customer` (`{ text, template? }`, to the row\'s customer on a customer-scoped table). Texts take `{{field}}` from the row, inserted as plain text. Saving under an existing name replaces it, unless `replace` is false; with no `name`, it always creates a new trigger, named from the table, event and action and numbered past those taken. Left out, `enabled` keeps a saved trigger on or off as it was. A new webhook answers with its signing `secret`, shown this once. An `email` goes to the organization\'s members; any other address is sent a link to confirm first, and those still waiting come back as `confirming`. Delivery is at least once: every event carries an `eventId`.',
|
|
284
|
+
description: 'Runs one action when rows of `table` are inserted, updated or deleted, and `when` holds: `{ "status": { "changedTo": "READY" } }` fires on the transition only; `changedFrom`, `changed: true` and `equals` test a column too, and `all` / `any` combine them. With `"on": "time"` it fires instead once a row comes due, with nothing written: `after` is `{ column, minutes }`, the column `created_at`, `updated_at` or a date or datetime column (a date counts from midnight in the database\'s time zone) and `minutes` 5 to 43,200, negative on a date or datetime for before it. Its `when` tests `equals` only, read when the row comes due; rows already due when it is saved don\'t fire, and each row fires once per due time (an `updated_at` trigger again after the next change). Due rows are looked for every 5 minutes, up to 100 events per trigger per scan; a database holds up to 10 time triggers, and the database\'s time triggers share 2,000 events a day (UTC): past that, each time trigger with another row due that day is turned off and the organization\'s admins are emailed. A time trigger is also turned off when its runs are paused (the plan no longer includes Data, or the month\'s trigger runs reached the plan\'s limit). The action is one of `function` (a function of this project, given `{ event, table, row, previous, actor, eventId, triggerId, dueAt? }`), `webhook` (an https URL, sent a POST signed in `x-ganju-signature`), `chat` (`{ channelId, chatId, text }`), `email` (`{ to, subject, text }`) or `customer` (`{ text, template? }`, to the row\'s customer on a customer-scoped table). Texts take `{{field}}` from the row, inserted as plain text. Saving under an existing name replaces it, unless `replace` is false; with no `name`, it always creates a new trigger, named from the table, event and action and numbered past those taken. Left out, `enabled` keeps a saved trigger on or off as it was. A new webhook answers with its signing `secret`, shown this once. An `email` goes to the organization\'s members; any other address is sent a link to confirm first, and those still waiting come back as `confirming`. Delivery is at least once: every event carries an `eventId`.',
|
|
259
285
|
body: DATA_TRIGGER_INPUT,
|
|
260
286
|
returns: '{ trigger, secret?, confirming? }',
|
|
261
287
|
status: 201
|
|
@@ -285,6 +311,23 @@ exports.DATA_API_ROUTES = {
|
|
|
285
311
|
body: DATA_TRIGGER_DEPLOY_BODY,
|
|
286
312
|
returns: '{ triggers, removed, secrets, confirming? }'
|
|
287
313
|
},
|
|
314
|
+
listTestRecipients: {
|
|
315
|
+
method: 'get',
|
|
316
|
+
path: '/trigger/test-send',
|
|
317
|
+
tag: 'Triggers',
|
|
318
|
+
summary: 'Where a test send can go',
|
|
319
|
+
description: "The caller's own chats with this project's bots: the ones they linked to their Ganju account by sending `/link` to the bot. Empty when there are none.",
|
|
320
|
+
returns: '{ recipients }'
|
|
321
|
+
},
|
|
322
|
+
testSend: {
|
|
323
|
+
method: 'post',
|
|
324
|
+
path: '/trigger/test-send',
|
|
325
|
+
tag: 'Triggers',
|
|
326
|
+
summary: 'Send a test of a customer message',
|
|
327
|
+
description: "Sends a `customer` action, saved or not, to the caller's own chat with the bot instead of the row's customer: built from the row `rowId` (the table's newest row by default), the same as a real run. `participantId` picks one of `GET /trigger/test-send`'s recipients when there are several. With `asTemplate`, a WhatsApp template goes out even inside the 24-hour window. Not a run: it isn't listed with any trigger's runs and doesn't count toward the daily limit per customer. Five a minute per user. A channel's refusal (the template not approved, outside the window with no template, the daily limit) comes back as the error.",
|
|
328
|
+
body: DATA_TRIGGER_TEST_SEND_BODY,
|
|
329
|
+
returns: '{ sent, text, template, rowId, recipient }'
|
|
330
|
+
},
|
|
288
331
|
listTriggerRuns: {
|
|
289
332
|
method: 'get',
|
|
290
333
|
path: '/trigger/:name/run',
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface DataAttachment {
|
|
2
|
+
table: string;
|
|
3
|
+
column: string;
|
|
4
|
+
index: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare const dataAttachmentOf: (metadata: unknown) => DataAttachment | null;
|
|
7
|
+
export declare const skipsIndexing: (metadata: unknown) => boolean;
|
|
8
|
+
//# sourceMappingURL=dataAttachment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataAttachment.d.ts","sourceRoot":"","sources":["../src/dataAttachment.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;CAChB;AAID,eAAO,MAAM,gBAAgB,GAAI,UAAU,OAAO,KAAG,cAAc,GAAG,IAMrE,CAAC;AAGF,eAAO,MAAM,aAAa,GAAI,UAAU,OAAO,KAAG,OAGjD,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.skipsIndexing = exports.dataAttachmentOf = void 0;
|
|
4
|
+
const schema_1 = require("./schema");
|
|
5
|
+
// The Data upload a knowledge item came from, read from its metadata, or
|
|
6
|
+
// null for any other item.
|
|
7
|
+
const dataAttachmentOf = (metadata) => {
|
|
8
|
+
if (!metadata || typeof metadata !== 'object')
|
|
9
|
+
return null;
|
|
10
|
+
const parsed = schema_1.Schema.DATA_ATTACHMENT_METADATA.safeParse(metadata.dataAttachment);
|
|
11
|
+
return parsed.success ? parsed.data : null;
|
|
12
|
+
};
|
|
13
|
+
exports.dataAttachmentOf = dataAttachmentOf;
|
|
14
|
+
// Uploads from Data are stored, not indexed, unless their column asks.
|
|
15
|
+
const skipsIndexing = (metadata) => {
|
|
16
|
+
const attachment = (0, exports.dataAttachmentOf)(metadata);
|
|
17
|
+
return attachment !== null && !attachment.index;
|
|
18
|
+
};
|
|
19
|
+
exports.skipsIndexing = skipsIndexing;
|
package/dist/dataCompiler.d.ts
CHANGED
|
@@ -28,6 +28,9 @@ export declare const joinsSql: (joins: Map<string, SqlJoin>) => string;
|
|
|
28
28
|
export declare const joinsParams: (joins: Map<string, SqlJoin>) => SqlValue[];
|
|
29
29
|
export declare const relationJoin: (caller: DataCaller, target: DataTable, alias: string, on: string) => SqlJoin;
|
|
30
30
|
export declare const isoSeconds: (date: Date) => string;
|
|
31
|
+
export declare const localDatetime: (value: string, timeZone?: string) => Date | null;
|
|
32
|
+
export declare const fileUriOf: (value: unknown, label: string) => string;
|
|
33
|
+
export declare const unknownFileUris: (uris: string[]) => DataError;
|
|
31
34
|
export declare const toStored: (table: DataTable, column: ResolvableColumn, value: unknown, timeZone?: string) => SqlValue;
|
|
32
35
|
export declare const zoneOffsetMinutes: (date: Date, timeZone?: string) => number;
|
|
33
36
|
export declare const zoned: (iso: string, timeZone?: string) => string;
|
|
@@ -44,6 +47,7 @@ export interface CompileContext {
|
|
|
44
47
|
table: DataTable;
|
|
45
48
|
joins: Map<string, SqlJoin>;
|
|
46
49
|
params: SqlValue[];
|
|
50
|
+
filtered?: Set<string>;
|
|
47
51
|
}
|
|
48
52
|
export declare const resolvePath: (ctx: CompileContext, path: unknown) => ResolvedPath;
|
|
49
53
|
export declare const compileWhere: (ctx: CompileContext, where: unknown, indexed?: Set<string>) => string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataCompiler.d.ts","sourceRoot":"","sources":["../src/dataCompiler.ts"],"names":[],"mappings":"AAMA,OAAO,
|
|
1
|
+
{"version":3,"file":"dataCompiler.d.ts","sourceRoot":"","sources":["../src/dataCompiler.ts"],"names":[],"mappings":"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"}
|