@elumixor/notion-orm 0.1.1 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +112 -210
- package/dist/ast/constants.d.ts +12 -13
- package/dist/cli.js +5409 -2038
- package/dist/config/helpers.d.ts +3 -1
- package/dist/db-client/add.d.ts +1 -1
- package/dist/db-client/client.d.ts +175 -0
- package/dist/db-client/query.d.ts +6 -3
- package/dist/db-client/{queryTypes.d.ts → types.d.ts} +39 -9
- package/dist/index.js +209 -97
- package/dist/public-api.d.ts +2 -2
- package/package.json +2 -1
- package/dist/db-client/DatabaseClient.d.ts +0 -47
package/dist/index.js
CHANGED
|
@@ -3,15 +3,29 @@ var __getProtoOf = Object.getPrototypeOf;
|
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
function __accessProp(key) {
|
|
7
|
+
return this[key];
|
|
8
|
+
}
|
|
9
|
+
var __toESMCache_node;
|
|
10
|
+
var __toESMCache_esm;
|
|
6
11
|
var __toESM = (mod, isNodeMode, target) => {
|
|
12
|
+
var canCache = mod != null && typeof mod === "object";
|
|
13
|
+
if (canCache) {
|
|
14
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
15
|
+
var cached = cache.get(mod);
|
|
16
|
+
if (cached)
|
|
17
|
+
return cached;
|
|
18
|
+
}
|
|
7
19
|
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
8
20
|
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
9
21
|
for (let key of __getOwnPropNames(mod))
|
|
10
22
|
if (!__hasOwnProp.call(to, key))
|
|
11
23
|
__defProp(to, key, {
|
|
12
|
-
get: (
|
|
24
|
+
get: __accessProp.bind(mod, key),
|
|
13
25
|
enumerable: true
|
|
14
26
|
});
|
|
27
|
+
if (canCache)
|
|
28
|
+
cache.set(mod, to);
|
|
15
29
|
return to;
|
|
16
30
|
};
|
|
17
31
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
@@ -1327,7 +1341,7 @@ var require_src = __commonJS((exports) => {
|
|
|
1327
1341
|
} });
|
|
1328
1342
|
});
|
|
1329
1343
|
|
|
1330
|
-
// src/db-client/
|
|
1344
|
+
// src/db-client/client.ts
|
|
1331
1345
|
var import_client = __toESM(require_src(), 1);
|
|
1332
1346
|
|
|
1333
1347
|
// src/ast/constants.ts
|
|
@@ -1337,7 +1351,6 @@ var __filename2 = fileURLToPath(import.meta.url);
|
|
|
1337
1351
|
var __dirname2 = path.dirname(__filename2);
|
|
1338
1352
|
var PACKAGE_ROOT = path.resolve(__dirname2, "../../");
|
|
1339
1353
|
var IS_DEV = process.cwd() === PACKAGE_ROOT;
|
|
1340
|
-
var DATABASES_DIR = path.join(process.cwd(), "generated");
|
|
1341
1354
|
var AST_RUNTIME_CONSTANTS = {
|
|
1342
1355
|
NOTION_API_VERSION: "2025-09-03",
|
|
1343
1356
|
PACKAGE_LOG_PREFIX: "[@elumixor/notion-orm]",
|
|
@@ -1346,6 +1359,16 @@ var AST_RUNTIME_CONSTANTS = {
|
|
|
1346
1359
|
SCHEMA_DRIFT_HELP_MESSAGE: "Run `notion generate` to refresh all database schemas."
|
|
1347
1360
|
};
|
|
1348
1361
|
|
|
1362
|
+
// src/helpers.ts
|
|
1363
|
+
function camelize(str) {
|
|
1364
|
+
const cleaned = str.replace(/[^a-zA-Z0-9\s]/g, "");
|
|
1365
|
+
return cleaned.replace(/(?:^\w|[A-Z]|\b\w|\s+)/g, function(match, index) {
|
|
1366
|
+
if (+match === 0)
|
|
1367
|
+
return "";
|
|
1368
|
+
return index === 0 ? match.toLowerCase() : match.toUpperCase();
|
|
1369
|
+
});
|
|
1370
|
+
}
|
|
1371
|
+
|
|
1349
1372
|
// src/db-client/add.ts
|
|
1350
1373
|
function buildPropertyValueForAddPage(args) {
|
|
1351
1374
|
const { type, value } = args;
|
|
@@ -1441,18 +1464,8 @@ var emailCall = (args) => {
|
|
|
1441
1464
|
return { email: value };
|
|
1442
1465
|
};
|
|
1443
1466
|
|
|
1444
|
-
// src/helpers.ts
|
|
1445
|
-
function camelize(str) {
|
|
1446
|
-
const cleaned = str.replace(/[^a-zA-Z0-9\s]/g, "");
|
|
1447
|
-
return cleaned.replace(/(?:^\w|[A-Z]|\b\w|\s+)/g, function(match, index) {
|
|
1448
|
-
if (+match === 0)
|
|
1449
|
-
return "";
|
|
1450
|
-
return index === 0 ? match.toLowerCase() : match.toUpperCase();
|
|
1451
|
-
});
|
|
1452
|
-
}
|
|
1453
|
-
|
|
1454
1467
|
// src/db-client/query.ts
|
|
1455
|
-
function buildQueryResponse(res, camelPropertyNameToNameAndTypeMap, validateSchema) {
|
|
1468
|
+
function buildQueryResponse(res, camelPropertyNameToNameAndTypeMap, validateSchema, meta) {
|
|
1456
1469
|
const results = res.results.map((result, index) => {
|
|
1457
1470
|
if (result.object === "page" && !("properties" in result)) {
|
|
1458
1471
|
console.log("Skipping this page: ", { result });
|
|
@@ -1467,6 +1480,24 @@ function buildQueryResponse(res, camelPropertyNameToNameAndTypeMap, validateSche
|
|
|
1467
1480
|
simpleResult[camelizeColumnName] = getResponseValue(columnType, result2);
|
|
1468
1481
|
}
|
|
1469
1482
|
}
|
|
1483
|
+
if (meta?.$icon) {
|
|
1484
|
+
const icon = result.icon;
|
|
1485
|
+
if (icon?.type === "external")
|
|
1486
|
+
simpleResult.$icon = icon.external?.url ?? null;
|
|
1487
|
+
else if (icon?.type === "file")
|
|
1488
|
+
simpleResult.$icon = icon.file?.url ?? null;
|
|
1489
|
+
else
|
|
1490
|
+
simpleResult.$icon = null;
|
|
1491
|
+
}
|
|
1492
|
+
if (meta?.$cover) {
|
|
1493
|
+
const cover = result.cover;
|
|
1494
|
+
if (cover?.type === "external")
|
|
1495
|
+
simpleResult.$cover = cover.external?.url ?? null;
|
|
1496
|
+
else if (cover?.type === "file")
|
|
1497
|
+
simpleResult.$cover = cover.file?.url ?? null;
|
|
1498
|
+
else
|
|
1499
|
+
simpleResult.$cover = null;
|
|
1500
|
+
}
|
|
1470
1501
|
if (index === 0) {
|
|
1471
1502
|
validateSchema(simpleResult);
|
|
1472
1503
|
}
|
|
@@ -1582,7 +1613,7 @@ function recursivelyBuildFilter(queryFilter, camelPropertyNameToNameAndTypeMap)
|
|
|
1582
1613
|
}
|
|
1583
1614
|
}
|
|
1584
1615
|
|
|
1585
|
-
// src/db-client/
|
|
1616
|
+
// src/db-client/client.ts
|
|
1586
1617
|
class DatabaseClient {
|
|
1587
1618
|
client;
|
|
1588
1619
|
id;
|
|
@@ -1603,103 +1634,201 @@ class DatabaseClient {
|
|
|
1603
1634
|
this.name = args.name;
|
|
1604
1635
|
this.loggedSchemaValidationIssues = new Set;
|
|
1605
1636
|
}
|
|
1606
|
-
|
|
1607
|
-
const
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
const columnObject = buildPropertyValueForAddPage({
|
|
1619
|
-
type,
|
|
1620
|
-
value
|
|
1621
|
-
});
|
|
1622
|
-
if (callBody.properties && columnObject) {
|
|
1623
|
-
callBody.properties[columnName] = columnObject;
|
|
1624
|
-
}
|
|
1637
|
+
findMany(args = {}) {
|
|
1638
|
+
const queryCall = this.buildQueryCall(args);
|
|
1639
|
+
if (args.stream)
|
|
1640
|
+
return this.streamingIterable(queryCall, args);
|
|
1641
|
+
return this.fetchAllPages(queryCall, args);
|
|
1642
|
+
}
|
|
1643
|
+
async paginate(args) {
|
|
1644
|
+
const queryCall = this.buildQueryCall(args ?? {});
|
|
1645
|
+
const response = await this.client.dataSources.query({
|
|
1646
|
+
...queryCall,
|
|
1647
|
+
page_size: args?.take ?? 100,
|
|
1648
|
+
start_cursor: args?.after
|
|
1625
1649
|
});
|
|
1626
|
-
|
|
1650
|
+
const results = buildQueryResponse(response, this.camelPropertyNameToNameAndTypeMap, (r) => this.validateDatabaseSchema(r), { $icon: args?.$icon, $cover: args?.$cover });
|
|
1651
|
+
return {
|
|
1652
|
+
data: this.applySelectOmit(results, args?.select, args?.omit),
|
|
1653
|
+
nextCursor: response.has_more ? response.next_cursor ?? null : null,
|
|
1654
|
+
hasMore: response.has_more
|
|
1655
|
+
};
|
|
1627
1656
|
}
|
|
1628
|
-
async
|
|
1629
|
-
const
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1657
|
+
async findFirst(args) {
|
|
1658
|
+
const queryCall = this.buildQueryCall(args ?? {});
|
|
1659
|
+
const response = await this.client.dataSources.query({ ...queryCall, page_size: 1 });
|
|
1660
|
+
const results = buildQueryResponse(response, this.camelPropertyNameToNameAndTypeMap, (r) => this.validateDatabaseSchema(r), { $icon: args?.$icon, $cover: args?.$cover });
|
|
1661
|
+
if (results.length === 0)
|
|
1662
|
+
return null;
|
|
1663
|
+
const [item] = this.applySelectOmit(results, args?.select, args?.omit);
|
|
1664
|
+
return item ?? null;
|
|
1665
|
+
}
|
|
1666
|
+
async findUnique(args) {
|
|
1667
|
+
try {
|
|
1668
|
+
const page = await this.client.pages.retrieve({ page_id: args.where.id });
|
|
1669
|
+
if (!("properties" in page))
|
|
1670
|
+
return null;
|
|
1671
|
+
const result = this.parsePage(page, { $icon: args.$icon, $cover: args.$cover });
|
|
1672
|
+
const [item] = this.applySelectOmit([result], args.select, args.omit);
|
|
1673
|
+
return item ?? null;
|
|
1674
|
+
} catch {
|
|
1675
|
+
return null;
|
|
1676
|
+
}
|
|
1677
|
+
}
|
|
1678
|
+
async create(args) {
|
|
1679
|
+
const callBody = this.buildCreateBody(args.data, args.$icon, args.$cover);
|
|
1680
|
+
const page = await this.client.pages.create(callBody);
|
|
1681
|
+
return this.parsePage(page);
|
|
1682
|
+
}
|
|
1683
|
+
async createMany(args) {
|
|
1684
|
+
return Promise.all(args.data.map((data) => this.create({ data, $icon: args.$icon, $cover: args.$cover })));
|
|
1685
|
+
}
|
|
1686
|
+
async update(args) {
|
|
1687
|
+
const callBody = { page_id: args.where.id, properties: {} };
|
|
1688
|
+
if (args.$icon !== undefined)
|
|
1689
|
+
callBody.icon = { type: "external", external: { url: args.$icon } };
|
|
1690
|
+
if (args.$cover !== undefined)
|
|
1691
|
+
callBody.cover = { type: "external", external: { url: args.$cover } };
|
|
1692
|
+
for (const [propertyName, value] of Object.entries(args.data)) {
|
|
1633
1693
|
const { type, columnName } = this.camelPropertyNameToNameAndTypeMap[propertyName];
|
|
1634
1694
|
const columnObject = buildPropertyValueForAddPage({ type, value });
|
|
1635
|
-
if (callBody.properties && columnObject)
|
|
1695
|
+
if (callBody.properties && columnObject)
|
|
1636
1696
|
callBody.properties[columnName] = columnObject;
|
|
1637
|
-
|
|
1638
|
-
});
|
|
1697
|
+
}
|
|
1639
1698
|
await this.client.pages.update(callBody);
|
|
1640
1699
|
}
|
|
1641
|
-
async
|
|
1642
|
-
|
|
1700
|
+
async updateMany(args) {
|
|
1701
|
+
const queryCall = this.buildQueryCall({ where: args.where });
|
|
1702
|
+
const results = await this.fetchAllPages(queryCall, {});
|
|
1703
|
+
await Promise.all(results.map((r) => this.update({ where: { id: r.id }, data: args.data, $icon: args.$icon, $cover: args.$cover })));
|
|
1704
|
+
return { count: results.length };
|
|
1643
1705
|
}
|
|
1644
1706
|
async upsert(args) {
|
|
1645
|
-
const queryCall = this.buildQueryCall({
|
|
1707
|
+
const queryCall = this.buildQueryCall({ where: args.where });
|
|
1646
1708
|
const response = await this.client.dataSources.query({ ...queryCall, page_size: 1 });
|
|
1647
1709
|
if (response.results.length > 0) {
|
|
1648
1710
|
const existingId = response.results[0].id;
|
|
1649
|
-
await this.update(existingId, args.
|
|
1711
|
+
await this.update({ where: { id: existingId }, data: args.update, $icon: args.$icon, $cover: args.$cover });
|
|
1650
1712
|
return { created: false, id: existingId };
|
|
1651
1713
|
}
|
|
1652
|
-
const created = await this.
|
|
1714
|
+
const created = await this.create({ data: args.create, $icon: args.$icon, $cover: args.$cover });
|
|
1653
1715
|
return { created: true, id: created.id };
|
|
1654
1716
|
}
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1717
|
+
async delete(args) {
|
|
1718
|
+
await this.client.pages.update({ page_id: args.where.id, archived: true });
|
|
1719
|
+
}
|
|
1720
|
+
async deleteMany(args) {
|
|
1721
|
+
const queryCall = this.buildQueryCall({ where: args?.where });
|
|
1722
|
+
const results = await this.fetchAllPages(queryCall, {});
|
|
1723
|
+
await Promise.all(results.map((r) => this.delete({ where: { id: r.id } })));
|
|
1724
|
+
return { count: results.length };
|
|
1660
1725
|
}
|
|
1661
|
-
|
|
1726
|
+
async count(args) {
|
|
1727
|
+
const queryCall = this.buildQueryCall({ where: args?.where });
|
|
1728
|
+
const results = await this.fetchAllPages(queryCall, {});
|
|
1729
|
+
return results.length;
|
|
1730
|
+
}
|
|
1731
|
+
buildCreateBody(data, $icon, $cover) {
|
|
1732
|
+
const callBody = {
|
|
1733
|
+
parent: { data_source_id: this.id, type: "data_source_id" },
|
|
1734
|
+
properties: {}
|
|
1735
|
+
};
|
|
1736
|
+
if ($icon)
|
|
1737
|
+
callBody.icon = { type: "external", external: { url: $icon } };
|
|
1738
|
+
if ($cover)
|
|
1739
|
+
callBody.cover = { type: "external", external: { url: $cover } };
|
|
1740
|
+
for (const [propertyName, value] of Object.entries(data)) {
|
|
1741
|
+
const { type, columnName } = this.camelPropertyNameToNameAndTypeMap[propertyName];
|
|
1742
|
+
const columnObject = buildPropertyValueForAddPage({ type, value });
|
|
1743
|
+
if (callBody.properties && columnObject)
|
|
1744
|
+
callBody.properties[columnName] = columnObject;
|
|
1745
|
+
}
|
|
1746
|
+
return callBody;
|
|
1747
|
+
}
|
|
1748
|
+
parsePage(page, meta) {
|
|
1749
|
+
const result = { id: page.id };
|
|
1750
|
+
for (const [columnName, value] of Object.entries(page.properties)) {
|
|
1751
|
+
const camelName = camelize(columnName);
|
|
1752
|
+
const colType = this.camelPropertyNameToNameAndTypeMap[camelName]?.type;
|
|
1753
|
+
if (colType)
|
|
1754
|
+
result[camelName] = getResponseValue(colType, value);
|
|
1755
|
+
}
|
|
1756
|
+
if (meta?.$icon) {
|
|
1757
|
+
if (page.icon?.type === "external")
|
|
1758
|
+
result.$icon = page.icon.external?.url ?? null;
|
|
1759
|
+
else if (page.icon?.type === "file")
|
|
1760
|
+
result.$icon = page.icon.file?.url ?? null;
|
|
1761
|
+
else
|
|
1762
|
+
result.$icon = null;
|
|
1763
|
+
}
|
|
1764
|
+
if (meta?.$cover) {
|
|
1765
|
+
if (page.cover?.type === "external")
|
|
1766
|
+
result.$cover = page.cover.external?.url ?? null;
|
|
1767
|
+
else if (page.cover?.type === "file")
|
|
1768
|
+
result.$cover = page.cover.file?.url ?? null;
|
|
1769
|
+
else
|
|
1770
|
+
result.$cover = null;
|
|
1771
|
+
}
|
|
1772
|
+
return result;
|
|
1773
|
+
}
|
|
1774
|
+
buildQueryCall(args) {
|
|
1662
1775
|
const queryCall = { data_source_id: this.id };
|
|
1663
|
-
if (
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
});
|
|
1776
|
+
if (args.orderBy) {
|
|
1777
|
+
const orderByArr = Array.isArray(args.orderBy) ? args.orderBy : [args.orderBy];
|
|
1778
|
+
queryCall["sorts"] = orderByArr.flatMap((obj) => Object.entries(obj).map(([prop, dir]) => ({
|
|
1779
|
+
property: this.camelPropertyNameToNameAndTypeMap[prop]?.columnName ?? prop,
|
|
1780
|
+
direction: dir === "asc" ? "ascending" : "descending"
|
|
1781
|
+
})));
|
|
1669
1782
|
}
|
|
1670
|
-
if (
|
|
1671
|
-
queryCall["filter"] = recursivelyBuildFilter(
|
|
1783
|
+
if (args.where) {
|
|
1784
|
+
queryCall["filter"] = recursivelyBuildFilter(args.where, this.camelPropertyNameToNameAndTypeMap);
|
|
1672
1785
|
}
|
|
1673
1786
|
return queryCall;
|
|
1674
1787
|
}
|
|
1675
|
-
async fetchAllPages(queryCall,
|
|
1788
|
+
async fetchAllPages(queryCall, args) {
|
|
1676
1789
|
const allResults = [];
|
|
1677
1790
|
let cursor;
|
|
1678
1791
|
let isFirst = true;
|
|
1792
|
+
const take = args.take;
|
|
1793
|
+
const skip = args.skip ?? 0;
|
|
1794
|
+
let fetched = 0;
|
|
1679
1795
|
do {
|
|
1680
1796
|
const response = await this.client.dataSources.query({ ...queryCall, start_cursor: cursor, page_size: 100 });
|
|
1681
|
-
const page = buildQueryResponse(response, this.camelPropertyNameToNameAndTypeMap, isFirst ? (r) => this.validateDatabaseSchema(r) : () => {});
|
|
1797
|
+
const page = buildQueryResponse(response, this.camelPropertyNameToNameAndTypeMap, isFirst ? (r) => this.validateDatabaseSchema(r) : () => {}, { $icon: args.$icon, $cover: args.$cover });
|
|
1682
1798
|
isFirst = false;
|
|
1683
|
-
|
|
1799
|
+
for (const item of this.applySelectOmit(page, args.select, args.omit)) {
|
|
1800
|
+
fetched++;
|
|
1801
|
+
if (fetched <= skip)
|
|
1802
|
+
continue;
|
|
1803
|
+
allResults.push(item);
|
|
1804
|
+
if (take && allResults.length >= take)
|
|
1805
|
+
return allResults;
|
|
1806
|
+
}
|
|
1684
1807
|
cursor = response.has_more ? response.next_cursor ?? undefined : undefined;
|
|
1685
|
-
} while (cursor
|
|
1686
|
-
return
|
|
1808
|
+
} while (cursor);
|
|
1809
|
+
return allResults;
|
|
1687
1810
|
}
|
|
1688
|
-
|
|
1811
|
+
streamingIterable(queryCall, args) {
|
|
1689
1812
|
const self = this;
|
|
1690
|
-
const pageSize =
|
|
1813
|
+
const pageSize = args.stream;
|
|
1691
1814
|
return {
|
|
1692
1815
|
[Symbol.asyncIterator]: async function* () {
|
|
1693
1816
|
let cursor;
|
|
1694
1817
|
let isFirst = true;
|
|
1695
1818
|
let yielded = 0;
|
|
1819
|
+
let skipped = 0;
|
|
1820
|
+
const skip = args.skip ?? 0;
|
|
1696
1821
|
do {
|
|
1697
1822
|
const response = await self.client.dataSources.query({ ...queryCall, start_cursor: cursor, page_size: pageSize });
|
|
1698
|
-
const page = buildQueryResponse(response, self.camelPropertyNameToNameAndTypeMap, isFirst ? (r) => self.validateDatabaseSchema(r) : () => {});
|
|
1823
|
+
const page = buildQueryResponse(response, self.camelPropertyNameToNameAndTypeMap, isFirst ? (r) => self.validateDatabaseSchema(r) : () => {}, { $icon: args.$icon, $cover: args.$cover });
|
|
1699
1824
|
isFirst = false;
|
|
1700
|
-
for (const item of self.applySelectOmit(page,
|
|
1825
|
+
for (const item of self.applySelectOmit(page, args.select, args.omit)) {
|
|
1826
|
+
if (skipped < skip) {
|
|
1827
|
+
skipped++;
|
|
1828
|
+
continue;
|
|
1829
|
+
}
|
|
1701
1830
|
yield item;
|
|
1702
|
-
if (
|
|
1831
|
+
if (args.take && ++yielded >= args.take)
|
|
1703
1832
|
return;
|
|
1704
1833
|
}
|
|
1705
1834
|
cursor = response.has_more ? response.next_cursor ?? undefined : undefined;
|
|
@@ -1725,22 +1854,17 @@ class DatabaseClient {
|
|
|
1725
1854
|
});
|
|
1726
1855
|
}
|
|
1727
1856
|
validateDatabaseSchema(result) {
|
|
1728
|
-
if (!this.schema)
|
|
1857
|
+
if (!this.schema)
|
|
1729
1858
|
return;
|
|
1730
|
-
}
|
|
1731
1859
|
const schemaLabel = this.name ?? this.id;
|
|
1732
1860
|
const remoteColumnNames = new Set(Object.keys(result));
|
|
1733
1861
|
const missingProperties = [];
|
|
1734
1862
|
for (const propName in this.camelPropertyNameToNameAndTypeMap) {
|
|
1735
|
-
if (!remoteColumnNames.has(propName))
|
|
1863
|
+
if (!remoteColumnNames.has(propName))
|
|
1736
1864
|
missingProperties.push(propName);
|
|
1737
|
-
}
|
|
1738
1865
|
}
|
|
1739
1866
|
if (missingProperties.length > 0) {
|
|
1740
|
-
const issueSignature2 = JSON.stringify({
|
|
1741
|
-
type: "missing_properties",
|
|
1742
|
-
properties: missingProperties
|
|
1743
|
-
});
|
|
1867
|
+
const issueSignature2 = JSON.stringify({ type: "missing_properties", properties: missingProperties });
|
|
1744
1868
|
if (!this.loggedSchemaValidationIssues.has(issueSignature2)) {
|
|
1745
1869
|
this.loggedSchemaValidationIssues.add(issueSignature2);
|
|
1746
1870
|
console.error(`⚠️ ${AST_RUNTIME_CONSTANTS.PACKAGE_LOG_PREFIX} ${AST_RUNTIME_CONSTANTS.SCHEMA_DRIFT_PREFIX} for the following Notion database ${schemaLabel}
|
|
@@ -1756,10 +1880,7 @@ Missing properties: ${missingProperties.map((prop) => `\`${prop}\``).join(", ")}
|
|
|
1756
1880
|
if (remoteColName === "id")
|
|
1757
1881
|
continue;
|
|
1758
1882
|
if (!this.camelPropertyNameToNameAndTypeMap[remoteColName]) {
|
|
1759
|
-
const issueSignature2 = JSON.stringify({
|
|
1760
|
-
type: "unexpected_property",
|
|
1761
|
-
property: remoteColName
|
|
1762
|
-
});
|
|
1883
|
+
const issueSignature2 = JSON.stringify({ type: "unexpected_property", property: remoteColName });
|
|
1763
1884
|
if (!this.loggedSchemaValidationIssues.has(issueSignature2)) {
|
|
1764
1885
|
this.loggedSchemaValidationIssues.add(issueSignature2);
|
|
1765
1886
|
console.error(`⚠️ ${AST_RUNTIME_CONSTANTS.PACKAGE_LOG_PREFIX} ${AST_RUNTIME_CONSTANTS.SCHEMA_DRIFT_PREFIX} for the following Notion database ${schemaLabel}
|
|
@@ -1773,17 +1894,11 @@ Unexpected property found in remote data: \`${remoteColName}\`
|
|
|
1773
1894
|
}
|
|
1774
1895
|
}
|
|
1775
1896
|
const parseResult = this.schema.safeParse(result);
|
|
1776
|
-
if (parseResult.success)
|
|
1897
|
+
if (parseResult.success)
|
|
1777
1898
|
return;
|
|
1778
|
-
}
|
|
1779
|
-
|
|
1780
|
-
code: issue.code,
|
|
1781
|
-
path: issue.path,
|
|
1782
|
-
message: issue.message
|
|
1783
|
-
})));
|
|
1784
|
-
if (this.loggedSchemaValidationIssues.has(issueSignature)) {
|
|
1899
|
+
const issueSignature = JSON.stringify(parseResult.error.issues.map((issue) => ({ code: issue.code, path: issue.path, message: issue.message })));
|
|
1900
|
+
if (this.loggedSchemaValidationIssues.has(issueSignature))
|
|
1785
1901
|
return;
|
|
1786
|
-
}
|
|
1787
1902
|
this.loggedSchemaValidationIssues.add(issueSignature);
|
|
1788
1903
|
console.error(`⚠️ ${AST_RUNTIME_CONSTANTS.PACKAGE_LOG_PREFIX} ${AST_RUNTIME_CONSTANTS.SCHEMA_DRIFT_PREFIX} for the following Notion database ${schemaLabel}
|
|
1789
1904
|
|
|
@@ -1792,10 +1907,7 @@ Validation issues: ${parseResult.error.issues.map((issue) => `\`${issue.path.joi
|
|
|
1792
1907
|
|
|
1793
1908
|
✅ ${AST_RUNTIME_CONSTANTS.SCHEMA_DRIFT_HELP_MESSAGE}
|
|
1794
1909
|
`);
|
|
1795
|
-
console.log("Validation details:", {
|
|
1796
|
-
issues: parseResult.error.issues,
|
|
1797
|
-
result
|
|
1798
|
-
});
|
|
1910
|
+
console.log("Validation details:", { issues: parseResult.error.issues, result });
|
|
1799
1911
|
}
|
|
1800
1912
|
}
|
|
1801
1913
|
export {
|
package/dist/public-api.d.ts
CHANGED
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
* Public API entry point for @elumixor/notion-orm.
|
|
3
3
|
* External users' generated files import DatabaseClient and types from here.
|
|
4
4
|
*/
|
|
5
|
-
export { DatabaseClient } from "./db-client/
|
|
6
|
-
export type { Query, QueryResult, QueryResultType, SupportedNotionColumnType } from "./db-client/
|
|
5
|
+
export { DatabaseClient } from "./db-client/client";
|
|
6
|
+
export type { FindManyArgs, PaginateArgs, Query, QueryFilter, QueryResult, QueryResultType, OrderByInput, SupportedNotionColumnType, } from "./db-client/types";
|
|
7
7
|
export type { NotionConfigType } from "./config/helpers";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elumixor/notion-orm",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Bring Notion database schemas/types to TypeScript",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@notionhq/client": "5.3.0",
|
|
32
|
+
"ora": "^9.3.0",
|
|
32
33
|
"typescript": "^5.6.3",
|
|
33
34
|
"zod": "^3.23.8"
|
|
34
35
|
},
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import type { CreatePageParameters, CreatePageResponse, UpdatePageParameters } from "@notionhq/client/build/src/api-endpoints";
|
|
2
|
-
import type { ZodTypeAny } from "zod";
|
|
3
|
-
import type { Query, QueryFilter, QueryResultType, SupportedNotionColumnType } from "./queryTypes";
|
|
4
|
-
export type camelPropertyNameToNameAndTypeMapType = Record<string, {
|
|
5
|
-
columnName: string;
|
|
6
|
-
type: SupportedNotionColumnType;
|
|
7
|
-
}>;
|
|
8
|
-
export declare class DatabaseClient<DatabaseSchemaType extends Record<string, any>, ColumnNameToColumnType extends Record<keyof DatabaseSchemaType, SupportedNotionColumnType>> {
|
|
9
|
-
private client;
|
|
10
|
-
private id;
|
|
11
|
-
private camelPropertyNameToNameAndTypeMap;
|
|
12
|
-
private schema;
|
|
13
|
-
name: string;
|
|
14
|
-
private loggedSchemaValidationIssues;
|
|
15
|
-
constructor(args: {
|
|
16
|
-
id: string;
|
|
17
|
-
camelPropertyNameToNameAndTypeMap: camelPropertyNameToNameAndTypeMapType;
|
|
18
|
-
auth: string;
|
|
19
|
-
name: string;
|
|
20
|
-
schema: ZodTypeAny;
|
|
21
|
-
});
|
|
22
|
-
add(args: {
|
|
23
|
-
properties: DatabaseSchemaType;
|
|
24
|
-
icon?: CreatePageParameters["icon"];
|
|
25
|
-
}): Promise<CreatePageParameters | CreatePageResponse>;
|
|
26
|
-
update(id: string, properties: Partial<DatabaseSchemaType>, icon?: UpdatePageParameters["icon"]): Promise<void>;
|
|
27
|
-
delete(id: string): Promise<void>;
|
|
28
|
-
upsert(args: {
|
|
29
|
-
where: QueryFilter<DatabaseSchemaType, ColumnNameToColumnType>;
|
|
30
|
-
properties: DatabaseSchemaType;
|
|
31
|
-
icon?: CreatePageParameters["icon"];
|
|
32
|
-
}): Promise<{
|
|
33
|
-
created: boolean;
|
|
34
|
-
id: string;
|
|
35
|
-
}>;
|
|
36
|
-
query<Args extends Query<DatabaseSchemaType, ColumnNameToColumnType> & {
|
|
37
|
-
pagination: {
|
|
38
|
-
pageSize: number;
|
|
39
|
-
};
|
|
40
|
-
}>(query: Args): AsyncIterable<QueryResultType<DatabaseSchemaType, Args>>;
|
|
41
|
-
query<Args extends Omit<Query<DatabaseSchemaType, ColumnNameToColumnType>, "pagination">>(query: Args): Promise<QueryResultType<DatabaseSchemaType, Args>[]>;
|
|
42
|
-
private buildQueryCall;
|
|
43
|
-
private fetchAllPages;
|
|
44
|
-
private paginatedIterable;
|
|
45
|
-
private applySelectOmit;
|
|
46
|
-
private validateDatabaseSchema;
|
|
47
|
-
}
|