@terreno/api 0.7.2 → 0.8.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.
- package/dist/__tests__/{versionCheck.test.js → versionCheckPlugin.test.js} +2 -2
- package/dist/api.d.ts +4 -2
- package/dist/api.js +7 -2
- package/dist/consentApp.d.ts +33 -0
- package/dist/consentApp.js +484 -0
- package/dist/consentApp.test.d.ts +1 -0
- package/dist/consentApp.test.js +1132 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/models/consentForm.d.ts +2 -0
- package/dist/models/consentForm.js +115 -0
- package/dist/models/consentResponse.d.ts +2 -0
- package/dist/models/consentResponse.js +73 -0
- package/dist/models/versionConfig.d.ts +1 -1
- package/dist/openApiValidator.js +2 -0
- package/dist/populate.d.ts +1 -0
- package/dist/populate.js +53 -13
- package/dist/syncConsents.d.ts +67 -0
- package/dist/syncConsents.js +334 -0
- package/dist/syncConsents.test.d.ts +1 -0
- package/dist/syncConsents.test.js +249 -0
- package/dist/terrenoApp.js +6 -5
- package/dist/terrenoPlugin.d.ts +1 -1
- package/dist/types/consentForm.d.ts +32 -0
- package/dist/types/consentForm.js +2 -0
- package/dist/types/consentResponse.d.ts +23 -0
- package/dist/types/consentResponse.js +2 -0
- package/dist/vendor/wesleytodd-openapi/lib/generate-doc.js +9 -2
- package/dist/versionCheckPlugin.d.ts +2 -0
- package/dist/versionCheckPlugin.js +3 -6
- package/package.json +1 -1
- package/src/__tests__/{versionCheck.test.ts → versionCheckPlugin.test.ts} +2 -2
- package/src/api.ts +11 -4
- package/src/consentApp.test.ts +749 -0
- package/src/consentApp.ts +463 -0
- package/src/index.ts +6 -0
- package/src/models/consentForm.ts +123 -0
- package/src/models/consentResponse.ts +78 -0
- package/src/models/versionConfig.ts +1 -1
- package/src/openApiValidator.ts +2 -0
- package/src/populate.ts +33 -0
- package/src/syncConsents.test.ts +124 -0
- package/src/syncConsents.ts +263 -0
- package/src/terrenoApp.ts +6 -6
- package/src/terrenoPlugin.ts +1 -1
- package/src/types/consentForm.ts +41 -0
- package/src/types/consentResponse.ts +34 -0
- package/src/vendor/wesleytodd-openapi/lib/generate-doc.js +8 -2
- package/src/versionCheckPlugin.ts +5 -6
- /package/dist/__tests__/{versionCheck.test.d.ts → versionCheckPlugin.test.d.ts} +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -5,11 +5,14 @@ export * from "./betterAuthApp";
|
|
|
5
5
|
export * from "./betterAuthSetup";
|
|
6
6
|
export * from "./configurationApp";
|
|
7
7
|
export * from "./configurationPlugin";
|
|
8
|
+
export * from "./consentApp";
|
|
8
9
|
export * from "./errors";
|
|
9
10
|
export * from "./expressServer";
|
|
10
11
|
export * from "./githubAuth";
|
|
11
12
|
export * from "./logger";
|
|
12
13
|
export * from "./middleware";
|
|
14
|
+
export * from "./models/consentForm";
|
|
15
|
+
export * from "./models/consentResponse";
|
|
13
16
|
export * from "./models/versionConfig";
|
|
14
17
|
export * from "./notifiers";
|
|
15
18
|
export * from "./openApiBuilder";
|
|
@@ -21,8 +24,11 @@ export * from "./plugins";
|
|
|
21
24
|
export * from "./populate";
|
|
22
25
|
export * from "./scriptRunner";
|
|
23
26
|
export * from "./secretProviders";
|
|
27
|
+
export * from "./syncConsents";
|
|
24
28
|
export * from "./terrenoApp";
|
|
25
29
|
export * from "./terrenoPlugin";
|
|
26
30
|
export * from "./transformers";
|
|
31
|
+
export * from "./types/consentForm";
|
|
32
|
+
export * from "./types/consentResponse";
|
|
27
33
|
export * from "./utils";
|
|
28
34
|
export * from "./versionCheckPlugin";
|
package/dist/index.js
CHANGED
|
@@ -21,11 +21,14 @@ __exportStar(require("./betterAuthApp"), exports);
|
|
|
21
21
|
__exportStar(require("./betterAuthSetup"), exports);
|
|
22
22
|
__exportStar(require("./configurationApp"), exports);
|
|
23
23
|
__exportStar(require("./configurationPlugin"), exports);
|
|
24
|
+
__exportStar(require("./consentApp"), exports);
|
|
24
25
|
__exportStar(require("./errors"), exports);
|
|
25
26
|
__exportStar(require("./expressServer"), exports);
|
|
26
27
|
__exportStar(require("./githubAuth"), exports);
|
|
27
28
|
__exportStar(require("./logger"), exports);
|
|
28
29
|
__exportStar(require("./middleware"), exports);
|
|
30
|
+
__exportStar(require("./models/consentForm"), exports);
|
|
31
|
+
__exportStar(require("./models/consentResponse"), exports);
|
|
29
32
|
__exportStar(require("./models/versionConfig"), exports);
|
|
30
33
|
__exportStar(require("./notifiers"), exports);
|
|
31
34
|
__exportStar(require("./openApiBuilder"), exports);
|
|
@@ -37,8 +40,11 @@ __exportStar(require("./plugins"), exports);
|
|
|
37
40
|
__exportStar(require("./populate"), exports);
|
|
38
41
|
__exportStar(require("./scriptRunner"), exports);
|
|
39
42
|
__exportStar(require("./secretProviders"), exports);
|
|
43
|
+
__exportStar(require("./syncConsents"), exports);
|
|
40
44
|
__exportStar(require("./terrenoApp"), exports);
|
|
41
45
|
__exportStar(require("./terrenoPlugin"), exports);
|
|
42
46
|
__exportStar(require("./transformers"), exports);
|
|
47
|
+
__exportStar(require("./types/consentForm"), exports);
|
|
48
|
+
__exportStar(require("./types/consentResponse"), exports);
|
|
43
49
|
__exportStar(require("./utils"), exports);
|
|
44
50
|
__exportStar(require("./versionCheckPlugin"), exports);
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ConsentForm = void 0;
|
|
7
|
+
var mongoose_1 = __importDefault(require("mongoose"));
|
|
8
|
+
var plugins_1 = require("../plugins");
|
|
9
|
+
var consentFormSchema = new mongoose_1.default.Schema({
|
|
10
|
+
active: {
|
|
11
|
+
default: false,
|
|
12
|
+
description: "Whether this consent form is currently active and available to users",
|
|
13
|
+
type: Boolean,
|
|
14
|
+
},
|
|
15
|
+
agreeButtonText: {
|
|
16
|
+
default: "I Agree",
|
|
17
|
+
description: "Label text for the agreement button",
|
|
18
|
+
type: String,
|
|
19
|
+
},
|
|
20
|
+
allowDecline: {
|
|
21
|
+
default: false,
|
|
22
|
+
description: "Whether users are allowed to decline the consent form",
|
|
23
|
+
type: Boolean,
|
|
24
|
+
},
|
|
25
|
+
captureSignature: {
|
|
26
|
+
default: false,
|
|
27
|
+
description: "Whether to require a drawn or typed signature when the user agrees",
|
|
28
|
+
type: Boolean,
|
|
29
|
+
},
|
|
30
|
+
checkboxes: {
|
|
31
|
+
default: [],
|
|
32
|
+
description: "List of checkboxes the user must interact with before agreeing",
|
|
33
|
+
type: [
|
|
34
|
+
{
|
|
35
|
+
confirmationPrompt: {
|
|
36
|
+
description: "Optional prompt shown when the user checks this checkbox",
|
|
37
|
+
type: String,
|
|
38
|
+
},
|
|
39
|
+
label: {
|
|
40
|
+
description: "Display label for the checkbox",
|
|
41
|
+
required: true,
|
|
42
|
+
type: String,
|
|
43
|
+
},
|
|
44
|
+
required: {
|
|
45
|
+
default: false,
|
|
46
|
+
description: "Whether this checkbox must be checked before the user can agree",
|
|
47
|
+
type: Boolean,
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
},
|
|
52
|
+
content: {
|
|
53
|
+
description: 'Locale-keyed map of Markdown content for this form (e.g. {"en": "# Terms\\n..."})',
|
|
54
|
+
of: String,
|
|
55
|
+
required: true,
|
|
56
|
+
type: Map,
|
|
57
|
+
},
|
|
58
|
+
declineButtonText: {
|
|
59
|
+
default: "Decline",
|
|
60
|
+
description: "Label text for the decline button (only shown when allowDecline is true)",
|
|
61
|
+
type: String,
|
|
62
|
+
},
|
|
63
|
+
defaultLocale: {
|
|
64
|
+
default: "en",
|
|
65
|
+
description: "Default locale to use when the requested locale is not available",
|
|
66
|
+
type: String,
|
|
67
|
+
},
|
|
68
|
+
order: {
|
|
69
|
+
default: 0,
|
|
70
|
+
description: "Display order relative to other consent forms (lower numbers appear first)",
|
|
71
|
+
required: true,
|
|
72
|
+
type: Number,
|
|
73
|
+
},
|
|
74
|
+
required: {
|
|
75
|
+
default: true,
|
|
76
|
+
description: "Whether users must complete this form before accessing the application",
|
|
77
|
+
type: Boolean,
|
|
78
|
+
},
|
|
79
|
+
requireScrollToBottom: {
|
|
80
|
+
default: false,
|
|
81
|
+
description: "Whether users must scroll to the bottom of the form content before agreeing",
|
|
82
|
+
type: Boolean,
|
|
83
|
+
},
|
|
84
|
+
slug: {
|
|
85
|
+
description: "URL-safe identifier for this form, combined with version to uniquely identify a form",
|
|
86
|
+
index: true,
|
|
87
|
+
required: true,
|
|
88
|
+
trim: true,
|
|
89
|
+
type: String,
|
|
90
|
+
},
|
|
91
|
+
title: {
|
|
92
|
+
description: "Human-readable title of the consent form",
|
|
93
|
+
required: true,
|
|
94
|
+
trim: true,
|
|
95
|
+
type: String,
|
|
96
|
+
},
|
|
97
|
+
type: {
|
|
98
|
+
description: "Category of consent form",
|
|
99
|
+
enum: ["agreement", "privacy", "hipaa", "research", "terms", "custom"],
|
|
100
|
+
required: true,
|
|
101
|
+
type: String,
|
|
102
|
+
},
|
|
103
|
+
version: {
|
|
104
|
+
default: 1,
|
|
105
|
+
description: "Version number of this form. Incrementing the version requires users to re-consent",
|
|
106
|
+
required: true,
|
|
107
|
+
type: Number,
|
|
108
|
+
},
|
|
109
|
+
}, { strict: "throw", toJSON: { virtuals: true }, toObject: { virtuals: true } });
|
|
110
|
+
consentFormSchema.index({ slug: 1, version: 1 }, { unique: true });
|
|
111
|
+
consentFormSchema.plugin(plugins_1.createdUpdatedPlugin);
|
|
112
|
+
consentFormSchema.plugin(plugins_1.isDeletedPlugin);
|
|
113
|
+
consentFormSchema.plugin(plugins_1.findOneOrNone);
|
|
114
|
+
consentFormSchema.plugin(plugins_1.findExactlyOne);
|
|
115
|
+
exports.ConsentForm = mongoose_1.default.model("ConsentForm", consentFormSchema);
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ConsentResponse = void 0;
|
|
7
|
+
var mongoose_1 = __importDefault(require("mongoose"));
|
|
8
|
+
var plugins_1 = require("../plugins");
|
|
9
|
+
var consentResponseSchema = new mongoose_1.default.Schema({
|
|
10
|
+
agreed: {
|
|
11
|
+
description: "Whether the user agreed (true) or declined (false) the consent form",
|
|
12
|
+
required: true,
|
|
13
|
+
type: Boolean,
|
|
14
|
+
},
|
|
15
|
+
agreedAt: {
|
|
16
|
+
description: "Timestamp when the user submitted their agreement or declination",
|
|
17
|
+
required: true,
|
|
18
|
+
type: Date,
|
|
19
|
+
},
|
|
20
|
+
checkboxValues: {
|
|
21
|
+
description: "Map of checkbox index to boolean indicating whether each checkbox was checked",
|
|
22
|
+
of: Boolean,
|
|
23
|
+
type: Map,
|
|
24
|
+
},
|
|
25
|
+
consentFormId: {
|
|
26
|
+
description: "Reference to the ConsentForm that was responded to",
|
|
27
|
+
ref: "ConsentForm",
|
|
28
|
+
required: true,
|
|
29
|
+
type: mongoose_1.default.Schema.Types.ObjectId,
|
|
30
|
+
},
|
|
31
|
+
contentSnapshot: {
|
|
32
|
+
description: "Snapshot of the form content in the user's locale at the time of response",
|
|
33
|
+
type: String,
|
|
34
|
+
},
|
|
35
|
+
formVersionSnapshot: {
|
|
36
|
+
description: "Version number of the form at the time the user responded",
|
|
37
|
+
type: Number,
|
|
38
|
+
},
|
|
39
|
+
ipAddress: {
|
|
40
|
+
description: "IP address of the user at the time of response, captured for audit purposes",
|
|
41
|
+
type: String,
|
|
42
|
+
},
|
|
43
|
+
locale: {
|
|
44
|
+
description: "Locale code of the content version the user viewed when responding",
|
|
45
|
+
required: true,
|
|
46
|
+
type: String,
|
|
47
|
+
},
|
|
48
|
+
signature: {
|
|
49
|
+
description: "Base64-encoded signature image or typed signature text, if captured",
|
|
50
|
+
type: String,
|
|
51
|
+
},
|
|
52
|
+
signedAt: {
|
|
53
|
+
description: "Timestamp when the user provided their signature",
|
|
54
|
+
type: Date,
|
|
55
|
+
},
|
|
56
|
+
userAgent: {
|
|
57
|
+
description: "User-agent string of the browser or app used to submit the response",
|
|
58
|
+
type: String,
|
|
59
|
+
},
|
|
60
|
+
userId: {
|
|
61
|
+
description: "Reference to the User who submitted this response",
|
|
62
|
+
index: true,
|
|
63
|
+
ref: "User",
|
|
64
|
+
required: true,
|
|
65
|
+
type: mongoose_1.default.Schema.Types.ObjectId,
|
|
66
|
+
},
|
|
67
|
+
}, { strict: "throw", toJSON: { virtuals: true }, toObject: { virtuals: true } });
|
|
68
|
+
consentResponseSchema.index({ consentFormId: 1, userId: 1 });
|
|
69
|
+
consentResponseSchema.plugin(plugins_1.createdUpdatedPlugin);
|
|
70
|
+
consentResponseSchema.plugin(plugins_1.isDeletedPlugin);
|
|
71
|
+
consentResponseSchema.plugin(plugins_1.findOneOrNone);
|
|
72
|
+
consentResponseSchema.plugin(plugins_1.findExactlyOne);
|
|
73
|
+
exports.ConsentResponse = mongoose_1.default.model("ConsentResponse", consentResponseSchema);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import mongoose, { type Document } from "mongoose";
|
|
2
|
-
import {
|
|
2
|
+
import type { APIErrorConstructor } from "../errors";
|
|
3
3
|
export interface VersionConfigDocument extends mongoose.Document {
|
|
4
4
|
webWarningVersion: number;
|
|
5
5
|
webRequiredVersion: number;
|
package/dist/openApiValidator.js
CHANGED
|
@@ -113,6 +113,7 @@ var ajv_formats_1 = __importDefault(require("ajv-formats"));
|
|
|
113
113
|
var mongoose_to_swagger_1 = __importDefault(require("mongoose-to-swagger"));
|
|
114
114
|
var errors_1 = require("./errors");
|
|
115
115
|
var logger_1 = require("./logger");
|
|
116
|
+
var populate_1 = require("./populate");
|
|
116
117
|
// Whether configureOpenApiValidator() has been called
|
|
117
118
|
var isConfigured = false;
|
|
118
119
|
// Global validator configuration - can be modified at runtime
|
|
@@ -601,6 +602,7 @@ var m2sOptions = {
|
|
|
601
602
|
*/
|
|
602
603
|
function getSchemaFromModel(model) {
|
|
603
604
|
var modelSwagger = (0, mongoose_to_swagger_1.default)(model, m2sOptions);
|
|
605
|
+
(0, populate_1.fixMixedFields)(model.schema, modelSwagger.properties);
|
|
604
606
|
return modelSwagger.properties;
|
|
605
607
|
}
|
|
606
608
|
/**
|
package/dist/populate.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export type PopulatePath = {
|
|
|
4
4
|
openApiComponent?: any;
|
|
5
5
|
fields?: string[];
|
|
6
6
|
};
|
|
7
|
+
export declare const fixMixedFields: (schema: any, properties: Record<string, any>) => void;
|
|
7
8
|
export declare function getOpenApiSpecForModel(model: any, { populatePaths, extraModelProperties, }?: {
|
|
8
9
|
populatePaths?: PopulatePath[];
|
|
9
10
|
extraModelProperties?: any;
|
package/dist/populate.js
CHANGED
|
@@ -50,6 +50,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
50
50
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
51
51
|
};
|
|
52
52
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
53
|
+
exports.fixMixedFields = void 0;
|
|
53
54
|
exports.getOpenApiSpecForModel = getOpenApiSpecForModel;
|
|
54
55
|
exports.unpopulate = unpopulate;
|
|
55
56
|
var isArray_1 = __importDefault(require("lodash/isArray"));
|
|
@@ -124,13 +125,52 @@ function getPathInSchema(schema, path) {
|
|
|
124
125
|
return fullPath;
|
|
125
126
|
}
|
|
126
127
|
// Replaces populated properties with the populated schema.
|
|
128
|
+
// Recursively walks a Mongoose schema and fixes any Mixed fields in the
|
|
129
|
+
// OpenAPI properties so they use an empty schema (accepts any type) instead
|
|
130
|
+
// of the `{type: "object", properties: {}}` that mongoose-to-swagger emits.
|
|
131
|
+
var fixMixedFields = function (schema, properties) {
|
|
132
|
+
var e_1, _a;
|
|
133
|
+
var _b, _c, _d;
|
|
134
|
+
if (!properties || !schema) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
try {
|
|
138
|
+
for (var _e = __values(Object.keys(properties)), _f = _e.next(); !_f.done; _f = _e.next()) {
|
|
139
|
+
var key = _f.value;
|
|
140
|
+
var schemaPath = schema.path(key);
|
|
141
|
+
if (!schemaPath) {
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
// Direct Mixed field
|
|
145
|
+
if (schemaPath.instance === "Mixed") {
|
|
146
|
+
properties[key] = { description: (_b = properties[key]) === null || _b === void 0 ? void 0 : _b.description };
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
// Array of sub-documents — check each sub-field for Mixed
|
|
150
|
+
if (schemaPath.instance === "Array" &&
|
|
151
|
+
schemaPath.schema &&
|
|
152
|
+
((_d = (_c = properties[key]) === null || _c === void 0 ? void 0 : _c.items) === null || _d === void 0 ? void 0 : _d.properties)) {
|
|
153
|
+
(0, exports.fixMixedFields)(schemaPath.schema, properties[key].items.properties);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
158
|
+
finally {
|
|
159
|
+
try {
|
|
160
|
+
if (_f && !_f.done && (_a = _e.return)) _a.call(_e);
|
|
161
|
+
}
|
|
162
|
+
finally { if (e_1) throw e_1.error; }
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
exports.fixMixedFields = fixMixedFields;
|
|
127
166
|
function getOpenApiSpecForModel(model, _a) {
|
|
128
|
-
var
|
|
167
|
+
var e_2, _b, _c, e_3, _d, e_4, _e, e_5, _f;
|
|
129
168
|
var _g, _h, _j, _k;
|
|
130
169
|
var _l = _a === void 0 ? {} : _a, populatePaths = _l.populatePaths, extraModelProperties = _l.extraModelProperties;
|
|
131
170
|
var modelSwagger = (0, mongoose_to_swagger_1.default)(model, {
|
|
132
171
|
props: ["required", "enum"],
|
|
133
172
|
});
|
|
173
|
+
(0, exports.fixMixedFields)(model.schema, modelSwagger.properties);
|
|
134
174
|
if (populatePaths && (0, isArray_1.default)(populatePaths)) {
|
|
135
175
|
try {
|
|
136
176
|
for (var populatePaths_1 = __values(populatePaths), populatePaths_1_1 = populatePaths_1.next(); !populatePaths_1_1.done; populatePaths_1_1 = populatePaths_1.next()) {
|
|
@@ -191,12 +231,12 @@ function getOpenApiSpecForModel(model, _a) {
|
|
|
191
231
|
}
|
|
192
232
|
}
|
|
193
233
|
}
|
|
194
|
-
catch (
|
|
234
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
195
235
|
finally {
|
|
196
236
|
try {
|
|
197
237
|
if (populatePaths_1_1 && !populatePaths_1_1.done && (_b = populatePaths_1.return)) _b.call(populatePaths_1);
|
|
198
238
|
}
|
|
199
|
-
finally { if (
|
|
239
|
+
finally { if (e_2) throw e_2.error; }
|
|
200
240
|
}
|
|
201
241
|
}
|
|
202
242
|
try {
|
|
@@ -212,12 +252,12 @@ function getOpenApiSpecForModel(model, _a) {
|
|
|
212
252
|
};
|
|
213
253
|
}
|
|
214
254
|
}
|
|
215
|
-
catch (
|
|
255
|
+
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
216
256
|
finally {
|
|
217
257
|
try {
|
|
218
258
|
if (_o && !_o.done && (_d = _m.return)) _d.call(_m);
|
|
219
259
|
}
|
|
220
|
-
finally { if (
|
|
260
|
+
finally { if (e_3) throw e_3.error; }
|
|
221
261
|
}
|
|
222
262
|
// Check subschemas for virtuals (one level deep)
|
|
223
263
|
if (model.schema.childSchemas.length > 0) {
|
|
@@ -225,7 +265,7 @@ function getOpenApiSpecForModel(model, _a) {
|
|
|
225
265
|
for (var _p = __values(model.schema.childSchemas), _q = _p.next(); !_q.done; _q = _p.next()) {
|
|
226
266
|
var childSchema = _q.value;
|
|
227
267
|
try {
|
|
228
|
-
for (var _r = (
|
|
268
|
+
for (var _r = (e_5 = void 0, __values(Object.keys(childSchema.schema.virtuals))), _s = _r.next(); !_s.done; _s = _r.next()) {
|
|
229
269
|
var virtual = _s.value;
|
|
230
270
|
if (virtual === "id" || virtual === "__v") {
|
|
231
271
|
continue;
|
|
@@ -235,21 +275,21 @@ function getOpenApiSpecForModel(model, _a) {
|
|
|
235
275
|
};
|
|
236
276
|
}
|
|
237
277
|
}
|
|
238
|
-
catch (
|
|
278
|
+
catch (e_5_1) { e_5 = { error: e_5_1 }; }
|
|
239
279
|
finally {
|
|
240
280
|
try {
|
|
241
281
|
if (_s && !_s.done && (_f = _r.return)) _f.call(_r);
|
|
242
282
|
}
|
|
243
|
-
finally { if (
|
|
283
|
+
finally { if (e_5) throw e_5.error; }
|
|
244
284
|
}
|
|
245
285
|
}
|
|
246
286
|
}
|
|
247
|
-
catch (
|
|
287
|
+
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
248
288
|
finally {
|
|
249
289
|
try {
|
|
250
290
|
if (_q && !_q.done && (_e = _p.return)) _e.call(_p);
|
|
251
291
|
}
|
|
252
|
-
finally { if (
|
|
292
|
+
finally { if (e_4) throw e_4.error; }
|
|
253
293
|
}
|
|
254
294
|
}
|
|
255
295
|
return {
|
|
@@ -268,7 +308,7 @@ function unpopulate(doc, path) {
|
|
|
268
308
|
var pathParts = path.split(".");
|
|
269
309
|
// Recursive because we need to support nested paths.
|
|
270
310
|
var recursiveUnpopulate = function (current, parts) {
|
|
271
|
-
var
|
|
311
|
+
var e_6, _a;
|
|
272
312
|
var _b;
|
|
273
313
|
var part = parts[0];
|
|
274
314
|
// If the path doesn't exist, return the original doc
|
|
@@ -297,12 +337,12 @@ function unpopulate(doc, path) {
|
|
|
297
337
|
recursiveUnpopulate(item, parts.slice(1)); // Recursively handle each item in the array
|
|
298
338
|
}
|
|
299
339
|
}
|
|
300
|
-
catch (
|
|
340
|
+
catch (e_6_1) { e_6 = { error: e_6_1 }; }
|
|
301
341
|
finally {
|
|
302
342
|
try {
|
|
303
343
|
if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
|
|
304
344
|
}
|
|
305
|
-
finally { if (
|
|
345
|
+
finally { if (e_6) throw e_6.error; }
|
|
306
346
|
}
|
|
307
347
|
}
|
|
308
348
|
else {
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sync consent form definitions from code to the database.
|
|
3
|
+
*
|
|
4
|
+
* Compares the provided definitions (keyed by slug) against what's in the database
|
|
5
|
+
* and creates, updates, or deactivates forms to match. When content changes, a new
|
|
6
|
+
* version is published so users are prompted to re-consent.
|
|
7
|
+
*/
|
|
8
|
+
import type { ConsentFormType } from "./types/consentForm";
|
|
9
|
+
export interface ConsentFormDefinition {
|
|
10
|
+
title: string;
|
|
11
|
+
type: ConsentFormType;
|
|
12
|
+
content: Record<string, string>;
|
|
13
|
+
order?: number;
|
|
14
|
+
required?: boolean;
|
|
15
|
+
requireScrollToBottom?: boolean;
|
|
16
|
+
captureSignature?: boolean;
|
|
17
|
+
agreeButtonText?: string;
|
|
18
|
+
allowDecline?: boolean;
|
|
19
|
+
declineButtonText?: string;
|
|
20
|
+
defaultLocale?: string;
|
|
21
|
+
checkboxes?: Array<{
|
|
22
|
+
label: string;
|
|
23
|
+
required?: boolean;
|
|
24
|
+
confirmationPrompt?: string;
|
|
25
|
+
}>;
|
|
26
|
+
}
|
|
27
|
+
export interface SyncConsentsOptions {
|
|
28
|
+
/** Deactivate database forms whose slugs are not in the definitions. Default: false */
|
|
29
|
+
deactivateRemoved?: boolean;
|
|
30
|
+
/** If true, log what would change without writing to the database. Default: false */
|
|
31
|
+
dryRun?: boolean;
|
|
32
|
+
}
|
|
33
|
+
export interface SyncConsentsResult {
|
|
34
|
+
created: string[];
|
|
35
|
+
updated: string[];
|
|
36
|
+
deactivated: string[];
|
|
37
|
+
unchanged: string[];
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Sync consent form definitions to the database.
|
|
41
|
+
*
|
|
42
|
+
* @param definitions - Map of slug to consent form definition
|
|
43
|
+
* @param options - Sync options
|
|
44
|
+
* @returns Summary of what was created, updated, deactivated, or unchanged
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* import {syncConsents} from "@terreno/api";
|
|
49
|
+
*
|
|
50
|
+
* await syncConsents({
|
|
51
|
+
* "terms-of-service": {
|
|
52
|
+
* title: "Terms of Service",
|
|
53
|
+
* type: "terms",
|
|
54
|
+
* content: {"en": "# Terms\n...", "es": "# Términos\n..."},
|
|
55
|
+
* required: true,
|
|
56
|
+
* order: 1,
|
|
57
|
+
* },
|
|
58
|
+
* "privacy-policy": {
|
|
59
|
+
* title: "Privacy Policy",
|
|
60
|
+
* type: "privacy",
|
|
61
|
+
* content: {"en": "# Privacy\n..."},
|
|
62
|
+
* order: 2,
|
|
63
|
+
* },
|
|
64
|
+
* });
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export declare const syncConsents: (definitions: Record<string, ConsentFormDefinition>, options?: SyncConsentsOptions) => Promise<SyncConsentsResult>;
|