@terreno/api 0.12.2 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/configurationPlugin.js +7 -1
- package/dist/models/consentForm.js +10 -1
- package/dist/openApiEtag.js +0 -7
- package/dist/scriptRunner.js +2 -2
- package/package.json +1 -1
- package/src/configurationPlugin.ts +7 -1
- package/src/models/consentForm.ts +12 -1
- package/src/openApiEtag.ts +0 -7
- package/src/scriptRunner.ts +2 -2
|
@@ -84,7 +84,13 @@ var configurationPlugin = function (schema, options) {
|
|
|
84
84
|
// Add a sentinel field with a unique index to enforce singleton at the DB level.
|
|
85
85
|
// All config documents get _singleton: "config", and the unique index prevents duplicates.
|
|
86
86
|
schema.add({
|
|
87
|
-
_singleton: {
|
|
87
|
+
_singleton: {
|
|
88
|
+
default: "config",
|
|
89
|
+
description: "Sentinel field enforcing singleton constraint",
|
|
90
|
+
immutable: true,
|
|
91
|
+
select: false,
|
|
92
|
+
type: String,
|
|
93
|
+
},
|
|
88
94
|
});
|
|
89
95
|
schema.index({ _singleton: 1 }, { unique: true });
|
|
90
96
|
// Enforce singleton: only one document allowed (application-level guard)
|
|
@@ -6,6 +6,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.ConsentForm = void 0;
|
|
7
7
|
var mongoose_1 = __importDefault(require("mongoose"));
|
|
8
8
|
var plugins_1 = require("../plugins");
|
|
9
|
+
var consentFormTypeMap = {
|
|
10
|
+
agreement: "agreement",
|
|
11
|
+
custom: "custom",
|
|
12
|
+
hipaa: "hipaa",
|
|
13
|
+
privacy: "privacy",
|
|
14
|
+
research: "research",
|
|
15
|
+
terms: "terms",
|
|
16
|
+
};
|
|
17
|
+
var consentFormTypeValues = Object.values(consentFormTypeMap);
|
|
9
18
|
var consentFormSchema = new mongoose_1.default.Schema({
|
|
10
19
|
active: {
|
|
11
20
|
default: false,
|
|
@@ -96,7 +105,7 @@ var consentFormSchema = new mongoose_1.default.Schema({
|
|
|
96
105
|
},
|
|
97
106
|
type: {
|
|
98
107
|
description: "Category of consent form",
|
|
99
|
-
enum:
|
|
108
|
+
enum: consentFormTypeValues,
|
|
100
109
|
required: true,
|
|
101
110
|
type: String,
|
|
102
111
|
},
|
package/dist/openApiEtag.js
CHANGED
|
@@ -11,27 +11,20 @@ var node_crypto_1 = __importDefault(require("node:crypto"));
|
|
|
11
11
|
* to intercept requests to /openapi.json and add conditional request support.
|
|
12
12
|
*/
|
|
13
13
|
var openApiEtagMiddleware = function (req, res, next) {
|
|
14
|
-
// Only handle GET requests to /openapi.json
|
|
15
14
|
if (req.method !== "GET" || req.path !== "/openapi.json") {
|
|
16
15
|
next();
|
|
17
16
|
return;
|
|
18
17
|
}
|
|
19
|
-
// Store original res.json to intercept the response
|
|
20
18
|
var originalJson = res.json.bind(res);
|
|
21
19
|
res.json = function (body) {
|
|
22
|
-
// Generate ETag based on the JSON content
|
|
23
20
|
var jsonString = JSON.stringify(body);
|
|
24
21
|
var etag = "\"".concat(node_crypto_1.default.createHash("sha256").update(jsonString).digest("hex").substring(0, 16), "\"");
|
|
25
|
-
// Set ETag header
|
|
26
22
|
res.set("ETag", etag);
|
|
27
|
-
// Check If-None-Match header for conditional requests
|
|
28
23
|
var ifNoneMatch = req.get("If-None-Match");
|
|
29
24
|
if (ifNoneMatch === etag) {
|
|
30
|
-
// Resource hasn't changed, return 304 Not Modified
|
|
31
25
|
res.status(304).end();
|
|
32
26
|
return res;
|
|
33
27
|
}
|
|
34
|
-
// Resource has changed or no conditional header, return the content
|
|
35
28
|
return originalJson(body);
|
|
36
29
|
};
|
|
37
30
|
next();
|
package/dist/scriptRunner.js
CHANGED
|
@@ -102,7 +102,7 @@ var progressSchema = new mongoose_1.Schema({
|
|
|
102
102
|
message: { description: "Human-readable progress message", type: String },
|
|
103
103
|
percentage: { description: "Progress percentage from 0 to 100", max: 100, min: 0, type: Number },
|
|
104
104
|
stage: { description: "Current stage of the task", type: String },
|
|
105
|
-
}, { _id: false });
|
|
105
|
+
}, { _id: false, strict: "throw" });
|
|
106
106
|
var logSchema = new mongoose_1.Schema({
|
|
107
107
|
level: {
|
|
108
108
|
description: "Log level",
|
|
@@ -112,7 +112,7 @@ var logSchema = new mongoose_1.Schema({
|
|
|
112
112
|
},
|
|
113
113
|
message: { description: "Log message", required: true, type: String },
|
|
114
114
|
timestamp: { description: "When this log entry was created", required: true, type: Date },
|
|
115
|
-
}, { _id: false });
|
|
115
|
+
}, { _id: false, strict: "throw" });
|
|
116
116
|
var backgroundTaskSchema = new mongoose_1.Schema({
|
|
117
117
|
completedAt: {
|
|
118
118
|
description: "When the task completed (success or failure)",
|
package/package.json
CHANGED
|
@@ -139,7 +139,13 @@ export const configurationPlugin = (schema: Schema, options?: ConfigurationPlugi
|
|
|
139
139
|
// Add a sentinel field with a unique index to enforce singleton at the DB level.
|
|
140
140
|
// All config documents get _singleton: "config", and the unique index prevents duplicates.
|
|
141
141
|
schema.add({
|
|
142
|
-
_singleton: {
|
|
142
|
+
_singleton: {
|
|
143
|
+
default: "config",
|
|
144
|
+
description: "Sentinel field enforcing singleton constraint",
|
|
145
|
+
immutable: true,
|
|
146
|
+
select: false,
|
|
147
|
+
type: String,
|
|
148
|
+
},
|
|
143
149
|
});
|
|
144
150
|
schema.index({_singleton: 1}, {unique: true});
|
|
145
151
|
|
|
@@ -2,6 +2,17 @@ import mongoose from "mongoose";
|
|
|
2
2
|
import {createdUpdatedPlugin, findExactlyOne, findOneOrNone, isDeletedPlugin} from "../plugins";
|
|
3
3
|
import type {ConsentFormDocument, ConsentFormModel} from "../types/consentForm";
|
|
4
4
|
|
|
5
|
+
const consentFormTypeMap = {
|
|
6
|
+
agreement: "agreement",
|
|
7
|
+
custom: "custom",
|
|
8
|
+
hipaa: "hipaa",
|
|
9
|
+
privacy: "privacy",
|
|
10
|
+
research: "research",
|
|
11
|
+
terms: "terms",
|
|
12
|
+
} as const;
|
|
13
|
+
|
|
14
|
+
const consentFormTypeValues = Object.values(consentFormTypeMap);
|
|
15
|
+
|
|
5
16
|
const consentFormSchema = new mongoose.Schema<ConsentFormDocument, ConsentFormModel>(
|
|
6
17
|
{
|
|
7
18
|
active: {
|
|
@@ -95,7 +106,7 @@ const consentFormSchema = new mongoose.Schema<ConsentFormDocument, ConsentFormMo
|
|
|
95
106
|
},
|
|
96
107
|
type: {
|
|
97
108
|
description: "Category of consent form",
|
|
98
|
-
enum:
|
|
109
|
+
enum: consentFormTypeValues,
|
|
99
110
|
required: true,
|
|
100
111
|
type: String,
|
|
101
112
|
},
|
package/src/openApiEtag.ts
CHANGED
|
@@ -7,32 +7,25 @@ import type {NextFunction, Request, Response} from "express";
|
|
|
7
7
|
* to intercept requests to /openapi.json and add conditional request support.
|
|
8
8
|
*/
|
|
9
9
|
export const openApiEtagMiddleware = (req: Request, res: Response, next: NextFunction): void => {
|
|
10
|
-
// Only handle GET requests to /openapi.json
|
|
11
10
|
if (req.method !== "GET" || req.path !== "/openapi.json") {
|
|
12
11
|
next();
|
|
13
12
|
return;
|
|
14
13
|
}
|
|
15
14
|
|
|
16
|
-
// Store original res.json to intercept the response
|
|
17
15
|
const originalJson = res.json.bind(res);
|
|
18
16
|
|
|
19
17
|
res.json = (body: any) => {
|
|
20
|
-
// Generate ETag based on the JSON content
|
|
21
18
|
const jsonString = JSON.stringify(body);
|
|
22
19
|
const etag = `"${crypto.createHash("sha256").update(jsonString).digest("hex").substring(0, 16)}"`;
|
|
23
20
|
|
|
24
|
-
// Set ETag header
|
|
25
21
|
res.set("ETag", etag);
|
|
26
22
|
|
|
27
|
-
// Check If-None-Match header for conditional requests
|
|
28
23
|
const ifNoneMatch = req.get("If-None-Match");
|
|
29
24
|
if (ifNoneMatch === etag) {
|
|
30
|
-
// Resource hasn't changed, return 304 Not Modified
|
|
31
25
|
res.status(304).end();
|
|
32
26
|
return res;
|
|
33
27
|
}
|
|
34
28
|
|
|
35
|
-
// Resource has changed or no conditional header, return the content
|
|
36
29
|
return originalJson(body);
|
|
37
30
|
};
|
|
38
31
|
|
package/src/scriptRunner.ts
CHANGED
|
@@ -86,7 +86,7 @@ const progressSchema = new Schema(
|
|
|
86
86
|
percentage: {description: "Progress percentage from 0 to 100", max: 100, min: 0, type: Number},
|
|
87
87
|
stage: {description: "Current stage of the task", type: String},
|
|
88
88
|
},
|
|
89
|
-
{_id: false}
|
|
89
|
+
{_id: false, strict: "throw"}
|
|
90
90
|
);
|
|
91
91
|
|
|
92
92
|
const logSchema = new Schema(
|
|
@@ -100,7 +100,7 @@ const logSchema = new Schema(
|
|
|
100
100
|
message: {description: "Log message", required: true, type: String},
|
|
101
101
|
timestamp: {description: "When this log entry was created", required: true, type: Date},
|
|
102
102
|
},
|
|
103
|
-
{_id: false}
|
|
103
|
+
{_id: false, strict: "throw"}
|
|
104
104
|
);
|
|
105
105
|
|
|
106
106
|
const backgroundTaskSchema = new Schema<
|