@oondemand/oon-core-back 0.5.6 → 0.6.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/package.json +2 -3
- package/src/api/core.routes.js +0 -2
- package/src/boot/createApp.js +0 -7
- package/src/boot/database.js +0 -34
- package/src/boot/loadCentral.js +0 -6
- package/src/capabilities/pdfRendering.js +9 -9
- package/src/core/define.js +1 -6
- package/src/core/models/Sistema.js +2 -10
- package/src/core/registry.js +0 -8
- package/src/deploy/render.js +0 -2
- package/src/deploy/templates/secret.yaml +0 -2
- package/src/index.js +2 -16
- package/src/manifest/appManifest.js +5 -22
- package/bin/integration-worker.js +0 -31
- package/src/modules/integrations/index.js +0 -26
- package/src/modules/integrations/models.js +0 -112
- package/src/modules/integrations/registry.js +0 -171
- package/src/modules/integrations/routes.js +0 -343
- package/src/modules/integrations/runtime/inbox.js +0 -134
- package/src/modules/integrations/runtime/lease.js +0 -94
- package/src/modules/integrations/runtime/outbox.js +0 -199
- package/src/modules/integrations/runtime/sync.js +0 -85
- package/src/modules/integrations/runtime/tracking.js +0 -89
- package/src/modules/integrations/runtime/utils.js +0 -71
- package/src/modules/integrations/runtime.js +0 -10
- package/src/modules/integrations/sanitizer.js +0 -96
- package/src/modules/integrations/worker.js +0 -56
- package/src/modules/omie/client.js +0 -282
- package/src/modules/omie/definitions.js +0 -212
- package/src/modules/omie/index.js +0 -33
- package/src/modules/omie/models.js +0 -377
- package/src/modules/omie/provider.js +0 -529
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oondemand/oon-core-back",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/oondemand/oon-platform.git",
|
|
@@ -9,8 +9,7 @@
|
|
|
9
9
|
"description": "Core runtime para Centrais Oon: Model Registry, CRUD/RBAC automáticos, módulos opinativos e capabilities nativas.",
|
|
10
10
|
"main": "src/index.js",
|
|
11
11
|
"bin": {
|
|
12
|
-
"oonCore-back": "bin/cli.js"
|
|
13
|
-
"oonCore-integration-worker": "bin/integration-worker.js"
|
|
12
|
+
"oonCore-back": "bin/cli.js"
|
|
14
13
|
},
|
|
15
14
|
"files": [
|
|
16
15
|
"bin",
|
package/src/api/core.routes.js
CHANGED
|
@@ -261,7 +261,6 @@ router.get("/metadata", (_req, res) => {
|
|
|
261
261
|
collections: registry.listCollections(),
|
|
262
262
|
documents: registry.listDocuments(),
|
|
263
263
|
pipelines: registry.listPipelines(),
|
|
264
|
-
integrations: registry.listIntegrations(),
|
|
265
264
|
features: registry.listFeatures(),
|
|
266
265
|
menus: registry.listMenus(),
|
|
267
266
|
});
|
|
@@ -276,7 +275,6 @@ router.get("/models/:name", (req, res) => {
|
|
|
276
275
|
router.get("/collections", (_req, res) => res.json({ results: registry.listCollections() }));
|
|
277
276
|
router.get("/documents", (_req, res) => res.json({ results: registry.listDocuments() }));
|
|
278
277
|
router.get("/pipelines", (_req, res) => res.json({ results: registry.listPipelines() }));
|
|
279
|
-
router.get("/integrations", (_req, res) => res.json({ results: registry.listIntegrations() }));
|
|
280
278
|
router.get("/permissions", (_req, res) => {
|
|
281
279
|
const permissions = registry.listModels().flatMap((entry) => {
|
|
282
280
|
const roles = entry.definition.crud?.roles || {};
|
package/src/boot/createApp.js
CHANGED
|
@@ -9,7 +9,6 @@ const correlationId = require("../core/middlewares/correlationId");
|
|
|
9
9
|
const requestLog = require("../core/middlewares/requestLog");
|
|
10
10
|
const errorMiddleware = require("../core/middlewares/error");
|
|
11
11
|
const { buildModelRouter } = require("../core/factories/modelRouter");
|
|
12
|
-
const { buildIntegrationRouter, integrationsEnabled } = require("../modules/integrations");
|
|
13
12
|
|
|
14
13
|
const coreRoutes = require("../api/core.routes");
|
|
15
14
|
const accessRoutes = require("../api/access.routes");
|
|
@@ -59,12 +58,6 @@ function createApp() {
|
|
|
59
58
|
app.use("/core", coreRoutes);
|
|
60
59
|
if (transactionalEmail.enabled()) app.use("/core/transactional-email", transactionalEmail.buildRouter());
|
|
61
60
|
|
|
62
|
-
if (integrationsEnabled(ctx.config)) {
|
|
63
|
-
const integrationRouter = buildIntegrationRouter();
|
|
64
|
-
app.use("/integrations", integrationRouter);
|
|
65
|
-
app.use("/integracoes", integrationRouter);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
61
|
app.use(requestLog);
|
|
69
62
|
|
|
70
63
|
for (const entry of registry.listModels()) {
|
package/src/boot/database.js
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
const mongoose = require("mongoose");
|
|
2
2
|
const registry = require("../core/registry");
|
|
3
|
-
const ctx = require("../core/context");
|
|
4
|
-
const { getIntegrationModels } = require("../modules/integrations/models");
|
|
5
|
-
const { listIntegrationProviders } = require("../modules/integrations/registry");
|
|
6
|
-
const { getOmieModels, omieEnabled } = require("../modules/omie");
|
|
7
3
|
|
|
8
4
|
function buildMongoUri() {
|
|
9
5
|
const cfg = {
|
|
@@ -73,38 +69,10 @@ async function syncDeclaredIndexes(entries = registry.listModels()) {
|
|
|
73
69
|
return results;
|
|
74
70
|
}
|
|
75
71
|
|
|
76
|
-
async function syncTechnicalIndexes() {
|
|
77
|
-
const integrationsEnabled = Boolean(
|
|
78
|
-
ctx.config.appManifest?.modules?.integrations
|
|
79
|
-
|| ctx.config.modules?.integrations
|
|
80
|
-
|| listIntegrationProviders().length,
|
|
81
|
-
);
|
|
82
|
-
if (!shouldSyncDeclaredIndexes() || !integrationsEnabled) return [];
|
|
83
|
-
|
|
84
|
-
const models = Object.values(getIntegrationModels());
|
|
85
|
-
if (omieEnabled(ctx.config)) models.push(...Object.values(getOmieModels()));
|
|
86
|
-
|
|
87
|
-
const results = [];
|
|
88
|
-
for (const model of models) {
|
|
89
|
-
const dropped = await model.syncIndexes();
|
|
90
|
-
const normalized = Array.isArray(dropped) ? dropped : [];
|
|
91
|
-
results.push({ model: model.modelName, dropped: normalized });
|
|
92
|
-
if (normalized.length) {
|
|
93
|
-
console.log(`[OonCore] Índices técnicos obsoletos removidos de ${model.modelName}: ${normalized.join(", ")}`);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
return results;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
async function syncIntegrationIndexes() {
|
|
100
|
-
return syncTechnicalIndexes();
|
|
101
|
-
}
|
|
102
|
-
|
|
103
72
|
async function connectDB() {
|
|
104
73
|
const uri = buildMongoUri();
|
|
105
74
|
await mongoose.connect(uri, connectionOptions());
|
|
106
75
|
await syncDeclaredIndexes();
|
|
107
|
-
await syncTechnicalIndexes();
|
|
108
76
|
console.log(`Conectado ao MongoDB (${databaseLabel(uri)})`);
|
|
109
77
|
return mongoose.connection;
|
|
110
78
|
}
|
|
@@ -116,6 +84,4 @@ module.exports = {
|
|
|
116
84
|
databaseLabel,
|
|
117
85
|
shouldSyncDeclaredIndexes,
|
|
118
86
|
syncDeclaredIndexes,
|
|
119
|
-
syncIntegrationIndexes,
|
|
120
|
-
syncTechnicalIndexes,
|
|
121
87
|
};
|
package/src/boot/loadCentral.js
CHANGED
|
@@ -15,7 +15,6 @@ const {
|
|
|
15
15
|
PROCESS_MANIFEST_FILENAME,
|
|
16
16
|
loadProcessManifest,
|
|
17
17
|
} = require("../manifest/processManifest");
|
|
18
|
-
const { ensureOmieProviderRegistered } = require("../modules/omie");
|
|
19
18
|
|
|
20
19
|
const DOMAIN_DIRS = [
|
|
21
20
|
"models",
|
|
@@ -24,8 +23,6 @@ const DOMAIN_DIRS = [
|
|
|
24
23
|
"routes",
|
|
25
24
|
"pipelines",
|
|
26
25
|
"documents",
|
|
27
|
-
"integrations",
|
|
28
|
-
"mappings",
|
|
29
26
|
"hooks",
|
|
30
27
|
];
|
|
31
28
|
|
|
@@ -105,9 +102,6 @@ function loadCentral(cwd = process.cwd()) {
|
|
|
105
102
|
if (fs.existsSync(full)) requireDir(full);
|
|
106
103
|
}
|
|
107
104
|
|
|
108
|
-
// O adaptador nativo é montado depois das declarações da Central. Assim,
|
|
109
|
-
// endpoints, mappings, listas e ações permanecem fora do pacote técnico.
|
|
110
|
-
ensureOmieProviderRegistered(ctx.config);
|
|
111
105
|
return ctx.config;
|
|
112
106
|
}
|
|
113
107
|
|
|
@@ -58,7 +58,7 @@ function pdfError(message, options) {
|
|
|
58
58
|
return new PdfRenderingError(message, options);
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
function
|
|
61
|
+
function implementationConfig() {
|
|
62
62
|
const baseUrl = String(process.env.OON_CAPABILITY_PDF_RENDERING_URL || "").replace(/\/+$/, "");
|
|
63
63
|
if (!baseUrl) throw pdfError("A capability pdfRendering não está resolvida neste ambiente.", {
|
|
64
64
|
code: "PDF_RENDERING_UNAVAILABLE", statusCode: 503,
|
|
@@ -75,7 +75,7 @@ function validatePdf(input) {
|
|
|
75
75
|
const pdf = Buffer.isBuffer(input) ? input : Buffer.from(input || "");
|
|
76
76
|
const maxBytes = numberLimit("OON_PDF_RENDERING_MAX_OUTPUT_BYTES", 20 * 1024 * 1024);
|
|
77
77
|
if (pdf.length < 8 || pdf.length > maxBytes || !pdf.subarray(0, 5).equals(Buffer.from("%PDF-"))) {
|
|
78
|
-
throw pdfError("
|
|
78
|
+
throw pdfError("A implementação retornou um PDF inválido ou acima do limite.", {
|
|
79
79
|
code: "PDF_RENDERING_INVALID_OUTPUT", details: { outputBytes: pdf.length, maxBytes },
|
|
80
80
|
});
|
|
81
81
|
}
|
|
@@ -88,7 +88,7 @@ function traceContext(context = {}) {
|
|
|
88
88
|
tenantId: String(context.tenantId || "unknown").slice(0, 128),
|
|
89
89
|
appCode: String(context.appCode || process.env.APP_CODE || "unknown").slice(0, 128),
|
|
90
90
|
environment: String(context.environment || process.env.APP_ENVIRONMENT || "unknown").slice(0, 64),
|
|
91
|
-
|
|
91
|
+
operationId: String(context.operationId || "").slice(0, 128),
|
|
92
92
|
};
|
|
93
93
|
}
|
|
94
94
|
|
|
@@ -109,11 +109,11 @@ function formFor(html, options) {
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
function defaultTransport({ html, options, trace, signal, fetchImpl = globalThis.fetch }) {
|
|
112
|
-
const
|
|
113
|
-
return fetchImpl(`${
|
|
112
|
+
const implementation = implementationConfig();
|
|
113
|
+
return fetchImpl(`${implementation.baseUrl}/forms/chromium/convert/html`, {
|
|
114
114
|
method: "POST",
|
|
115
115
|
headers: {
|
|
116
|
-
authorization: `Basic ${Buffer.from(`${
|
|
116
|
+
authorization: `Basic ${Buffer.from(`${implementation.username}:${implementation.password}`).toString("base64")}`,
|
|
117
117
|
"Gotenberg-Trace": trace.correlationId,
|
|
118
118
|
"X-Oon-App-Code": trace.appCode,
|
|
119
119
|
"X-Oon-Environment": trace.environment,
|
|
@@ -161,11 +161,11 @@ async function render(input = {}, context = {}) {
|
|
|
161
161
|
await acquire();
|
|
162
162
|
try {
|
|
163
163
|
const response = await configuredTransport({ html, options, trace, signal: controller.signal, fetchImpl: context.fetchImpl });
|
|
164
|
-
if (!response?.ok) throw pdfError(`
|
|
165
|
-
code: "
|
|
164
|
+
if (!response?.ok) throw pdfError(`Implementação de pdfRendering indisponível (HTTP ${response?.status || 502}).`, {
|
|
165
|
+
code: "PDF_RENDERING_IMPLEMENTATION_ERROR", statusCode: 502,
|
|
166
166
|
});
|
|
167
167
|
const pdf = validatePdf(Buffer.from(await response.arrayBuffer()));
|
|
168
|
-
console.info(JSON.stringify({ event: "pdfRendering.completed", ...trace, durationMs: Date.now() - startedAt, inputBytes, outputBytes: pdf.length,
|
|
168
|
+
console.info(JSON.stringify({ event: "pdfRendering.completed", ...trace, durationMs: Date.now() - startedAt, inputBytes, outputBytes: pdf.length, implementationVersion: process.env.OON_CAPABILITY_PDF_RENDERING_VERSION || "unknown" }));
|
|
169
169
|
return pdf;
|
|
170
170
|
} catch (error) {
|
|
171
171
|
const normalized = error instanceof PdfRenderingError ? error : pdfError(
|
package/src/core/define.js
CHANGED
|
@@ -149,10 +149,6 @@ function definePipeline(name, config) {
|
|
|
149
149
|
return registry.registerPipeline(name, { name, ...config });
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
function defineOmieMapping(name, config) {
|
|
153
|
-
return registry.registerOmieMapping(name, { name, ...config });
|
|
154
|
-
}
|
|
155
|
-
|
|
156
152
|
function defineRoutes(basePath, builder) {
|
|
157
153
|
const expressRouter = express.Router();
|
|
158
154
|
|
|
@@ -196,6 +192,5 @@ module.exports = {
|
|
|
196
192
|
defineCollection,
|
|
197
193
|
defineDocument,
|
|
198
194
|
definePipeline,
|
|
199
|
-
defineOmieMapping,
|
|
200
195
|
defineRoutes,
|
|
201
|
-
};
|
|
196
|
+
};
|
|
@@ -1,20 +1,12 @@
|
|
|
1
1
|
const mongoose = require("mongoose");
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Configuração singleton da Central
|
|
4
|
+
* Configuração singleton da Central. Credenciais funcionais pertencem às
|
|
5
|
+
* capabilities ou ao domínio do app, nunca a adaptadores nativos do Core.
|
|
5
6
|
* Model interna do Core. O cliente estende via `central.config.js`.
|
|
6
7
|
*/
|
|
7
|
-
const omieSchema = new mongoose.Schema(
|
|
8
|
-
{
|
|
9
|
-
id_conta_corrente: { type: Number },
|
|
10
|
-
codigo_categoria: { type: String },
|
|
11
|
-
},
|
|
12
|
-
{ _id: false }
|
|
13
|
-
);
|
|
14
|
-
|
|
15
8
|
const sistemaSchema = new mongoose.Schema(
|
|
16
9
|
{
|
|
17
|
-
omie: omieSchema,
|
|
18
10
|
openIaKey: String,
|
|
19
11
|
appKey: String,
|
|
20
12
|
sendgrid_api_key: { type: String },
|
package/src/core/registry.js
CHANGED
|
@@ -15,8 +15,6 @@ const store = {
|
|
|
15
15
|
collections: new Map(),
|
|
16
16
|
documents: new Map(),
|
|
17
17
|
pipelines: new Map(),
|
|
18
|
-
omieMappings: new Map(),
|
|
19
|
-
integrations: new Map(),
|
|
20
18
|
menus: [],
|
|
21
19
|
features: new Map(),
|
|
22
20
|
};
|
|
@@ -82,8 +80,6 @@ function reset() {
|
|
|
82
80
|
store.collections.clear();
|
|
83
81
|
store.documents.clear();
|
|
84
82
|
store.pipelines.clear();
|
|
85
|
-
store.omieMappings.clear();
|
|
86
|
-
store.integrations.clear();
|
|
87
83
|
store.menus.length = 0;
|
|
88
84
|
store.features.clear();
|
|
89
85
|
}
|
|
@@ -105,10 +101,6 @@ module.exports = {
|
|
|
105
101
|
listDocuments: simpleList("documents"),
|
|
106
102
|
registerPipeline: simpleRegister("pipelines"),
|
|
107
103
|
listPipelines: simpleList("pipelines"),
|
|
108
|
-
registerOmieMapping: simpleRegister("omieMappings"),
|
|
109
|
-
listOmieMappings: simpleList("omieMappings"),
|
|
110
|
-
registerIntegration: simpleRegister("integrations"),
|
|
111
|
-
listIntegrations: simpleList("integrations"),
|
|
112
104
|
registerFeature: simpleRegister("features"),
|
|
113
105
|
listFeatures: simpleList("features"),
|
|
114
106
|
registerMenu,
|
package/src/deploy/render.js
CHANGED
package/src/index.js
CHANGED
|
@@ -10,8 +10,6 @@ const tenancy = require("./core/tenancy");
|
|
|
10
10
|
const GenericError = require("./core/errors/GenericError");
|
|
11
11
|
const { requirePermission } = require("./core/middlewares/permissions");
|
|
12
12
|
const rbacPolicy = require("./core/rbac/policy");
|
|
13
|
-
const omieModule = require("./modules/omie");
|
|
14
|
-
const integrations = require("./modules/integrations");
|
|
15
13
|
const capabilities = require("./capabilities");
|
|
16
14
|
const { operationalRequestHeaders } = require("./core/utils/instanceActivation");
|
|
17
15
|
const appManifest = require("./manifest/appManifest");
|
|
@@ -27,7 +25,7 @@ module.exports = {
|
|
|
27
25
|
start, createApp, activate,
|
|
28
26
|
defineCentral: define.defineCentral, defineModel: define.defineModel,
|
|
29
27
|
defineCollection: define.defineCollection, defineDocument: define.defineDocument,
|
|
30
|
-
definePipeline: define.definePipeline,
|
|
28
|
+
definePipeline: define.definePipeline,
|
|
31
29
|
defineRoutes: define.defineRoutes, defineValidation: define.defineValidation,
|
|
32
30
|
defineTrigger: define.defineTrigger,
|
|
33
31
|
requirePermission, CORE_PERMISSIONS: rbacPolicy.CORE_PERMISSIONS,
|
|
@@ -75,19 +73,7 @@ module.exports = {
|
|
|
75
73
|
assertDeleteAllowed: processRuntime.assertDeleteAllowed,
|
|
76
74
|
recalculateDependents: processRuntime.recalculateDependents,
|
|
77
75
|
drainProcessJobs: processRuntime.drainProcessJobs,
|
|
78
|
-
fields,
|
|
79
|
-
createOmieClient: omieModule.createOmieClient,
|
|
80
|
-
OmieApiError: omieModule.OmieApiError,
|
|
81
|
-
enqueueOmieCall: omieModule.enqueueOmieCall,
|
|
82
|
-
ensureOmieProviderRegistered: omieModule.ensureOmieProviderRegistered,
|
|
83
|
-
collectOmieDefinitions: omieModule.collectOmieDefinitions,
|
|
84
|
-
describeOmieDefinitions: omieModule.describeOmieDefinitions,
|
|
85
|
-
saveOmieConfiguration: omieModule.saveOmieConfiguration,
|
|
86
|
-
listOmieConfigurations: omieModule.listOmieConfigurations,
|
|
87
|
-
testOmieConnection: omieModule.testOmieConnection,
|
|
88
|
-
integrations, registerIntegrationProvider: integrations.registerIntegrationProvider,
|
|
89
|
-
enqueueIntegration: integrations.enqueueIntegration,
|
|
90
|
-
receiveIntegrationWebhook: integrations.receiveWebhook,
|
|
76
|
+
fields,
|
|
91
77
|
capabilities,
|
|
92
78
|
operationalRequestHeaders,
|
|
93
79
|
localDevelopment,
|
|
@@ -7,17 +7,15 @@ const corePackage = require("../../package.json");
|
|
|
7
7
|
const { validateRbac } = require("./rbacManifest");
|
|
8
8
|
|
|
9
9
|
const APP_MANIFEST_FILENAME = "central.app.json";
|
|
10
|
-
const APP_MANIFEST_SCHEMA_VERSION =
|
|
10
|
+
const APP_MANIFEST_SCHEMA_VERSION = 2;
|
|
11
11
|
const SUPPORTED_APP_KINDS = Object.freeze(["root-central", "member-central", "portal-cockpit"]);
|
|
12
12
|
const SUPPORTED_MODULES = Object.freeze([
|
|
13
|
-
"collections", "documents", "pipelines", "
|
|
13
|
+
"collections", "documents", "pipelines", "assistants", "currencies",
|
|
14
14
|
]);
|
|
15
15
|
const SUPPORTED_TENANCY_MODELS = Object.freeze(["none", "single_tenant", "multi_tenant"]);
|
|
16
16
|
const SUPPORTED_AVAILABILITIES = Object.freeze(["system", "common", "licensed"]);
|
|
17
17
|
const SUPPORTED_ACCESS_MODES = Object.freeze(["tenant_members", "explicit_users", "authenticated_users"]);
|
|
18
18
|
const SUPPORTED_AUTHORIZATION_MODES = Object.freeze(["none", "rbac"]);
|
|
19
|
-
// Compatibilidade de leitura para manifestos anteriores à separação das duas dimensões.
|
|
20
|
-
const SUPPORTED_ACCESS_POLICIES = Object.freeze(["tenant_members", "explicit_users", "rbac"]);
|
|
21
19
|
const SUPPORTED_DEPLOYMENT_MODES = Object.freeze(["singleton", "shared", "dedicated", "hybrid"]);
|
|
22
20
|
const TRANSACTIONAL_EMAIL_CAPABILITY = "core.transactional-email";
|
|
23
21
|
const EMAIL_SCOPE_POLICIES = Object.freeze(["app_only", "tenant_required", "tenant_override"]);
|
|
@@ -192,22 +190,13 @@ function validateDimension(value, field, supported, issues) {
|
|
|
192
190
|
}
|
|
193
191
|
}
|
|
194
192
|
|
|
195
|
-
function legacyAccessDimensions(accessPolicy) {
|
|
196
|
-
return {
|
|
197
|
-
tenant_members: { accessMode: "tenant_members", authorizationMode: "none" },
|
|
198
|
-
explicit_users: { accessMode: "explicit_users", authorizationMode: "none" },
|
|
199
|
-
rbac: { accessMode: "explicit_users", authorizationMode: "rbac" },
|
|
200
|
-
}[accessPolicy];
|
|
201
|
-
}
|
|
202
|
-
|
|
203
193
|
function dimensionsFor(manifest) {
|
|
204
194
|
const defaults = APP_KIND_DIMENSIONS[manifest.appKind] || APP_KIND_DIMENSIONS["member-central"];
|
|
205
|
-
const legacy = legacyAccessDimensions(manifest.accessPolicy) || {};
|
|
206
195
|
return {
|
|
207
196
|
tenancyModel: manifest.tenancyModel || defaults.tenancyModel,
|
|
208
197
|
availability: manifest.availability || defaults.availability,
|
|
209
|
-
accessMode: manifest.accessMode ||
|
|
210
|
-
authorizationMode: manifest.authorizationMode ||
|
|
198
|
+
accessMode: manifest.accessMode || defaults.accessMode,
|
|
199
|
+
authorizationMode: manifest.authorizationMode || defaults.authorizationMode,
|
|
211
200
|
deploymentMode: manifest.deploymentMode || defaults.deploymentMode,
|
|
212
201
|
};
|
|
213
202
|
}
|
|
@@ -219,7 +208,7 @@ function validateAppManifest(input, { coreVersion = corePackage.version } = {})
|
|
|
219
208
|
}
|
|
220
209
|
const allowedTopLevel = new Set([
|
|
221
210
|
"$schema", "schemaVersion", "id", "name", "slug", "appKind",
|
|
222
|
-
"tenancyModel", "availability", "accessMode", "authorizationMode", "
|
|
211
|
+
"tenancyModel", "availability", "accessMode", "authorizationMode", "deploymentMode",
|
|
223
212
|
"modules", "capabilities", "capabilitySettings", "compatibility", "activation", "auth", "rbac",
|
|
224
213
|
]);
|
|
225
214
|
for (const key of Object.keys(input)) {
|
|
@@ -242,11 +231,7 @@ function validateAppManifest(input, { coreVersion = corePackage.version } = {})
|
|
|
242
231
|
validateDimension(input.availability, "availability", SUPPORTED_AVAILABILITIES, issues);
|
|
243
232
|
validateDimension(input.accessMode, "accessMode", SUPPORTED_ACCESS_MODES, issues);
|
|
244
233
|
validateDimension(input.authorizationMode, "authorizationMode", SUPPORTED_AUTHORIZATION_MODES, issues);
|
|
245
|
-
validateDimension(input.accessPolicy, "accessPolicy", SUPPORTED_ACCESS_POLICIES, issues);
|
|
246
234
|
validateDimension(input.deploymentMode, "deploymentMode", SUPPORTED_DEPLOYMENT_MODES, issues);
|
|
247
|
-
if (input.accessPolicy !== undefined && (input.accessMode !== undefined || input.authorizationMode !== undefined)) {
|
|
248
|
-
addIssue(issues, "accessPolicy", "é legado e não pode ser combinado com accessMode/authorizationMode.");
|
|
249
|
-
}
|
|
250
235
|
const dimensions = dimensionsFor(input);
|
|
251
236
|
const role = APP_KIND_ROLE[input.appKind];
|
|
252
237
|
if (role === "root" && (
|
|
@@ -383,7 +368,6 @@ module.exports = {
|
|
|
383
368
|
SUPPORTED_AVAILABILITIES,
|
|
384
369
|
SUPPORTED_ACCESS_MODES,
|
|
385
370
|
SUPPORTED_AUTHORIZATION_MODES,
|
|
386
|
-
SUPPORTED_ACCESS_POLICIES,
|
|
387
371
|
SUPPORTED_DEPLOYMENT_MODES,
|
|
388
372
|
TRANSACTIONAL_EMAIL_CAPABILITY,
|
|
389
373
|
EMAIL_SCOPE_POLICIES,
|
|
@@ -391,7 +375,6 @@ module.exports = {
|
|
|
391
375
|
AppManifestError,
|
|
392
376
|
parseVersion,
|
|
393
377
|
compareVersions,
|
|
394
|
-
legacyAccessDimensions,
|
|
395
378
|
dimensionsFor,
|
|
396
379
|
validateAppManifest,
|
|
397
380
|
resolveAppManifestPath,
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
|
|
4
|
-
const { runIntegrationWorker } = require("../src/modules/integrations");
|
|
5
|
-
|
|
6
|
-
function flag(name) {
|
|
7
|
-
const args = process.argv.slice(2);
|
|
8
|
-
const index = args.indexOf(name);
|
|
9
|
-
if (index < 0) return undefined;
|
|
10
|
-
const value = args[index + 1];
|
|
11
|
-
return value && !value.startsWith("--") ? value : true;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function positive(value) {
|
|
15
|
-
if (value == null || value === true) return undefined;
|
|
16
|
-
const parsed = Number(value);
|
|
17
|
-
if (!Number.isFinite(parsed) || parsed <= 0) throw new Error(`Valor inválido: ${value}.`);
|
|
18
|
-
return parsed;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
runIntegrationWorker({
|
|
22
|
-
cwd: process.cwd(),
|
|
23
|
-
once: flag("--once") === true,
|
|
24
|
-
intervalMs: positive(flag("--interval")),
|
|
25
|
-
batchSize: positive(flag("--batch")),
|
|
26
|
-
webhookBatchSize: positive(flag("--webhook-batch")),
|
|
27
|
-
provider: flag("--provider") === true ? undefined : flag("--provider"),
|
|
28
|
-
}).catch((error) => {
|
|
29
|
-
console.error(error?.message || error);
|
|
30
|
-
process.exit(1);
|
|
31
|
-
});
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
const registry = require("./registry");
|
|
4
|
-
const runtime = require("./runtime");
|
|
5
|
-
const sanitizer = require("./sanitizer");
|
|
6
|
-
const models = require("./models");
|
|
7
|
-
const worker = require("./worker");
|
|
8
|
-
const { buildIntegrationRouter } = require("./routes");
|
|
9
|
-
|
|
10
|
-
function integrationsEnabled(config = {}) {
|
|
11
|
-
return Boolean(
|
|
12
|
-
config.appManifest?.modules?.integrations
|
|
13
|
-
|| config.modules?.integrations
|
|
14
|
-
|| registry.listIntegrationProviders().length,
|
|
15
|
-
);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
module.exports = {
|
|
19
|
-
...registry,
|
|
20
|
-
...runtime,
|
|
21
|
-
...sanitizer,
|
|
22
|
-
...models,
|
|
23
|
-
...worker,
|
|
24
|
-
buildIntegrationRouter,
|
|
25
|
-
integrationsEnabled,
|
|
26
|
-
};
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
const mongoose = require("mongoose");
|
|
4
|
-
|
|
5
|
-
const OUTBOX_STATUSES = ["Pendente", "Processando", "Erro temporário", "Concluído", "Erro definitivo", "Arquivado"];
|
|
6
|
-
const INBOX_STATUSES = ["Pendente", "Processando", "Concluído", "Erro temporário", "Erro definitivo"];
|
|
7
|
-
const EXECUTION_STATUSES = ["Executando", "Concluído", "Concluído com erros", "Erro"];
|
|
8
|
-
|
|
9
|
-
function jsonField(defaultValue) {
|
|
10
|
-
return { type: mongoose.Schema.Types.Mixed, default: defaultValue };
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function leaseFields() {
|
|
14
|
-
return {
|
|
15
|
-
leaseId: { type: String, default: "", index: true },
|
|
16
|
-
lockedAt: { type: Date, default: null },
|
|
17
|
-
lockedBy: { type: String, default: "" },
|
|
18
|
-
leaseExpiresAt: { type: Date, default: null, index: true },
|
|
19
|
-
heartbeatAt: { type: Date, default: null },
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function model(name, schemaFactory, collection) {
|
|
24
|
-
return mongoose.models[name] || mongoose.model(name, schemaFactory(), collection);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function outboxSchema() {
|
|
28
|
-
const schema = new mongoose.Schema({
|
|
29
|
-
provider: { type: String, required: true, index: true },
|
|
30
|
-
handler: { type: String, required: true },
|
|
31
|
-
resource: { type: String, default: "", index: true },
|
|
32
|
-
operation: { type: String, default: "execute", index: true },
|
|
33
|
-
aggregateType: { type: String, default: "", index: true },
|
|
34
|
-
aggregateId: { type: String, default: "", index: true },
|
|
35
|
-
idempotencyKey: { type: String, required: true, unique: true },
|
|
36
|
-
payload: jsonField({}),
|
|
37
|
-
status: { type: String, enum: OUTBOX_STATUSES, default: "Pendente", index: true },
|
|
38
|
-
previousStatus: { type: String, default: "" },
|
|
39
|
-
attempts: { type: Number, min: 0, default: 0 },
|
|
40
|
-
nextAttemptAt: { type: Date, default: Date.now, index: true },
|
|
41
|
-
lastError: jsonField({}),
|
|
42
|
-
responseSummary: jsonField({}),
|
|
43
|
-
completedAt: { type: Date, default: null },
|
|
44
|
-
archivedAt: { type: Date, default: null },
|
|
45
|
-
archiveReason: { type: String, default: "" },
|
|
46
|
-
...leaseFields(),
|
|
47
|
-
}, { timestamps: true, minimize: false, strict: true });
|
|
48
|
-
schema.index({ provider: 1, status: 1, nextAttemptAt: 1, createdAt: 1 });
|
|
49
|
-
schema.index({ status: 1, leaseExpiresAt: 1 });
|
|
50
|
-
return schema;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function inboxSchema() {
|
|
54
|
-
const schema = new mongoose.Schema({
|
|
55
|
-
provider: { type: String, required: true, index: true },
|
|
56
|
-
resource: { type: String, default: "", index: true },
|
|
57
|
-
eventType: { type: String, required: true, index: true },
|
|
58
|
-
externalEventId: { type: String, default: "" },
|
|
59
|
-
deduplicationKey: { type: String, required: true, unique: true },
|
|
60
|
-
payloadHash: { type: String, required: true, index: true },
|
|
61
|
-
payload: jsonField({}),
|
|
62
|
-
metadata: jsonField({}),
|
|
63
|
-
receivedAt: { type: Date, default: Date.now, index: true },
|
|
64
|
-
status: { type: String, enum: INBOX_STATUSES, default: "Pendente", index: true },
|
|
65
|
-
attempts: { type: Number, min: 0, default: 0 },
|
|
66
|
-
nextAttemptAt: { type: Date, default: Date.now, index: true },
|
|
67
|
-
processedAt: { type: Date, default: null },
|
|
68
|
-
lastError: jsonField({}),
|
|
69
|
-
...leaseFields(),
|
|
70
|
-
}, { timestamps: true, minimize: false, strict: true });
|
|
71
|
-
schema.index({ provider: 1, status: 1, nextAttemptAt: 1, receivedAt: 1 });
|
|
72
|
-
return schema;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function executionSchema() {
|
|
76
|
-
const schema = new mongoose.Schema({
|
|
77
|
-
provider: { type: String, required: true, index: true },
|
|
78
|
-
resource: { type: String, default: "", index: true },
|
|
79
|
-
operation: { type: String, default: "execute", index: true },
|
|
80
|
-
title: { type: String, required: true },
|
|
81
|
-
status: { type: String, enum: EXECUTION_STATUSES, default: "Executando", index: true },
|
|
82
|
-
startedAt: { type: Date, default: Date.now, index: true },
|
|
83
|
-
concludedAt: { type: Date, default: null },
|
|
84
|
-
durationMs: { type: Number, default: 0 },
|
|
85
|
-
message: { type: String, default: "" },
|
|
86
|
-
error: jsonField({}),
|
|
87
|
-
summary: jsonField({}),
|
|
88
|
-
metadata: jsonField({}),
|
|
89
|
-
requests: { type: [mongoose.Schema.Types.Mixed], default: [] },
|
|
90
|
-
requestCount: { type: Number, default: 0 },
|
|
91
|
-
requestsLimited: { type: Boolean, default: false },
|
|
92
|
-
errors: { type: [mongoose.Schema.Types.Mixed], default: [] },
|
|
93
|
-
errorCount: { type: Number, default: 0 },
|
|
94
|
-
errorsLimited: { type: Boolean, default: false },
|
|
95
|
-
items: { type: [mongoose.Schema.Types.Mixed], default: [] },
|
|
96
|
-
itemCount: { type: Number, default: 0 },
|
|
97
|
-
itemsLimited: { type: Boolean, default: false },
|
|
98
|
-
}, { timestamps: true, minimize: false, strict: true });
|
|
99
|
-
schema.index({ provider: 1, resource: 1, startedAt: -1 });
|
|
100
|
-
schema.index({ status: 1, startedAt: -1 });
|
|
101
|
-
return schema;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function getIntegrationModels() {
|
|
105
|
-
return {
|
|
106
|
-
Outbox: model("OonIntegrationOutbox", outboxSchema, "oon_integration_outbox"),
|
|
107
|
-
Inbox: model("OonIntegrationInbox", inboxSchema, "oon_integration_inbox"),
|
|
108
|
-
Execution: model("OonIntegrationExecution", executionSchema, "oon_integration_executions"),
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
module.exports = { EXECUTION_STATUSES, INBOX_STATUSES, OUTBOX_STATUSES, getIntegrationModels };
|