@stoker-platform/utils 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/lib/src/access/collection.d.ts +9 -0
  2. package/lib/src/access/collection.js +59 -0
  3. package/lib/src/access/document.d.ts +3 -0
  4. package/lib/src/access/document.js +191 -0
  5. package/lib/src/access/getCollectionRestrictions.d.ts +7 -0
  6. package/lib/src/access/getCollectionRestrictions.js +71 -0
  7. package/lib/src/access/getRecordSubcollections.d.ts +2 -0
  8. package/lib/src/access/getRecordSubcollections.js +15 -0
  9. package/lib/src/access/getRelatedCollections.d.ts +2 -0
  10. package/lib/src/access/getRelatedCollections.js +24 -0
  11. package/lib/src/access/hasDependencyAccess.d.ts +2 -0
  12. package/lib/src/access/hasDependencyAccess.js +24 -0
  13. package/lib/src/access/isPaginationEnabled.d.ts +2 -0
  14. package/lib/src/access/isPaginationEnabled.js +35 -0
  15. package/lib/src/access/permissions.d.ts +2 -0
  16. package/lib/src/access/permissions.js +543 -0
  17. package/lib/src/access/read/getOne.d.ts +2 -0
  18. package/lib/src/access/read/getOne.js +19 -0
  19. package/lib/src/access/read/getSome.d.ts +2 -0
  20. package/lib/src/access/read/getSome.js +21 -0
  21. package/lib/src/access/roleHasOperationAccess.d.ts +2 -0
  22. package/lib/src/access/roleHasOperationAccess.js +7 -0
  23. package/lib/src/access/write/addRecord.d.ts +2 -0
  24. package/lib/src/access/write/addRecord.js +40 -0
  25. package/lib/src/access/write/deleteRecord.d.ts +2 -0
  26. package/lib/src/access/write/deleteRecord.js +26 -0
  27. package/lib/src/access/write/updateRecord.d.ts +2 -0
  28. package/lib/src/access/write/updateRecord.js +61 -0
  29. package/lib/src/getConfigValue.d.ts +12 -0
  30. package/lib/src/getConfigValue.js +83 -0
  31. package/lib/src/getCustomization.d.ts +4 -0
  32. package/lib/src/getCustomization.js +29 -0
  33. package/lib/src/getFieldCustomization.d.ts +7 -0
  34. package/lib/src/getFieldCustomization.js +3 -0
  35. package/lib/src/main.d.ts +60 -0
  36. package/lib/src/main.js +60 -0
  37. package/lib/src/operations/addInitialValues.d.ts +2 -0
  38. package/lib/src/operations/addInitialValues.js +27 -0
  39. package/lib/src/operations/addLowercaseFields.d.ts +2 -0
  40. package/lib/src/operations/addLowercaseFields.js +12 -0
  41. package/lib/src/operations/addRelationArrays.d.ts +2 -0
  42. package/lib/src/operations/addRelationArrays.js +60 -0
  43. package/lib/src/operations/addSystemFields.d.ts +2 -0
  44. package/lib/src/operations/addSystemFields.js +17 -0
  45. package/lib/src/operations/getDateRange.d.ts +5 -0
  46. package/lib/src/operations/getDateRange.js +56 -0
  47. package/lib/src/operations/getExtendedSchema.d.ts +2 -0
  48. package/lib/src/operations/getExtendedSchema.js +23 -0
  49. package/lib/src/operations/getFinalRecord.d.ts +1 -0
  50. package/lib/src/operations/getFinalRecord.js +11 -0
  51. package/lib/src/operations/getInputSchema.d.ts +15 -0
  52. package/lib/src/operations/getInputSchema.js +352 -0
  53. package/lib/src/operations/getLowercaseFields.d.ts +2 -0
  54. package/lib/src/operations/getLowercaseFields.js +15 -0
  55. package/lib/src/operations/getSingleFieldRelations.d.ts +2 -0
  56. package/lib/src/operations/getSingleFieldRelations.js +27 -0
  57. package/lib/src/operations/getZodSchema.d.ts +15 -0
  58. package/lib/src/operations/getZodSchema.js +303 -0
  59. package/lib/src/operations/isDeleteSentinel.d.ts +1 -0
  60. package/lib/src/operations/isDeleteSentinel.js +4 -0
  61. package/lib/src/operations/isSortingEnabled.d.ts +2 -0
  62. package/lib/src/operations/isSortingEnabled.js +7 -0
  63. package/lib/src/operations/isValidUniqueFieldValue.d.ts +1 -0
  64. package/lib/src/operations/isValidUniqueFieldValue.js +25 -0
  65. package/lib/src/operations/parseDate.d.ts +1 -0
  66. package/lib/src/operations/parseDate.js +4 -0
  67. package/lib/src/operations/prepareDenormalized.d.ts +8 -0
  68. package/lib/src/operations/prepareDenormalized.js +312 -0
  69. package/lib/src/operations/removeDeleteSentinels.d.ts +2 -0
  70. package/lib/src/operations/removeDeleteSentinels.js +15 -0
  71. package/lib/src/operations/removeDeletedFields.d.ts +2 -0
  72. package/lib/src/operations/removeDeletedFields.js +14 -0
  73. package/lib/src/operations/removeEmptyStrings.d.ts +2 -0
  74. package/lib/src/operations/removeEmptyStrings.js +14 -0
  75. package/lib/src/operations/removePrivateFields.d.ts +2 -0
  76. package/lib/src/operations/removePrivateFields.js +14 -0
  77. package/lib/src/operations/removeUndefined.d.ts +2 -0
  78. package/lib/src/operations/removeUndefined.js +14 -0
  79. package/lib/src/operations/retryOperation.d.ts +1 -0
  80. package/lib/src/operations/retryOperation.js +21 -0
  81. package/lib/src/operations/runHooks.d.ts +17 -0
  82. package/lib/src/operations/runHooks.js +18 -0
  83. package/lib/src/operations/sanitizeDownloadFilename.d.ts +1 -0
  84. package/lib/src/operations/sanitizeDownloadFilename.js +18 -0
  85. package/lib/src/operations/sanitizeEmailInput.d.ts +5 -0
  86. package/lib/src/operations/sanitizeEmailInput.js +73 -0
  87. package/lib/src/operations/updateFieldReference.d.ts +2 -0
  88. package/lib/src/operations/updateFieldReference.js +14 -0
  89. package/lib/src/operations/validateRecord.d.ts +2 -0
  90. package/lib/src/operations/validateRecord.js +18 -0
  91. package/lib/src/operations/validateStorageName.d.ts +1 -0
  92. package/lib/src/operations/validateStorageName.js +19 -0
  93. package/lib/src/schema/getAccessFields.d.ts +2 -0
  94. package/lib/src/schema/getAccessFields.js +62 -0
  95. package/lib/src/schema/getCollection.d.ts +2 -0
  96. package/lib/src/schema/getCollection.js +3 -0
  97. package/lib/src/schema/getDependencyFields.d.ts +6 -0
  98. package/lib/src/schema/getDependencyFields.js +22 -0
  99. package/lib/src/schema/getField.d.ts +2 -0
  100. package/lib/src/schema/getField.js +3 -0
  101. package/lib/src/schema/getFieldNames.d.ts +2 -0
  102. package/lib/src/schema/getFieldNames.js +3 -0
  103. package/lib/src/schema/getIndexFields.d.ts +9 -0
  104. package/lib/src/schema/getIndexFields.js +184 -0
  105. package/lib/src/schema/getInverseRelationType.d.ts +1 -0
  106. package/lib/src/schema/getInverseRelationType.js +15 -0
  107. package/lib/src/schema/getPathCollections.d.ts +2 -0
  108. package/lib/src/schema/getPathCollections.js +12 -0
  109. package/lib/src/schema/getRecordSystemFields.d.ts +2 -0
  110. package/lib/src/schema/getRecordSystemFields.js +11 -0
  111. package/lib/src/schema/getRelationLists.d.ts +5 -0
  112. package/lib/src/schema/getRelationLists.js +13 -0
  113. package/lib/src/schema/getSubcollections.d.ts +2 -0
  114. package/lib/src/schema/getSubcollections.js +9 -0
  115. package/lib/src/schema/getSystemFieldsSchema.d.ts +2 -0
  116. package/lib/src/schema/getSystemFieldsSchema.js +52 -0
  117. package/lib/src/schema/isDependencyField.d.ts +2 -0
  118. package/lib/src/schema/isDependencyField.js +18 -0
  119. package/lib/src/schema/isIncludedField.d.ts +2 -0
  120. package/lib/src/schema/isIncludedField.js +18 -0
  121. package/lib/src/schema/isRelationField.d.ts +2 -0
  122. package/lib/src/schema/isRelationField.js +3 -0
  123. package/lib/src/schema/system-fields.d.ts +2 -0
  124. package/lib/src/schema/system-fields.js +13 -0
  125. package/lib/tsconfig.tsbuildinfo +1 -0
  126. package/package.json +35 -0
@@ -0,0 +1,26 @@
1
+ import { collectionAccess, collectionAuthAccess } from "../collection.js";
2
+ import { documentAccess } from "../document.js";
3
+ import { permissionsWriteAccess } from "../permissions.js";
4
+ export const deleteRecordAccessControl = (record, docId, collectionSchema, schema, currentUserId, currentUserPermissions) => {
5
+ const { labels } = collectionSchema;
6
+ // eslint-disable-next-line security/detect-object-injection
7
+ const collectionPermissions = currentUserPermissions.collections?.[labels.collection];
8
+ let granted = true;
9
+ if (!collectionPermissions) {
10
+ throw new Error("PERMISSION_DENIED");
11
+ }
12
+ if (!collectionAccess("Delete", collectionPermissions))
13
+ granted = false;
14
+ if (!documentAccess("Delete", collectionSchema, schema, currentUserId, currentUserPermissions, record))
15
+ granted = false;
16
+ if (collectionSchema.auth && record.User_ID) {
17
+ if (!collectionAuthAccess(collectionPermissions))
18
+ granted = false;
19
+ if (!permissionsWriteAccess("delete", record, docId, collectionSchema, schema, currentUserId, currentUserPermissions)) {
20
+ granted = false;
21
+ }
22
+ }
23
+ if (!granted)
24
+ throw new Error("PERMISSION_DENIED");
25
+ return;
26
+ };
@@ -0,0 +1,2 @@
1
+ import { CollectionSchema, CollectionsSchema, StokerPermissions, StokerRecord } from "@stoker-platform/types";
2
+ export declare const updateRecordAccessControl: (partial: StokerRecord, originalRecord: StokerRecord, docId: string, collectionSchema: CollectionSchema, schema: CollectionsSchema, currentUserId?: string, currentUserPermissions?: StokerPermissions, userOperation?: string, permissions?: StokerPermissions, originalPermissions?: StokerPermissions | undefined) => void;
@@ -0,0 +1,61 @@
1
+ import { collectionAccess, collectionAuthAccess, privateFieldAccess, restrictUpdateAccess } from "../collection.js";
2
+ import { documentAccess } from "../document.js";
3
+ import { permissionsWriteAccess } from "../permissions.js";
4
+ import { removeDeleteSentinels } from "../../operations/removeDeleteSentinels.js";
5
+ export const updateRecordAccessControl = (partial, originalRecord, docId, collectionSchema, schema, currentUserId, currentUserPermissions, userOperation, permissions, originalPermissions) => {
6
+ const { labels, fields } = collectionSchema;
7
+ // eslint-disable-next-line security/detect-object-injection
8
+ const collectionPermissions = currentUserPermissions?.collections?.[labels.collection];
9
+ const finalRecord = { ...originalRecord, ...partial };
10
+ removeDeleteSentinels(finalRecord);
11
+ let granted = true;
12
+ let errorDetails = "";
13
+ const logErrors = true;
14
+ if (currentUserId && !collectionPermissions) {
15
+ throw new Error("PERMISSION_DENIED");
16
+ }
17
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
18
+ if (currentUserId && !collectionAccess("Update", collectionPermissions)) {
19
+ granted = false;
20
+ errorDetails = "Authenticated user does not have Update access to this collection";
21
+ }
22
+ if (currentUserId &&
23
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
24
+ (!documentAccess("Update", collectionSchema, schema, currentUserId, currentUserPermissions, originalRecord) ||
25
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
26
+ !documentAccess("Update", collectionSchema, schema, currentUserId, currentUserPermissions, finalRecord))) {
27
+ granted = false;
28
+ errorDetails = "Authenticated user does not have Update access to this document";
29
+ }
30
+ if (userOperation) {
31
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
32
+ if (currentUserId && !collectionAuthAccess(collectionPermissions)) {
33
+ granted = false;
34
+ errorDetails = "Authenticated user does not have Auth access for this collection";
35
+ }
36
+ if (!permissionsWriteAccess("update", finalRecord, docId, collectionSchema, schema, currentUserId, currentUserPermissions, permissions, originalPermissions, originalRecord, userOperation)) {
37
+ errorDetails = "Authenticated user does not have sufficient write access for this record";
38
+ granted = false;
39
+ }
40
+ }
41
+ for (const field of fields) {
42
+ const value = partial[field.name];
43
+ if (field.access) {
44
+ if (!privateFieldAccess(field, currentUserPermissions) && value !== undefined) {
45
+ errorDetails = `Authenticated user does not have access to field ${field.name}`;
46
+ granted = false;
47
+ }
48
+ }
49
+ if (value !== undefined && !restrictUpdateAccess(field, currentUserPermissions)) {
50
+ errorDetails = `Authenticated user does not have Update access to field ${field.name}`;
51
+ granted = false;
52
+ }
53
+ }
54
+ if (!granted) {
55
+ if (logErrors && errorDetails) {
56
+ console.error(`PERMISSION_DENIED: ${errorDetails}`);
57
+ }
58
+ throw new Error("PERMISSION_DENIED");
59
+ }
60
+ return;
61
+ };
@@ -0,0 +1,12 @@
1
+ import { GlobalConfig, CollectionCustomization, StokerCollection, AuthConfig, FirebaseConfig, PreloadConfig, MailConfig, CollectionSchema, AdminConfig } from "@stoker-platform/types";
2
+ export declare const clearConfigCache: () => void;
3
+ export declare const tryFunction: (configProperty: unknown, args?: unknown[]) => any;
4
+ export declare const tryPromise: (configProperty: any, args?: unknown[]) => Promise<any>;
5
+ type ConfigPath = [
6
+ "global",
7
+ keyof GlobalConfig,
8
+ (keyof AuthConfig | keyof FirebaseConfig | keyof PreloadConfig | keyof MailConfig | keyof AdminConfig)?,
9
+ ...string[]
10
+ ] | ["collections", StokerCollection, keyof CollectionSchema, ...string[]];
11
+ export declare const getCachedConfigValue: (config: GlobalConfig | CollectionCustomization, pathArray: ConfigPath, args?: unknown[], overwrite?: boolean) => Promise<any>;
12
+ export {};
@@ -0,0 +1,83 @@
1
+ import merge from "lodash/merge.js";
2
+ import set from "lodash/set.js";
3
+ const configCache = {
4
+ global: {},
5
+ collections: {},
6
+ };
7
+ export const clearConfigCache = () => {
8
+ configCache.global = {};
9
+ configCache.collections = {};
10
+ };
11
+ export const tryFunction = (configProperty, args) => {
12
+ if (configProperty && typeof configProperty === "function") {
13
+ return args ? configProperty(...args) : configProperty();
14
+ }
15
+ return configProperty;
16
+ };
17
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
18
+ export const tryPromise = async (configProperty, args) => {
19
+ let configValue = configProperty;
20
+ if (configProperty && (typeof configProperty === "function" || typeof configProperty.then === "function")) {
21
+ args ? (configValue = await configProperty(...args)) : (configValue = await configProperty());
22
+ }
23
+ return configValue;
24
+ };
25
+ export const getCachedConfigValue = async (config, pathArray, args, overwrite) => {
26
+ /* eslint-disable security/detect-object-injection, @typescript-eslint/no-explicit-any */
27
+ // Validate path array to prevent prototype pollution
28
+ for (const property of pathArray) {
29
+ if (property === "__proto__" || property === "constructor" || property === "prototype") {
30
+ throw new Error("Invalid config path: prototype pollution keys are not allowed");
31
+ }
32
+ }
33
+ let configCacheProperty = configCache;
34
+ let existsInCache = true;
35
+ for (const property of pathArray) {
36
+ if (property === undefined || configCacheProperty[property] === undefined) {
37
+ existsInCache = false;
38
+ break;
39
+ }
40
+ configCacheProperty = configCacheProperty[property];
41
+ }
42
+ if (configCacheProperty && existsInCache && !overwrite) {
43
+ return configCacheProperty;
44
+ }
45
+ let modifiedPathArray;
46
+ let configProperty = config;
47
+ let existsInConfig = true;
48
+ pathArray[0] === "collections" ? (modifiedPathArray = pathArray.slice(2)) : (modifiedPathArray = pathArray.slice(1));
49
+ for (const property of modifiedPathArray) {
50
+ if (property === undefined || configProperty[property] === undefined) {
51
+ existsInConfig = false;
52
+ break;
53
+ }
54
+ configProperty = configProperty[property];
55
+ }
56
+ let configValue;
57
+ if (existsInConfig)
58
+ configValue = await tryPromise(configProperty, args);
59
+ if (configValue) {
60
+ let currentCache = configCache;
61
+ const cachePartial = {};
62
+ for (let i = 0; i < pathArray.length; i++) {
63
+ const property = pathArray[i];
64
+ if (property === undefined) {
65
+ continue;
66
+ }
67
+ // Additional check to prevent prototype pollution
68
+ if (property === "__proto__" || property === "constructor" || property === "prototype") {
69
+ throw new Error("Invalid config path: prototype pollution keys are not allowed");
70
+ }
71
+ if (i === pathArray.length - 1) {
72
+ set(cachePartial, pathArray.join("."), configValue);
73
+ }
74
+ else {
75
+ currentCache[property] ||= {};
76
+ currentCache = currentCache[property];
77
+ }
78
+ }
79
+ merge(configCache, cachePartial);
80
+ }
81
+ /* eslint-enable security/detect-object-injection, @typescript-eslint/no-explicit-any */
82
+ return configValue;
83
+ };
@@ -0,0 +1,4 @@
1
+ import { CollectionCustomization } from "@stoker-platform/types/src/types/schema";
2
+ export declare const getCustomization: (collections: string[], modules: any, sdk: "web" | "node", utilities?: any, context?: any) => {
3
+ [key: string]: CollectionCustomization;
4
+ };
@@ -0,0 +1,29 @@
1
+ export const getCustomization = (collections,
2
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
3
+ modules, sdk,
4
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5
+ utilities,
6
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
7
+ context) => {
8
+ const collectionFiles = {};
9
+ for (const collection of collections) {
10
+ // eslint-disable-next-line security/detect-object-injection
11
+ const module = modules[collection];
12
+ const collectionFile = module.default(sdk, utilities, context);
13
+ for (const key in collectionFile) {
14
+ // eslint-disable-next-line security/detect-object-injection
15
+ if (!(key === "custom" || key === "admin" || key === "fields"))
16
+ delete collectionFile[key];
17
+ }
18
+ for (const field of collectionFile.fields) {
19
+ for (const key in field) {
20
+ // eslint-disable-next-line security/detect-object-injection
21
+ if (!(key === "custom" || key === "admin" || key === "name" || key === "formula"))
22
+ delete field[key];
23
+ }
24
+ }
25
+ // eslint-disable-next-line security/detect-object-injection
26
+ collectionFiles[collection] = collectionFile;
27
+ }
28
+ return collectionFiles;
29
+ };
@@ -0,0 +1,7 @@
1
+ import { CollectionField, CollectionCustomization } from "@stoker-platform/types";
2
+ export declare const getFieldCustomization: (field: CollectionField, customizationFile: CollectionCustomization) => {
3
+ name: string;
4
+ custom?: import("@stoker-platform/types").FieldCustom;
5
+ admin?: import("@stoker-platform/types").FieldAdmin;
6
+ formula?: (record: import("@stoker-platform/types").StokerRecord) => string | number;
7
+ };
@@ -0,0 +1,3 @@
1
+ export const getFieldCustomization = (field, customizationFile) => {
2
+ return customizationFile.fields.filter((customField) => customField.name === field.name)[0];
3
+ };
@@ -0,0 +1,60 @@
1
+ export * from "./access/collection.js";
2
+ export * from "./access/document.js";
3
+ export { hasDependencyAccess } from "./access/hasDependencyAccess.js";
4
+ export { getRelatedCollections } from "./access/getRelatedCollections.js";
5
+ export { getRecordSubcollections } from "./access/getRecordSubcollections.js";
6
+ export { addRecordAccessControl } from "./access/write/addRecord.js";
7
+ export { updateRecordAccessControl } from "./access/write/updateRecord.js";
8
+ export { deleteRecordAccessControl } from "./access/write/deleteRecord.js";
9
+ export { getOneAccessControl } from "./access/read/getOne.js";
10
+ export { getSomeAccessControl } from "./access/read/getSome.js";
11
+ export { roleHasOperationAccess } from "./access/roleHasOperationAccess.js";
12
+ export { isPaginationEnabled } from "./access/isPaginationEnabled.js";
13
+ export { getAttributeRestrictions, getEntityRestrictions, getEntityParentFilters, } from "./access/getCollectionRestrictions.js";
14
+ export { getCustomization } from "./getCustomization.js";
15
+ export { getFieldCustomization } from "./getFieldCustomization.js";
16
+ export * from "./getConfigValue.js";
17
+ export { isDependencyField } from "./schema/isDependencyField.js";
18
+ export { isIncludedField } from "./schema/isIncludedField.js";
19
+ export { getCollection } from "./schema/getCollection.js";
20
+ export { getDependencyFields } from "./schema/getDependencyFields.js";
21
+ export { getField } from "./schema/getField.js";
22
+ export { getFieldNames } from "./schema/getFieldNames.js";
23
+ export { getRoleFields, getDependencyAccessFields, getDependencyIndexFields, getRoleGroups, getRoleGroup, getRoleExcludedFields, getUserRoleGroups, getAllRoleGroups, } from "./schema/getIndexFields.js";
24
+ export { getAccessFields } from "./schema/getAccessFields.js";
25
+ export { getSystemFieldsSchema } from "./schema/getSystemFieldsSchema.js";
26
+ export { isRelationField } from "./schema/isRelationField.js";
27
+ export { getPathCollections } from "./schema/getPathCollections.js";
28
+ export { getInverseRelationType } from "./schema/getInverseRelationType.js";
29
+ export { getSubcollections } from "./schema/getSubcollections.js";
30
+ export { getRecordSystemFields } from "./schema/getRecordSystemFields.js";
31
+ export { getRelationLists } from "./schema/getRelationLists.js";
32
+ export { systemFields } from "./schema/system-fields.js";
33
+ export { runHooks } from "./operations/runHooks.js";
34
+ export { addSystemFields } from "./operations/addSystemFields.js";
35
+ export { addRelationArrays } from "./operations/addRelationArrays.js";
36
+ export { getSingleFieldRelations } from "./operations/getSingleFieldRelations.js";
37
+ export { addLowercaseFields } from "./operations/addLowercaseFields.js";
38
+ export { getLowercaseFields } from "./operations/getLowercaseFields.js";
39
+ export { addInitialValues } from "./operations/addInitialValues.js";
40
+ export { getExtendedSchema } from "./operations/getExtendedSchema.js";
41
+ export { getZodSchema as getSchema } from "./operations/getZodSchema.js";
42
+ export { getInputSchema } from "./operations/getInputSchema.js";
43
+ export { validateRecord } from "./operations/validateRecord.js";
44
+ export { prepareDenormalized as addDenormalized } from "./operations/prepareDenormalized.js";
45
+ export { removePrivateFields } from "./operations/removePrivateFields.js";
46
+ export { removeUndefined } from "./operations/removeUndefined.js";
47
+ export { removeEmptyStrings } from "./operations/removeEmptyStrings.js";
48
+ export { getDateRange as getRange } from "./operations/getDateRange.js";
49
+ export { isValidUniqueFieldValue } from "./operations/isValidUniqueFieldValue.js";
50
+ export { retryOperation } from "./operations/retryOperation.js";
51
+ export { isDeleteSentinel } from "./operations/isDeleteSentinel.js";
52
+ export { removeDeleteSentinels } from "./operations/removeDeleteSentinels.js";
53
+ export { updateFieldReference } from "./operations/updateFieldReference.js";
54
+ export { removeDeletedFields } from "./operations/removeDeletedFields.js";
55
+ export { isSortingEnabled } from "./operations/isSortingEnabled.js";
56
+ export { getFinalRecord } from "./operations/getFinalRecord.js";
57
+ export { parseDate } from "./operations/parseDate.js";
58
+ export { sanitizeEmailAddress, sanitizeEmailAddressArray, sanitizeEmailAddressOrArray, sanitizeEmailSubject, sanitizeEmailBody, } from "./operations/sanitizeEmailInput.js";
59
+ export { validateStorageName } from "./operations/validateStorageName.js";
60
+ export { sanitizeDownloadFilename } from "./operations/sanitizeDownloadFilename.js";
@@ -0,0 +1,60 @@
1
+ export * from "./access/collection.js";
2
+ export * from "./access/document.js";
3
+ export { hasDependencyAccess } from "./access/hasDependencyAccess.js";
4
+ export { getRelatedCollections } from "./access/getRelatedCollections.js";
5
+ export { getRecordSubcollections } from "./access/getRecordSubcollections.js";
6
+ export { addRecordAccessControl } from "./access/write/addRecord.js";
7
+ export { updateRecordAccessControl } from "./access/write/updateRecord.js";
8
+ export { deleteRecordAccessControl } from "./access/write/deleteRecord.js";
9
+ export { getOneAccessControl } from "./access/read/getOne.js";
10
+ export { getSomeAccessControl } from "./access/read/getSome.js";
11
+ export { roleHasOperationAccess } from "./access/roleHasOperationAccess.js";
12
+ export { isPaginationEnabled } from "./access/isPaginationEnabled.js";
13
+ export { getAttributeRestrictions, getEntityRestrictions, getEntityParentFilters, } from "./access/getCollectionRestrictions.js";
14
+ export { getCustomization } from "./getCustomization.js";
15
+ export { getFieldCustomization } from "./getFieldCustomization.js";
16
+ export * from "./getConfigValue.js";
17
+ export { isDependencyField } from "./schema/isDependencyField.js";
18
+ export { isIncludedField } from "./schema/isIncludedField.js";
19
+ export { getCollection } from "./schema/getCollection.js";
20
+ export { getDependencyFields } from "./schema/getDependencyFields.js";
21
+ export { getField } from "./schema/getField.js";
22
+ export { getFieldNames } from "./schema/getFieldNames.js";
23
+ export { getRoleFields, getDependencyAccessFields, getDependencyIndexFields, getRoleGroups, getRoleGroup, getRoleExcludedFields, getUserRoleGroups, getAllRoleGroups, } from "./schema/getIndexFields.js";
24
+ export { getAccessFields } from "./schema/getAccessFields.js";
25
+ export { getSystemFieldsSchema } from "./schema/getSystemFieldsSchema.js";
26
+ export { isRelationField } from "./schema/isRelationField.js";
27
+ export { getPathCollections } from "./schema/getPathCollections.js";
28
+ export { getInverseRelationType } from "./schema/getInverseRelationType.js";
29
+ export { getSubcollections } from "./schema/getSubcollections.js";
30
+ export { getRecordSystemFields } from "./schema/getRecordSystemFields.js";
31
+ export { getRelationLists } from "./schema/getRelationLists.js";
32
+ export { systemFields } from "./schema/system-fields.js";
33
+ export { runHooks } from "./operations/runHooks.js";
34
+ export { addSystemFields } from "./operations/addSystemFields.js";
35
+ export { addRelationArrays } from "./operations/addRelationArrays.js";
36
+ export { getSingleFieldRelations } from "./operations/getSingleFieldRelations.js";
37
+ export { addLowercaseFields } from "./operations/addLowercaseFields.js";
38
+ export { getLowercaseFields } from "./operations/getLowercaseFields.js";
39
+ export { addInitialValues } from "./operations/addInitialValues.js";
40
+ export { getExtendedSchema } from "./operations/getExtendedSchema.js";
41
+ export { getZodSchema as getSchema } from "./operations/getZodSchema.js";
42
+ export { getInputSchema } from "./operations/getInputSchema.js";
43
+ export { validateRecord } from "./operations/validateRecord.js";
44
+ export { prepareDenormalized as addDenormalized } from "./operations/prepareDenormalized.js";
45
+ export { removePrivateFields } from "./operations/removePrivateFields.js";
46
+ export { removeUndefined } from "./operations/removeUndefined.js";
47
+ export { removeEmptyStrings } from "./operations/removeEmptyStrings.js";
48
+ export { getDateRange as getRange } from "./operations/getDateRange.js";
49
+ export { isValidUniqueFieldValue } from "./operations/isValidUniqueFieldValue.js";
50
+ export { retryOperation } from "./operations/retryOperation.js";
51
+ export { isDeleteSentinel } from "./operations/isDeleteSentinel.js";
52
+ export { removeDeleteSentinels } from "./operations/removeDeleteSentinels.js";
53
+ export { updateFieldReference } from "./operations/updateFieldReference.js";
54
+ export { removeDeletedFields } from "./operations/removeDeletedFields.js";
55
+ export { isSortingEnabled } from "./operations/isSortingEnabled.js";
56
+ export { getFinalRecord } from "./operations/getFinalRecord.js";
57
+ export { parseDate } from "./operations/parseDate.js";
58
+ export { sanitizeEmailAddress, sanitizeEmailAddressArray, sanitizeEmailAddressOrArray, sanitizeEmailSubject, sanitizeEmailBody, } from "./operations/sanitizeEmailInput.js";
59
+ export { validateStorageName } from "./operations/validateStorageName.js";
60
+ export { sanitizeDownloadFilename } from "./operations/sanitizeDownloadFilename.js";
@@ -0,0 +1,2 @@
1
+ import { CollectionSchema, CollectionCustomization, StokerRecord, StokerRole } from "@stoker-platform/types";
2
+ export declare const addInitialValues: (data: StokerRecord, collectionSchema: CollectionSchema, customization: CollectionCustomization, role?: StokerRole) => Promise<void>;
@@ -0,0 +1,27 @@
1
+ import { tryPromise } from "../getConfigValue.js";
2
+ import { getField } from "../schema/getField.js";
3
+ import { isRelationField } from "../schema/isRelationField.js";
4
+ import { getLowercaseFields } from "./getLowercaseFields.js";
5
+ export const addInitialValues = async (data, collectionSchema, customization, role) => {
6
+ const { fields } = collectionSchema;
7
+ for (const field of customization.fields) {
8
+ const fieldSchema = getField(fields, field.name);
9
+ if (field.custom?.initialValue && !(role && fieldSchema.access && !fieldSchema.access.includes(role))) {
10
+ data[field.name] = await tryPromise(field.custom.initialValue, [data]);
11
+ const lowercaseFields = getLowercaseFields(collectionSchema, [fieldSchema]);
12
+ if (lowercaseFields.size === 1) {
13
+ data[`${field.name}_Lowercase`] = data[field.name].toLowerCase();
14
+ }
15
+ }
16
+ }
17
+ for (const field of fields) {
18
+ if (!(role && field.access && !field.access.includes(role))) {
19
+ if ("autoIncrement" in field && field.autoIncrement && !data[field.name]) {
20
+ data[field.name] = "Pending";
21
+ }
22
+ if (!isRelationField(field) && field.nullable && data[field.name] === undefined) {
23
+ data[field.name] = null;
24
+ }
25
+ }
26
+ }
27
+ };
@@ -0,0 +1,2 @@
1
+ import { CollectionSchema, StokerRecord } from "@stoker-platform/types";
2
+ export declare const addLowercaseFields: (collection: CollectionSchema, data: StokerRecord) => void;
@@ -0,0 +1,12 @@
1
+ import { getLowercaseFields } from "./getLowercaseFields.js";
2
+ export const addLowercaseFields = (collection, data) => {
3
+ const lowercaseFields = getLowercaseFields(collection, collection.fields);
4
+ lowercaseFields.forEach((field) => {
5
+ if (data[field.name]) {
6
+ data[`${field.name}_Lowercase`] = data[field.name].toLowerCase();
7
+ }
8
+ else {
9
+ delete data[`${field.name}_Lowercase`];
10
+ }
11
+ });
12
+ };
@@ -0,0 +1,2 @@
1
+ import { CollectionSchema, CollectionsSchema, StokerRecord } from "@stoker-platform/types";
2
+ export declare const addRelationArrays: (collection: CollectionSchema, data: StokerRecord, schema: CollectionsSchema) => void;
@@ -0,0 +1,60 @@
1
+ import { isDeleteSentinel } from "./isDeleteSentinel.js";
2
+ import { isRelationField } from "../schema/isRelationField.js";
3
+ import { getSingleFieldRelations } from "./getSingleFieldRelations.js";
4
+ import { getField } from "../schema/getField.js";
5
+ import { getLowercaseFields } from "./getLowercaseFields.js";
6
+ export const addRelationArrays = (collection, data, schema) => {
7
+ const { fields } = collection;
8
+ fields.forEach((field) => {
9
+ if (isRelationField(field)) {
10
+ if (data[field.name]) {
11
+ if (!isDeleteSentinel(data[field.name])) {
12
+ data[`${field.name}_Array`] = Object.keys(data[field.name]);
13
+ if (field.includeFields) {
14
+ for (const includeField of field.includeFields) {
15
+ const relationCollection = schema.collections[field.collection];
16
+ const includeFieldSchema = getField(relationCollection.fields, includeField);
17
+ const lowercaseFields = getLowercaseFields(relationCollection, [includeFieldSchema]);
18
+ if (lowercaseFields.size === 1) {
19
+ /* eslint-disable security/detect-object-injection */
20
+ Object.keys(data[field.name]).forEach((key) => {
21
+ if (data[field.name][key][includeField]) {
22
+ data[field.name][key][`${includeField}_Lowercase`] =
23
+ data[field.name][key][includeField].toLowerCase();
24
+ }
25
+ else {
26
+ delete data[field.name][key][`${includeField}_Lowercase`];
27
+ }
28
+ });
29
+ /* eslint-enable security/detect-object-injection */
30
+ }
31
+ }
32
+ }
33
+ }
34
+ else {
35
+ data[`${field.name}_Array`] = data[field.name];
36
+ }
37
+ }
38
+ else {
39
+ delete data[`${field.name}_Array`];
40
+ delete data[`${field.name}_Single`];
41
+ }
42
+ }
43
+ });
44
+ const singleRelationFields = getSingleFieldRelations(collection, fields);
45
+ singleRelationFields.forEach((field) => {
46
+ if (data[field.name]) {
47
+ if (!isDeleteSentinel(data[field.name])) {
48
+ const id = data[`${field.name}_Array`]?.[0];
49
+ if (id) {
50
+ // eslint-disable-next-line security/detect-object-injection
51
+ const includeFields = data[field.name][id] || {};
52
+ data[`${field.name}_Single`] = { ...includeFields };
53
+ }
54
+ }
55
+ else {
56
+ data[`${field.name}_Single`] = data[field.name];
57
+ }
58
+ }
59
+ });
60
+ };
@@ -0,0 +1,2 @@
1
+ import { CollectionsSchema, FirebaseTimestamp, StokerRecord } from "@stoker-platform/types";
2
+ export declare const addSystemFields: (operation: "create" | "update" | "delete", path: string[], data: Partial<StokerRecord>, schema: CollectionsSchema, appName: string, connection: "Online" | "Offline", userId: string, timestamp: FirebaseTimestamp, serverTimestamp: FirebaseTimestamp, retry?: boolean) => StokerRecord;
@@ -0,0 +1,17 @@
1
+ export const addSystemFields = (operation, path, data, schema, appName, connection, userId, timestamp, serverTimestamp, retry) => {
2
+ if (operation == "create") {
3
+ data.Collection_Path = path;
4
+ if (!retry)
5
+ data.Created_At = timestamp;
6
+ data.Saved_At = serverTimestamp;
7
+ data.Created_By = userId || "System";
8
+ }
9
+ data.Last_Write_App = appName;
10
+ if (!retry)
11
+ data.Last_Write_At = timestamp;
12
+ data.Last_Save_At = serverTimestamp;
13
+ data.Last_Write_By = userId || "System";
14
+ data.Last_Write_Connection_Status = connection;
15
+ data.Last_Write_Version = schema.version;
16
+ return data;
17
+ };
@@ -0,0 +1,5 @@
1
+ import { PreloadCacheRange } from "@stoker-platform/types";
2
+ export declare const getDateRange: (range: PreloadCacheRange, _timezone: string | undefined) => {
3
+ start: Date;
4
+ end: Date | undefined;
5
+ };
@@ -0,0 +1,56 @@
1
+ import { DateTime } from "luxon";
2
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
3
+ export const getDateRange = (range, _timezone) => {
4
+ let start, end = undefined;
5
+ if (typeof range.start === "object") {
6
+ start = range.start;
7
+ }
8
+ else {
9
+ start = new Date();
10
+ let startDateTime = DateTime.fromJSDate(start);
11
+ switch (range.start) {
12
+ case "Today":
13
+ startDateTime = startDateTime.startOf("day");
14
+ break;
15
+ case "Week":
16
+ startDateTime = startDateTime.startOf("week");
17
+ break;
18
+ case "Month":
19
+ startDateTime = startDateTime.startOf("month");
20
+ break;
21
+ case "Year":
22
+ startDateTime = startDateTime.startOf("year");
23
+ break;
24
+ default:
25
+ startDateTime = startDateTime.startOf("day");
26
+ }
27
+ if (typeof range.start === "number") {
28
+ startDateTime = startDateTime.plus({ days: range.start });
29
+ }
30
+ if (range.startOffsetDays) {
31
+ startDateTime = startDateTime.plus({ days: range.startOffsetDays });
32
+ }
33
+ if (range.startOffsetHours) {
34
+ startDateTime = startDateTime.plus({ hours: range.startOffsetHours });
35
+ }
36
+ start = startDateTime.toJSDate();
37
+ }
38
+ if (typeof range.end === "object") {
39
+ end = range.end;
40
+ }
41
+ else if (range.end) {
42
+ end = new Date();
43
+ let endDateTime = DateTime.fromJSDate(end);
44
+ if (typeof range.end === "number") {
45
+ endDateTime = endDateTime.plus({ days: range.end });
46
+ }
47
+ if (range.endOffsetDays) {
48
+ endDateTime = endDateTime.plus({ days: range.endOffsetDays });
49
+ }
50
+ if (range.endOffsetHours) {
51
+ endDateTime = endDateTime.plus({ hours: range.endOffsetHours });
52
+ }
53
+ end = endDateTime.toJSDate();
54
+ }
55
+ return { start, end };
56
+ };
@@ -0,0 +1,2 @@
1
+ import { CollectionField, CollectionSchema } from "@stoker-platform/types";
2
+ export declare const getExtendedSchema: (collection: CollectionSchema, fields: CollectionField[]) => string[];
@@ -0,0 +1,23 @@
1
+ import { getLowercaseFields } from "./getLowercaseFields.js";
2
+ import { getSingleFieldRelations } from "./getSingleFieldRelations.js";
3
+ import { isRelationField } from "../schema/isRelationField.js";
4
+ export const getExtendedSchema = (collection, fields) => {
5
+ const extendedSchema = [];
6
+ fields.forEach((field) => {
7
+ extendedSchema.push(field.name);
8
+ });
9
+ const lowercaseFields = getLowercaseFields(collection, fields);
10
+ lowercaseFields.forEach((field) => {
11
+ extendedSchema.push(`${field.name}_Lowercase`);
12
+ });
13
+ const singleRelationFields = getSingleFieldRelations(collection, fields);
14
+ singleRelationFields.forEach((field) => {
15
+ extendedSchema.push(`${field.name}_Single`);
16
+ });
17
+ fields.forEach((field) => {
18
+ if (isRelationField(field)) {
19
+ extendedSchema.push(`${field.name}_Array`);
20
+ }
21
+ });
22
+ return extendedSchema;
23
+ };
@@ -0,0 +1 @@
1
+ export declare const getFinalRecord: (args: IArguments) => any;
@@ -0,0 +1,11 @@
1
+ export const getFinalRecord = (args) => {
2
+ const record = args[1];
3
+ const originalRecord = Array.from(args).at(-1);
4
+ if (originalRecord) {
5
+ return {
6
+ ...originalRecord,
7
+ ...record,
8
+ };
9
+ }
10
+ return record;
11
+ };
@@ -0,0 +1,15 @@
1
+ import { CollectionCustomization, CollectionSchema, CollectionsSchema } from "@stoker-platform/types";
2
+ import { z } from "zod";
3
+ export declare const getInputSchema: (collection: CollectionSchema, schema: CollectionsSchema, customization?: CollectionCustomization, chat?: boolean, updateMany?: boolean) => z.ZodObject<{
4
+ [key: string]: any;
5
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
6
+ [key: string]: any;
7
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
8
+ [key: string]: any;
9
+ }, z.ZodTypeAny, "passthrough">> | z.ZodObject<{
10
+ [key: string]: any;
11
+ }, "strict", z.ZodTypeAny, {
12
+ [x: string]: any;
13
+ }, {
14
+ [x: string]: any;
15
+ }>;