@datawheel/bespoke 0.1.18 → 0.1.19
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/index.css +0 -133
- package/dist/index.js +497 -259
- package/dist/server.js +265 -95
- package/package.json +2 -1
package/dist/server.js
CHANGED
|
@@ -23,6 +23,7 @@ import auth0 from 'auth0';
|
|
|
23
23
|
import NextCors from 'nextjs-cors';
|
|
24
24
|
import formidable from 'formidable';
|
|
25
25
|
import glob from 'fast-glob';
|
|
26
|
+
import toposort from 'toposort';
|
|
26
27
|
import { schema, normalize } from 'normalizr';
|
|
27
28
|
import { createSlice, configureStore } from '@reduxjs/toolkit';
|
|
28
29
|
import { HYDRATE, createWrapper } from 'next-redux-wrapper';
|
|
@@ -53,7 +54,6 @@ var afterRefetch = async (req, res, session) => {
|
|
|
53
54
|
return session;
|
|
54
55
|
};
|
|
55
56
|
var fetchMe = async (req, res, refetch) => {
|
|
56
|
-
console.log("fetchMe: refetch?", refetch);
|
|
57
57
|
return await getAuth_default.handleProfile(req, res, { afterRefetch, refetch });
|
|
58
58
|
};
|
|
59
59
|
var handleAuth_default = getAuth_default.handleAuth({
|
|
@@ -67,12 +67,15 @@ var handleAuth_default = getAuth_default.handleAuth({
|
|
|
67
67
|
}
|
|
68
68
|
});
|
|
69
69
|
|
|
70
|
+
// libs/js/arrayUtils.ts
|
|
71
|
+
var keyDiver = (obj, str) => !str ? obj : typeof str === "string" ? str.split(".").reduce((o, i) => o[i], obj) : obj;
|
|
72
|
+
function arrContainsAnyItem(arr1, arr2) {
|
|
73
|
+
return arr1.some((item) => arr2.includes(item));
|
|
74
|
+
}
|
|
75
|
+
|
|
70
76
|
// api/auth/withApiRoleAuthRequired.tsx
|
|
71
77
|
var withApiRoleAuthRequired = (apiRoute, allowedRoles) => {
|
|
72
78
|
return async function(req, res) {
|
|
73
|
-
function arrContains(arr1, arr2) {
|
|
74
|
-
return arr1.some((item) => arr2.includes(item));
|
|
75
|
-
}
|
|
76
79
|
const session = await getAuth_default.getSession(req, res);
|
|
77
80
|
if (!session || !session.user) {
|
|
78
81
|
res.status(401).json({
|
|
@@ -82,7 +85,7 @@ var withApiRoleAuthRequired = (apiRoute, allowedRoles) => {
|
|
|
82
85
|
return;
|
|
83
86
|
}
|
|
84
87
|
const usersRoles = session.user.bespoke_roles;
|
|
85
|
-
if (allowedRoles.length > 0 && !
|
|
88
|
+
if (allowedRoles.length > 0 && !arrContainsAnyItem(usersRoles, allowedRoles)) {
|
|
86
89
|
res.status(402).json({
|
|
87
90
|
error: "unauthorize",
|
|
88
91
|
description: "The user requires some specific roles"
|
|
@@ -1661,13 +1664,20 @@ if (!connectionString) {
|
|
|
1661
1664
|
var getDB = () => {
|
|
1662
1665
|
if (!global.sequelize) {
|
|
1663
1666
|
if (verbose2)
|
|
1664
|
-
console.log("INITIALIZING DB CONNECTION");
|
|
1667
|
+
console.log("\u{1F511} INITIALIZING DB CONNECTION");
|
|
1665
1668
|
let sequelize;
|
|
1666
1669
|
try {
|
|
1667
1670
|
sequelize = new Sequelize(connectionString, {
|
|
1668
1671
|
// logging: verbose ? console.log : false,
|
|
1669
1672
|
logging: false,
|
|
1670
|
-
dialectModule: pg
|
|
1673
|
+
dialectModule: pg,
|
|
1674
|
+
pool: {
|
|
1675
|
+
max: 10,
|
|
1676
|
+
min: 1,
|
|
1677
|
+
acquire: 5 * 1e3,
|
|
1678
|
+
idle: 10 * 1e3,
|
|
1679
|
+
evict: 1 * 1e3
|
|
1680
|
+
}
|
|
1671
1681
|
});
|
|
1672
1682
|
} catch (e) {
|
|
1673
1683
|
throw new Error(`
|
|
@@ -1690,7 +1700,7 @@ var getDB = () => {
|
|
|
1690
1700
|
}).then(() => sequelize.models);
|
|
1691
1701
|
} else {
|
|
1692
1702
|
if (verbose2)
|
|
1693
|
-
console.log("RE-UTILIZING DB CONNECTION");
|
|
1703
|
+
console.log("\u267B\uFE0F RE-UTILIZING DB CONNECTION");
|
|
1694
1704
|
}
|
|
1695
1705
|
return global.sequelize;
|
|
1696
1706
|
};
|
|
@@ -1734,9 +1744,6 @@ var getLocales_default = () => {
|
|
|
1734
1744
|
return { localeDefault: localeDefault10, locales: locales8 };
|
|
1735
1745
|
};
|
|
1736
1746
|
|
|
1737
|
-
// libs/js/arrayUtils.ts
|
|
1738
|
-
var keyDiver = (obj, str) => !str ? obj : typeof str === "string" ? str.split(".").reduce((o, i) => o[i], obj) : obj;
|
|
1739
|
-
|
|
1740
1747
|
// libs/js/stripHTML.ts
|
|
1741
1748
|
function stripHTML(n) {
|
|
1742
1749
|
const entities = {
|
|
@@ -2021,33 +2028,17 @@ function readMemberImageFactory(db) {
|
|
|
2021
2028
|
async function readMemberImage(params) {
|
|
2022
2029
|
const member = await Search.findOne({
|
|
2023
2030
|
where: { content_id: params.member },
|
|
2024
|
-
include: [
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
},
|
|
2032
|
-
{
|
|
2033
|
-
association: "report",
|
|
2034
|
-
attributes: ["id", "name"]
|
|
2035
|
-
},
|
|
2036
|
-
{
|
|
2037
|
-
association: "dimension",
|
|
2038
|
-
attributes: ["id", "name", "ordering"]
|
|
2039
|
-
},
|
|
2040
|
-
{
|
|
2041
|
-
association: "variant",
|
|
2042
|
-
attributes: ["id", "name", "slug"]
|
|
2043
|
-
}
|
|
2044
|
-
]
|
|
2031
|
+
include: [{
|
|
2032
|
+
association: "image",
|
|
2033
|
+
attributes: [params.size],
|
|
2034
|
+
include: [{
|
|
2035
|
+
association: "contentByLocale"
|
|
2036
|
+
}]
|
|
2037
|
+
}]
|
|
2045
2038
|
});
|
|
2046
|
-
if (member && member.image) {
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
return image;
|
|
2050
|
-
}
|
|
2039
|
+
if (member && member.image && member.image[params.size]) {
|
|
2040
|
+
const image = member.image[params.size];
|
|
2041
|
+
return image;
|
|
2051
2042
|
} else {
|
|
2052
2043
|
const emptyPixelImage = Buffer.from(
|
|
2053
2044
|
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkkAQAAB8AG7jymN8AAAAASUVORK5CYII=",
|
|
@@ -2055,7 +2046,6 @@ function readMemberImageFactory(db) {
|
|
|
2055
2046
|
);
|
|
2056
2047
|
return emptyPixelImage;
|
|
2057
2048
|
}
|
|
2058
|
-
throw new BackendError(404, "error in image, member not found");
|
|
2059
2049
|
}
|
|
2060
2050
|
}
|
|
2061
2051
|
lunrStemmer(lunr);
|
|
@@ -2084,26 +2074,20 @@ var whitelist = [
|
|
|
2084
2074
|
"vi",
|
|
2085
2075
|
"zh"
|
|
2086
2076
|
];
|
|
2087
|
-
|
|
2077
|
+
getLogging_default();
|
|
2088
2078
|
var { locales } = getLocales_default();
|
|
2089
2079
|
var enabledLocales = locales.filter((d) => whitelist.includes(d));
|
|
2090
2080
|
var initializing = false;
|
|
2091
2081
|
var getSearchIndexByLocale = async (db, forceRegenerate = false) => {
|
|
2092
2082
|
if (forceRegenerate) {
|
|
2093
|
-
if (verbose3)
|
|
2094
|
-
console.log("CLEARING SEARCH INDEX");
|
|
2095
2083
|
global.lunrsearch = void 0;
|
|
2096
2084
|
initializing = false;
|
|
2097
2085
|
}
|
|
2098
2086
|
if (global.lunrsearch) {
|
|
2099
|
-
if (verbose3)
|
|
2100
|
-
console.log("RE-UTILIZING SEARCH INDEX");
|
|
2101
2087
|
return global.lunrsearch;
|
|
2102
2088
|
}
|
|
2103
2089
|
try {
|
|
2104
2090
|
if (!initializing) {
|
|
2105
|
-
if (verbose3)
|
|
2106
|
-
console.log("INITIALIZING SEARCH INDEX");
|
|
2107
2091
|
initializing = true;
|
|
2108
2092
|
global.lunrsearch = await newSearchIndex(db);
|
|
2109
2093
|
}
|
|
@@ -3027,7 +3011,7 @@ function endpointMemberFactory(operations) {
|
|
|
3027
3011
|
endpoint("POST", "update/member", (req) => {
|
|
3028
3012
|
const { body } = req;
|
|
3029
3013
|
return updateMember(body);
|
|
3030
|
-
}, CMS_ROLES.EDITOR),
|
|
3014
|
+
}, [CMS_ROLES.EDITOR]),
|
|
3031
3015
|
/*
|
|
3032
3016
|
* Get image file itself
|
|
3033
3017
|
* Example queries:
|
|
@@ -3037,7 +3021,7 @@ function endpointMemberFactory(operations) {
|
|
|
3037
3021
|
const size = normalizeList(req.query.size)[0];
|
|
3038
3022
|
return readMemberImage({
|
|
3039
3023
|
member: parseFiniteNumber(req.query.member),
|
|
3040
|
-
size: size && size === "
|
|
3024
|
+
size: size && size === "splash" ? "splash" : "thumb"
|
|
3041
3025
|
});
|
|
3042
3026
|
})
|
|
3043
3027
|
];
|
|
@@ -3502,6 +3486,72 @@ function dbRevalidateFactory(db) {
|
|
|
3502
3486
|
}
|
|
3503
3487
|
};
|
|
3504
3488
|
}
|
|
3489
|
+
|
|
3490
|
+
// libs/blocks/crawlDown.ts
|
|
3491
|
+
function crawlDown(rootBlockIds, blockList) {
|
|
3492
|
+
let consumersBlocksIds = [];
|
|
3493
|
+
const crawlDownIndividual = (privateBlockId) => {
|
|
3494
|
+
const downIds = Object.values(blockList).reduce((acc, block) => {
|
|
3495
|
+
if ("inputs" in block && block.inputs.includes(privateBlockId)) {
|
|
3496
|
+
acc.push(block.id);
|
|
3497
|
+
acc = acc.concat(crawlDownIndividual(block.id));
|
|
3498
|
+
}
|
|
3499
|
+
return acc;
|
|
3500
|
+
}, []);
|
|
3501
|
+
return downIds;
|
|
3502
|
+
};
|
|
3503
|
+
rootBlockIds.forEach((rootBlockId) => {
|
|
3504
|
+
consumersBlocksIds = consumersBlocksIds.concat(crawlDownIndividual(rootBlockId));
|
|
3505
|
+
});
|
|
3506
|
+
const uniqueConsumerBlocksIds = [];
|
|
3507
|
+
consumersBlocksIds.forEach((id) => {
|
|
3508
|
+
if (!uniqueConsumerBlocksIds.includes(id)) {
|
|
3509
|
+
uniqueConsumerBlocksIds.push(id);
|
|
3510
|
+
}
|
|
3511
|
+
});
|
|
3512
|
+
return uniqueConsumerBlocksIds;
|
|
3513
|
+
}
|
|
3514
|
+
|
|
3515
|
+
// api/db/readPrivateBlocks.ts
|
|
3516
|
+
function accessContainsRole(arr1, arr2) {
|
|
3517
|
+
return arr1.some((item) => arr2.includes(`role.${item}`));
|
|
3518
|
+
}
|
|
3519
|
+
function dbReadPrivateBlocksFactory(db) {
|
|
3520
|
+
const { report: Report } = db;
|
|
3521
|
+
return dbReadPrivateBlocks;
|
|
3522
|
+
async function dbReadPrivateBlocks(params) {
|
|
3523
|
+
const allBlocks = await Report.findByPk(
|
|
3524
|
+
params.report_id,
|
|
3525
|
+
{
|
|
3526
|
+
include: reportQuery.include
|
|
3527
|
+
}
|
|
3528
|
+
).then((report) => {
|
|
3529
|
+
if (report && report.sections && Array.isArray(report.sections)) {
|
|
3530
|
+
return report.sections.reduce((acc, section) => {
|
|
3531
|
+
const nestedBlocks = section.blocks.map((entity) => {
|
|
3532
|
+
const normalized = entity.toJSON();
|
|
3533
|
+
normalized.inputs = normalized.inputs.map((b) => b.id);
|
|
3534
|
+
normalized.consumers = normalized.consumers.map((b) => b.id);
|
|
3535
|
+
return normalized;
|
|
3536
|
+
});
|
|
3537
|
+
return acc.concat(nestedBlocks);
|
|
3538
|
+
}, []);
|
|
3539
|
+
} else {
|
|
3540
|
+
return [];
|
|
3541
|
+
}
|
|
3542
|
+
});
|
|
3543
|
+
let privateBlockIds = allBlocks.filter((block) => {
|
|
3544
|
+
return block.settings && block.settings.access && Array.isArray(block.settings.access) && Array.isArray(params.roles) && (block.settings.access.includes("private") || accessContainsRole(params.roles, block.settings.access));
|
|
3545
|
+
}).map((block) => block.id);
|
|
3546
|
+
privateBlockIds = privateBlockIds.concat(crawlDown(privateBlockIds, allBlocks));
|
|
3547
|
+
return {
|
|
3548
|
+
params: {
|
|
3549
|
+
...params
|
|
3550
|
+
},
|
|
3551
|
+
data: allBlocks.filter((block) => privateBlockIds.includes(block.id))
|
|
3552
|
+
};
|
|
3553
|
+
}
|
|
3554
|
+
}
|
|
3505
3555
|
var auth0ConfigObject = {
|
|
3506
3556
|
domain: new URL(process.env.AUTH0_ISSUER_BASE_URL || "").host,
|
|
3507
3557
|
clientId: process.env.AUTH0_CLIENT_ID,
|
|
@@ -3642,7 +3692,8 @@ function apiFactory(dbModels) {
|
|
|
3642
3692
|
readUser: resultWrapper(dbReadUser()),
|
|
3643
3693
|
updateUser: resultWrapper(dbUpdateUser()),
|
|
3644
3694
|
addNewReportToCurrentUser: resultWrapper(dbAddNewReportToCurrentUser()),
|
|
3645
|
-
revalidate: resultWrapper(dbRevalidateFactory())
|
|
3695
|
+
revalidate: resultWrapper(dbRevalidateFactory()),
|
|
3696
|
+
readPrivateBlocks: resultWrapper(dbReadPrivateBlocksFactory(dbModels))
|
|
3646
3697
|
};
|
|
3647
3698
|
}
|
|
3648
3699
|
async function parseBody(req) {
|
|
@@ -3671,7 +3722,7 @@ function endpointCRUDFactory(api, entity) {
|
|
|
3671
3722
|
endpoint("POST", `create/${entity}`, (req) => {
|
|
3672
3723
|
const { body } = req;
|
|
3673
3724
|
return crudCreate(body);
|
|
3674
|
-
}, CMS_ROLES.EDITOR),
|
|
3725
|
+
}, [CMS_ROLES.EDITOR]),
|
|
3675
3726
|
endpoint("GET", `read/${entity}`, (req) => {
|
|
3676
3727
|
const params = req.query;
|
|
3677
3728
|
const id = normalizeList(params.id).map(parseFiniteNumber);
|
|
@@ -3680,11 +3731,11 @@ function endpointCRUDFactory(api, entity) {
|
|
|
3680
3731
|
endpoint("POST", `update/${entity}`, (req) => {
|
|
3681
3732
|
const { body } = req;
|
|
3682
3733
|
return crudUpdate(body);
|
|
3683
|
-
}, CMS_ROLES.EDITOR),
|
|
3734
|
+
}, [CMS_ROLES.EDITOR]),
|
|
3684
3735
|
endpoint("DELETE", `delete/${entity}`, (req) => {
|
|
3685
3736
|
const id = parseFiniteNumber(req.body.id);
|
|
3686
3737
|
return crudDelete(id);
|
|
3687
|
-
}, CMS_ROLES.EDITOR)
|
|
3738
|
+
}, [CMS_ROLES.EDITOR])
|
|
3688
3739
|
];
|
|
3689
3740
|
}
|
|
3690
3741
|
function endpointVariantCRUDFactory(api) {
|
|
@@ -3695,7 +3746,7 @@ function endpointVariantCRUDFactory(api) {
|
|
|
3695
3746
|
const params = req.query;
|
|
3696
3747
|
const dimension = parseFiniteNumber(params.dimension);
|
|
3697
3748
|
return validateVariantSlug({ dimension, slug: slugify_default(params.slug) });
|
|
3698
|
-
}, CMS_ROLES.EDITOR)
|
|
3749
|
+
}, [CMS_ROLES.EDITOR])
|
|
3699
3750
|
];
|
|
3700
3751
|
}
|
|
3701
3752
|
|
|
@@ -3712,7 +3763,7 @@ function endpointImageSaveFactory(operations, provider) {
|
|
|
3712
3763
|
throw new BackendError(400, "Missing 'image_id' parameter.");
|
|
3713
3764
|
}
|
|
3714
3765
|
return saveMethod(params);
|
|
3715
|
-
}, CMS_ROLES.EDITOR);
|
|
3766
|
+
}, [CMS_ROLES.EDITOR]);
|
|
3716
3767
|
}
|
|
3717
3768
|
|
|
3718
3769
|
// api/endpoints/image/imageSearch.ts
|
|
@@ -3725,7 +3776,7 @@ function endpointImageSearchFactory(operations, provider) {
|
|
|
3725
3776
|
throw new BackendError(400, "Empty 'prompt' param.");
|
|
3726
3777
|
}
|
|
3727
3778
|
return searchMethod({ prompt });
|
|
3728
|
-
}, CMS_ROLES.EDITOR);
|
|
3779
|
+
}, [CMS_ROLES.EDITOR]);
|
|
3729
3780
|
}
|
|
3730
3781
|
|
|
3731
3782
|
// api/endpoints/readMetadata.ts
|
|
@@ -3737,7 +3788,7 @@ function endpointReadMetadataFactory(operations) {
|
|
|
3737
3788
|
// api/endpoints/regenerateSearch.ts
|
|
3738
3789
|
function endpointRegenerateSearchFactory(operations) {
|
|
3739
3790
|
const { regenerateSearch } = operations;
|
|
3740
|
-
return endpoint("POST", "search/regenerate", () => regenerateSearch(void 0), CMS_ROLES.EDITOR);
|
|
3791
|
+
return endpoint("POST", "search/regenerate", () => regenerateSearch(void 0), [CMS_ROLES.EDITOR]);
|
|
3741
3792
|
}
|
|
3742
3793
|
|
|
3743
3794
|
// api/endpoints/searchReport.ts
|
|
@@ -3813,7 +3864,20 @@ function endpointRevalidateFactory(operations) {
|
|
|
3813
3864
|
console.log(err);
|
|
3814
3865
|
throw new BackendError(500, "Error revalidating");
|
|
3815
3866
|
}
|
|
3816
|
-
});
|
|
3867
|
+
}, [CMS_ROLES.EDITOR]);
|
|
3868
|
+
}
|
|
3869
|
+
|
|
3870
|
+
// api/endpoints/readPrivateBlocks.ts
|
|
3871
|
+
function endpointReadPrivateBlocksFactory(operations) {
|
|
3872
|
+
const { readPrivateBlocks: readPrivateBlocks2 } = operations;
|
|
3873
|
+
return endpoint("POST", "read/blocks/private", (req, res, session) => {
|
|
3874
|
+
const params = {
|
|
3875
|
+
report_id: parseInt(req.body.report_id, 10),
|
|
3876
|
+
locale: req.body.locale || "es",
|
|
3877
|
+
roles: session && session.user ? session.user.bespoke_roles : []
|
|
3878
|
+
};
|
|
3879
|
+
return readPrivateBlocks2(params);
|
|
3880
|
+
}, []);
|
|
3817
3881
|
}
|
|
3818
3882
|
|
|
3819
3883
|
// api/endpoints/users/auth0.ts
|
|
@@ -3821,7 +3885,7 @@ function endpointGetRolesFactory(operations) {
|
|
|
3821
3885
|
const { searchRole: searchRole2 } = operations;
|
|
3822
3886
|
return endpoint("GET", "auth/search/roles", () => {
|
|
3823
3887
|
return searchRole2("");
|
|
3824
|
-
}, CMS_ROLES.
|
|
3888
|
+
}, [CMS_ROLES.EDITOR]);
|
|
3825
3889
|
}
|
|
3826
3890
|
function endpointGetUsersFactory(operations) {
|
|
3827
3891
|
const { searchUser: searchUser2 } = operations;
|
|
@@ -3831,13 +3895,13 @@ function endpointGetUsersFactory(operations) {
|
|
|
3831
3895
|
role_id: req.query.role_id,
|
|
3832
3896
|
page: req.query.page || 0
|
|
3833
3897
|
});
|
|
3834
|
-
}, CMS_ROLES.ADMIN);
|
|
3898
|
+
}, [CMS_ROLES.ADMIN]);
|
|
3835
3899
|
}
|
|
3836
3900
|
function endpointGetUserDataFactory(operations) {
|
|
3837
3901
|
const { readUser: readUser2 } = operations;
|
|
3838
3902
|
return endpoint("GET", "auth/read/user", (req) => {
|
|
3839
3903
|
return readUser2(req.query.user_id);
|
|
3840
|
-
}, CMS_ROLES.ADMIN);
|
|
3904
|
+
}, [CMS_ROLES.ADMIN]);
|
|
3841
3905
|
}
|
|
3842
3906
|
function endpointUpdateUserDataFactory(operations) {
|
|
3843
3907
|
const { updateUser: updateUser2, readUser: readUser2 } = operations;
|
|
@@ -3858,7 +3922,7 @@ function endpointUpdateUserDataFactory(operations) {
|
|
|
3858
3922
|
}
|
|
3859
3923
|
}
|
|
3860
3924
|
return response;
|
|
3861
|
-
}, CMS_ROLES.ADMIN);
|
|
3925
|
+
}, [CMS_ROLES.ADMIN]);
|
|
3862
3926
|
}
|
|
3863
3927
|
function endpointAddNewReportToCurrentUserFactory(operations) {
|
|
3864
3928
|
const { updateUser: updateUser2, readUser: readUser2 } = operations;
|
|
@@ -3905,7 +3969,7 @@ function endpointAddNewReportToCurrentUserFactory(operations) {
|
|
|
3905
3969
|
error: error.message
|
|
3906
3970
|
};
|
|
3907
3971
|
}
|
|
3908
|
-
}, CMS_ROLES.EDITOR);
|
|
3972
|
+
}, [CMS_ROLES.EDITOR]);
|
|
3909
3973
|
}
|
|
3910
3974
|
|
|
3911
3975
|
// api/endpoints/index.ts
|
|
@@ -3939,7 +4003,8 @@ function getEndpointMap(db) {
|
|
|
3939
4003
|
endpointGetUserDataFactory(api),
|
|
3940
4004
|
endpointUpdateUserDataFactory(api),
|
|
3941
4005
|
endpointAddNewReportToCurrentUserFactory(api),
|
|
3942
|
-
endpointRevalidateFactory(api)
|
|
4006
|
+
endpointRevalidateFactory(api),
|
|
4007
|
+
endpointReadPrivateBlocksFactory(api)
|
|
3943
4008
|
].map(({ handler, method, path, roleRequired }) => [endpointKey(method, path), { handler, roleRequired }]));
|
|
3944
4009
|
}
|
|
3945
4010
|
var endpointMap = getDB().then(getEndpointMap);
|
|
@@ -3963,7 +4028,7 @@ async function endpointNextJsHandlerFactory(req, res) {
|
|
|
3963
4028
|
return res.status(401).json({ error: "Unauthorized. Must be logged in." });
|
|
3964
4029
|
}
|
|
3965
4030
|
const userRoles = session && session.user && session.user.bespoke_roles && Array.isArray(session.user.bespoke_roles) ? session.user.bespoke_roles : [];
|
|
3966
|
-
if (
|
|
4031
|
+
if (Array.isArray(handlerObj.roleRequired) && handlerObj.roleRequired.length > 0 && !arrContainsAnyItem(userRoles, handlerObj.roleRequired)) {
|
|
3967
4032
|
return res.status(402).json({ error: "Forbidden. Not enough roles." });
|
|
3968
4033
|
}
|
|
3969
4034
|
}
|
|
@@ -4009,6 +4074,7 @@ var crosswalk_default = reportsCrosswalkEntrypointFn;
|
|
|
4009
4074
|
// store/actions.ts
|
|
4010
4075
|
var actions_exports = {};
|
|
4011
4076
|
__export(actions_exports, {
|
|
4077
|
+
addBlockToState: () => addBlockToState,
|
|
4012
4078
|
addNewReportToCurrentUser: () => addNewReportToCurrentUser,
|
|
4013
4079
|
createEntity: () => createEntity,
|
|
4014
4080
|
deleteEntity: () => deleteEntity,
|
|
@@ -4016,8 +4082,10 @@ __export(actions_exports, {
|
|
|
4016
4082
|
readEntity: () => readEntity,
|
|
4017
4083
|
readMember: () => readMember,
|
|
4018
4084
|
readMetadata: () => readMetadata,
|
|
4085
|
+
readPrivateBlocks: () => readPrivateBlocks,
|
|
4019
4086
|
readUser: () => readUser,
|
|
4020
4087
|
recalculateVariables: () => recalculateVariables,
|
|
4088
|
+
removeBlocksFromState: () => removeBlocksFromState,
|
|
4021
4089
|
reportSearch: () => reportSearch,
|
|
4022
4090
|
searchMember: () => searchMember,
|
|
4023
4091
|
searchRegenerate: () => searchRegenerate,
|
|
@@ -4140,7 +4208,8 @@ function apiFactory2(baseURL) {
|
|
|
4140
4208
|
readUser: httpGET(axios6, "auth/read/user"),
|
|
4141
4209
|
updateUser: httpPOST(axios6, "auth/update/user"),
|
|
4142
4210
|
addNewReportToCurrentUser: httpPOST(axios6, "auth/update/me"),
|
|
4143
|
-
revalidate: httpGET(axios6, "revalidate/report")
|
|
4211
|
+
revalidate: httpGET(axios6, "revalidate/report"),
|
|
4212
|
+
readPrivateBlocks: httpPOST(axios6, "read/blocks/private")
|
|
4144
4213
|
};
|
|
4145
4214
|
}
|
|
4146
4215
|
var transformDeletePayload = (id) => ({ id });
|
|
@@ -4194,7 +4263,7 @@ function mortarEval(varInnerName, varOuterValue, logic, formatterFunctions, attr
|
|
|
4194
4263
|
if (typeof output === "object" && Object.keys(output).length > 0) {
|
|
4195
4264
|
Object.assign(vars, output);
|
|
4196
4265
|
}
|
|
4197
|
-
return { vars, error: null, log };
|
|
4266
|
+
return { vars, error: null, log, output };
|
|
4198
4267
|
}
|
|
4199
4268
|
return { vars, error: "Invalid API Link", log };
|
|
4200
4269
|
} catch (err) {
|
|
@@ -4371,8 +4440,6 @@ function getRootBlocksForSection(sid, blocks) {
|
|
|
4371
4440
|
);
|
|
4372
4441
|
}
|
|
4373
4442
|
var getRootBlocksForSection_default = getRootBlocksForSection;
|
|
4374
|
-
|
|
4375
|
-
// libs/blocks/runConsumers.ts
|
|
4376
4443
|
var verbose7 = getLogging_default();
|
|
4377
4444
|
var ORIGIN = process.env.REPORTS_ORIGIN || "";
|
|
4378
4445
|
axios5.interceptors.request.use((config) => ({
|
|
@@ -4417,7 +4484,7 @@ async function runSingleBlock(block, formatterFunctions, blockContext) {
|
|
|
4417
4484
|
api = swapAPI(unswappedAPI, formatterFunctions, blockContext);
|
|
4418
4485
|
apiResponse = await apiFetch(api).then((result) => {
|
|
4419
4486
|
if (verbose7)
|
|
4420
|
-
console.log("Variable loaded:", api);
|
|
4487
|
+
console.log("Variable loaded:", api, "response time: ", result.requestDuration);
|
|
4421
4488
|
return result;
|
|
4422
4489
|
}, (e) => {
|
|
4423
4490
|
if (verbose7)
|
|
@@ -4489,11 +4556,57 @@ async function runSingleBlock(block, formatterFunctions, blockContext) {
|
|
|
4489
4556
|
}
|
|
4490
4557
|
};
|
|
4491
4558
|
}
|
|
4492
|
-
var
|
|
4559
|
+
var getConsumers = (bid, blocks, acc = []) => {
|
|
4560
|
+
const rootBlock = blocks[bid];
|
|
4561
|
+
if (rootBlock.consumers.length) {
|
|
4562
|
+
rootBlock.consumers.forEach((consumer) => {
|
|
4563
|
+
getConsumers(consumer, blocks, acc);
|
|
4564
|
+
});
|
|
4565
|
+
}
|
|
4566
|
+
acc.push(bid);
|
|
4567
|
+
return acc;
|
|
4568
|
+
};
|
|
4569
|
+
var getDependencies = (bid, blocks, acc = []) => {
|
|
4570
|
+
const rootBlock = blocks[bid];
|
|
4571
|
+
if (rootBlock.consumers.length) {
|
|
4572
|
+
rootBlock.consumers.forEach((cid) => {
|
|
4573
|
+
acc.push([bid, cid]);
|
|
4574
|
+
rootBlock.consumers.forEach((cid2) => getDependencies(cid2, blocks, acc));
|
|
4575
|
+
});
|
|
4576
|
+
}
|
|
4577
|
+
return acc;
|
|
4578
|
+
};
|
|
4579
|
+
var runConsumersV2 = async (blocks, sections, bid, formatterFunctions, blockContext, initialVariables = {}) => {
|
|
4580
|
+
if (!bid && !sections)
|
|
4581
|
+
return { variables: {} };
|
|
4582
|
+
const variablesById = { ...initialVariables };
|
|
4583
|
+
const parsedBlockContext = parseBlockContext(blockContext);
|
|
4584
|
+
const attributes = parsedBlockContext.variables;
|
|
4585
|
+
const rootBlocks = bid ? { [bid]: blocks[bid] } : sections.reduce((rootBlocks2, { id }) => ({ ...rootBlocks2, ...getRootBlocksForSection_default(id, blocks) }), {});
|
|
4586
|
+
const blockDeps = Object.keys(rootBlocks).reduce((deps, bid2) => [...deps, ...getDependencies(Number(bid2), blocks)], []);
|
|
4587
|
+
const orderedDAG = toposort(blockDeps);
|
|
4588
|
+
const blockOrder = bid ? orderedDAG : Object.keys(blocks).sort((a, b) => orderedDAG.indexOf(Number(a)) - orderedDAG.indexOf(Number(b)));
|
|
4589
|
+
for (const blockId of blockOrder) {
|
|
4590
|
+
const block = blocks[blockId];
|
|
4591
|
+
const variables = block.inputs.reduce((acc, d) => ({ ...acc, ...variablesById[d] }), attributes);
|
|
4592
|
+
const { outputVariables } = await runSingleBlock(
|
|
4593
|
+
block,
|
|
4594
|
+
formatterFunctions,
|
|
4595
|
+
{
|
|
4596
|
+
...parsedBlockContext,
|
|
4597
|
+
variables
|
|
4598
|
+
}
|
|
4599
|
+
);
|
|
4600
|
+
variablesById[blockId] = outputVariables;
|
|
4601
|
+
}
|
|
4602
|
+
return { variables: { ...initialVariables, ...variablesById } };
|
|
4603
|
+
};
|
|
4604
|
+
var runConsumers = async (blocks, sid, bid, formatterFunctions, blockContext, initialVariables) => {
|
|
4605
|
+
const revalidate = bid ? getConsumers(bid, blocks) : [];
|
|
4493
4606
|
const rootBlocks = bid ? { [bid]: blocks[bid] } : getRootBlocksForSection_default(sid, blocks);
|
|
4494
4607
|
const parsedBlockContext = parseBlockContext(blockContext);
|
|
4495
4608
|
const attributes = parsedBlockContext.variables;
|
|
4496
|
-
const variablesById = {};
|
|
4609
|
+
const variablesById = initialVariables ? { ...initialVariables } : {};
|
|
4497
4610
|
const statusById = {};
|
|
4498
4611
|
const crawlUp = async (bid2) => {
|
|
4499
4612
|
const block = blocks[bid2];
|
|
@@ -4519,13 +4632,13 @@ var runConsumers = async (blocks, sid, bid, formatterFunctions, blockContext) =>
|
|
|
4519
4632
|
statusById[bid2] = status;
|
|
4520
4633
|
}
|
|
4521
4634
|
};
|
|
4522
|
-
const
|
|
4635
|
+
const crawlDown2 = async (bid2, cascader = false) => {
|
|
4523
4636
|
if (cascader) {
|
|
4524
4637
|
variablesById[bid2] = {};
|
|
4525
4638
|
statusById[bid2] = { hiddenByCascade: cascader };
|
|
4526
4639
|
for (let i = 0; i < blocks[bid2].consumers.length; i += 1) {
|
|
4527
4640
|
const cid = blocks[bid2].consumers[i];
|
|
4528
|
-
await
|
|
4641
|
+
await crawlDown2(cid, cascader);
|
|
4529
4642
|
}
|
|
4530
4643
|
return;
|
|
4531
4644
|
}
|
|
@@ -4548,7 +4661,7 @@ var runConsumers = async (blocks, sid, bid, formatterFunctions, blockContext) =>
|
|
|
4548
4661
|
if (block.settings.allowed === "never")
|
|
4549
4662
|
allowed = false;
|
|
4550
4663
|
else {
|
|
4551
|
-
const { vars, error } = mortarEval_default(
|
|
4664
|
+
const { vars, error, output } = mortarEval_default(
|
|
4552
4665
|
"variables",
|
|
4553
4666
|
{ ...variables, ...attributes },
|
|
4554
4667
|
block.settings.allowedLogic,
|
|
@@ -4557,29 +4670,28 @@ var runConsumers = async (blocks, sid, bid, formatterFunctions, blockContext) =>
|
|
|
4557
4670
|
parsedBlockContext
|
|
4558
4671
|
);
|
|
4559
4672
|
if (!error)
|
|
4560
|
-
allowed = Boolean(
|
|
4673
|
+
allowed = Boolean(output);
|
|
4561
4674
|
}
|
|
4562
4675
|
}
|
|
4563
4676
|
if (allowed) {
|
|
4564
|
-
if (!variablesById[bid2]) {
|
|
4677
|
+
if (!variablesById[bid2] || revalidate.includes(Number(bid2))) {
|
|
4565
4678
|
const { outputVariables, status } = await runSingleBlock(block, formatterFunctions, { ...parsedBlockContext, variables: { ...variables, ...attributes } });
|
|
4566
|
-
|
|
4567
|
-
variablesById[bid2] = outputVariables;
|
|
4679
|
+
variablesById[bid2] = outputVariables;
|
|
4568
4680
|
statusById[bid2] = status;
|
|
4569
4681
|
}
|
|
4570
4682
|
for (const cid of blocks[bid2].consumers) {
|
|
4571
|
-
await
|
|
4683
|
+
await crawlDown2(cid);
|
|
4572
4684
|
}
|
|
4573
4685
|
} else {
|
|
4574
4686
|
variablesById[bid2] = {};
|
|
4575
4687
|
statusById[bid2] = { hiddenByCascade: bid2 };
|
|
4576
4688
|
for (const cid of blocks[bid2].consumers) {
|
|
4577
|
-
await
|
|
4689
|
+
await crawlDown2(cid, bid2);
|
|
4578
4690
|
}
|
|
4579
4691
|
}
|
|
4580
4692
|
};
|
|
4581
4693
|
for (const id of Object.keys(rootBlocks)) {
|
|
4582
|
-
await
|
|
4694
|
+
await crawlDown2(id);
|
|
4583
4695
|
}
|
|
4584
4696
|
return {
|
|
4585
4697
|
variables: variablesById,
|
|
@@ -4779,7 +4891,10 @@ var statusSlice = createSlice({
|
|
|
4779
4891
|
* properties for the client's components.
|
|
4780
4892
|
*/
|
|
4781
4893
|
[HYDRATE]: (_state, _action) => {
|
|
4782
|
-
return
|
|
4894
|
+
return {
|
|
4895
|
+
..._state,
|
|
4896
|
+
previews: _action.payload.status.previews
|
|
4897
|
+
};
|
|
4783
4898
|
}
|
|
4784
4899
|
}
|
|
4785
4900
|
});
|
|
@@ -4979,6 +5094,33 @@ var recordsSlice = createSlice({
|
|
|
4979
5094
|
arrayRemove(state.entities[parentType][parentId][pluralKey], id);
|
|
4980
5095
|
}
|
|
4981
5096
|
}
|
|
5097
|
+
},
|
|
5098
|
+
removeBlocks: (state, action) => {
|
|
5099
|
+
const privateBlockIds = action.payload;
|
|
5100
|
+
const newBlocks = { ...state.entities.block };
|
|
5101
|
+
privateBlockIds.forEach((pbId) => {
|
|
5102
|
+
delete newBlocks[pbId];
|
|
5103
|
+
});
|
|
5104
|
+
return {
|
|
5105
|
+
...state,
|
|
5106
|
+
entities: {
|
|
5107
|
+
...state.entities,
|
|
5108
|
+
block: newBlocks
|
|
5109
|
+
}
|
|
5110
|
+
};
|
|
5111
|
+
},
|
|
5112
|
+
addBlocks: (state, action) => {
|
|
5113
|
+
const newBlocks = action.payload;
|
|
5114
|
+
return {
|
|
5115
|
+
...state,
|
|
5116
|
+
entities: {
|
|
5117
|
+
...state.entities,
|
|
5118
|
+
block: {
|
|
5119
|
+
...state.entities.block,
|
|
5120
|
+
...newBlocks
|
|
5121
|
+
}
|
|
5122
|
+
}
|
|
5123
|
+
};
|
|
4982
5124
|
}
|
|
4983
5125
|
},
|
|
4984
5126
|
extraReducers: {
|
|
@@ -4991,7 +5133,7 @@ var recordsSlice = createSlice({
|
|
|
4991
5133
|
*/
|
|
4992
5134
|
[HYDRATE]: (state, action) => {
|
|
4993
5135
|
const nextState = action.payload.records;
|
|
4994
|
-
const entities =
|
|
5136
|
+
const entities = nextState.entities;
|
|
4995
5137
|
return {
|
|
4996
5138
|
entities,
|
|
4997
5139
|
reports: Object.values(entities.report).map((item) => item.id),
|
|
@@ -5025,8 +5167,6 @@ function arrayRemove(list2, item) {
|
|
|
5025
5167
|
list2.splice(index, 1);
|
|
5026
5168
|
}
|
|
5027
5169
|
}
|
|
5028
|
-
|
|
5029
|
-
// store/recordsActions.ts
|
|
5030
5170
|
var recordsActions = recordsSlice.actions;
|
|
5031
5171
|
var createEntity = entityActionFactory({
|
|
5032
5172
|
block: createHandlerFactory("block"),
|
|
@@ -5364,6 +5504,27 @@ function addNewReportToCurrentUser(params) {
|
|
|
5364
5504
|
return result.data;
|
|
5365
5505
|
};
|
|
5366
5506
|
}
|
|
5507
|
+
function removeBlocksFromState(privateBlockIds) {
|
|
5508
|
+
const { removeBlocks } = recordsSlice.actions;
|
|
5509
|
+
return async (dispatch) => {
|
|
5510
|
+
await dispatch(removeBlocks(privateBlockIds));
|
|
5511
|
+
};
|
|
5512
|
+
}
|
|
5513
|
+
function addBlockToState(newBlocks) {
|
|
5514
|
+
const { addBlocks } = recordsSlice.actions;
|
|
5515
|
+
return async (dispatch) => {
|
|
5516
|
+
await dispatch(addBlocks(newBlocks));
|
|
5517
|
+
};
|
|
5518
|
+
}
|
|
5519
|
+
function readPrivateBlocks(params) {
|
|
5520
|
+
return async (_, __, api) => {
|
|
5521
|
+
const result = await api.readPrivateBlocks({ ...params, roles: [] });
|
|
5522
|
+
if ("error" in result) {
|
|
5523
|
+
throw new Error(result.error);
|
|
5524
|
+
}
|
|
5525
|
+
return result.data;
|
|
5526
|
+
};
|
|
5527
|
+
}
|
|
5367
5528
|
var storeFactory = (_context) => configureStore({
|
|
5368
5529
|
reducer: {
|
|
5369
5530
|
[recordsSlice.name]: recordsSlice.reducer,
|
|
@@ -5470,7 +5631,6 @@ function BespokeRendererStaticPaths(options) {
|
|
|
5470
5631
|
paths = req.data.results.slice(0, limit).map((item) => ({
|
|
5471
5632
|
locale: locales8.find((token) => token === item.locale),
|
|
5472
5633
|
params: {
|
|
5473
|
-
//@ts-ignore
|
|
5474
5634
|
bespoke: [item.variant.slug, item.slug]
|
|
5475
5635
|
// TODO: fix SearchResult definition
|
|
5476
5636
|
}
|
|
@@ -5492,7 +5652,6 @@ function BespokeRendererStaticProps(options) {
|
|
|
5492
5652
|
return async (context) => {
|
|
5493
5653
|
await dispatch(useDatabaseApi);
|
|
5494
5654
|
const buildTime = (/* @__PURE__ */ new Date()).toISOString();
|
|
5495
|
-
console.log("StaticProps", context);
|
|
5496
5655
|
const {
|
|
5497
5656
|
locale = localeDefault7,
|
|
5498
5657
|
// TODO: detect or use app default
|
|
@@ -5526,16 +5685,27 @@ function BespokeRendererStaticProps(options) {
|
|
|
5526
5685
|
const formatters = funcifyFormattersByLocale(formatterList, localeDefault7);
|
|
5527
5686
|
const sectionList = selectSectionList(state);
|
|
5528
5687
|
const blockRecords = selectBlockRecords(state);
|
|
5688
|
+
const publicBlockRecords = { ...blockRecords };
|
|
5689
|
+
let privateBlockIds = Object.values(blockRecords).reduce((acc, block) => {
|
|
5690
|
+
if ("access" in block.settings && !["public", "guest"].some((grant) => !block.settings.access || block.settings.access.includes(grant))) {
|
|
5691
|
+
console.log("is Private", block.id);
|
|
5692
|
+
acc.push(block.id);
|
|
5693
|
+
}
|
|
5694
|
+
return acc;
|
|
5695
|
+
}, []);
|
|
5696
|
+
privateBlockIds = privateBlockIds.concat(crawlDown(privateBlockIds, Object.values(publicBlockRecords)));
|
|
5697
|
+
privateBlockIds.forEach((privateBlockId) => {
|
|
5698
|
+
delete publicBlockRecords[privateBlockId];
|
|
5699
|
+
});
|
|
5700
|
+
await dispatch(removeBlocksFromState(privateBlockIds));
|
|
5529
5701
|
const attributes = previewsToAttributes_default(members.results);
|
|
5530
|
-
await
|
|
5531
|
-
|
|
5532
|
-
|
|
5533
|
-
|
|
5534
|
-
|
|
5535
|
-
|
|
5536
|
-
|
|
5537
|
-
})
|
|
5538
|
-
));
|
|
5702
|
+
await runConsumersV2(publicBlockRecords, sectionList, void 0, formatters, {
|
|
5703
|
+
locale,
|
|
5704
|
+
query: params,
|
|
5705
|
+
variables: attributes
|
|
5706
|
+
}).then((data) => {
|
|
5707
|
+
dispatch(variablesActions.setVariableChange({ ...data, attributes }));
|
|
5708
|
+
});
|
|
5539
5709
|
return {
|
|
5540
5710
|
props: {
|
|
5541
5711
|
buildTime
|