@malloy-publisher/server 0.0.85 → 0.0.86
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/app/api-doc.yaml +187 -0
- package/dist/app/assets/{RenderedResult-BAZuT25g-9oy_tMLH.js → RenderedResult-BAZuT25g-_eLjVkSo.js} +2 -2
- package/dist/app/assets/{index-DQ2nRzzZ.js → index-BvRGZn2o.js} +1 -1
- package/dist/app/assets/{index-C3s9KcRM.js → index-C-lp8bCy.js} +1 -1
- package/dist/app/assets/{index-Da-HoCBr.js → index-EI2L5apg.js} +119 -119
- package/dist/app/assets/{index.umd-CeT9AycY.js → index.umd-DBkg1U_t.js} +1 -1
- package/dist/app/index.html +1 -1
- package/dist/instrumentation.js +2 -1
- package/dist/server.js +321 -108
- package/package.json +1 -1
- package/publisher.config.json +1 -0
- package/src/controller/package.controller.ts +32 -0
- package/src/errors.ts +14 -0
- package/src/logger.ts +12 -5
- package/src/mcp/tools/discovery_tools.ts +2 -2
- package/src/server.ts +95 -19
- package/src/service/db_utils.ts +3 -6
- package/src/service/package.ts +12 -0
- package/src/service/project.ts +85 -3
- package/src/service/project_store.spec.ts +173 -0
- package/src/service/project_store.ts +97 -22
- package/src/utils.ts +14 -2
package/dist/server.js
CHANGED
|
@@ -228489,14 +228489,14 @@ var require_brace_expansion2 = __commonJS((exports2, module2) => {
|
|
|
228489
228489
|
var require_minimatch = __commonJS((exports2, module2) => {
|
|
228490
228490
|
module2.exports = minimatch;
|
|
228491
228491
|
minimatch.Minimatch = Minimatch;
|
|
228492
|
-
var
|
|
228492
|
+
var path4 = function() {
|
|
228493
228493
|
try {
|
|
228494
228494
|
return require("path");
|
|
228495
228495
|
} catch (e) {}
|
|
228496
228496
|
}() || {
|
|
228497
228497
|
sep: "/"
|
|
228498
228498
|
};
|
|
228499
|
-
minimatch.sep =
|
|
228499
|
+
minimatch.sep = path4.sep;
|
|
228500
228500
|
var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {};
|
|
228501
228501
|
var expand = require_brace_expansion2();
|
|
228502
228502
|
var plTypes = {
|
|
@@ -228587,8 +228587,8 @@ var require_minimatch = __commonJS((exports2, module2) => {
|
|
|
228587
228587
|
if (!options)
|
|
228588
228588
|
options = {};
|
|
228589
228589
|
pattern = pattern.trim();
|
|
228590
|
-
if (!options.allowWindowsEscape &&
|
|
228591
|
-
pattern = pattern.split(
|
|
228590
|
+
if (!options.allowWindowsEscape && path4.sep !== "/") {
|
|
228591
|
+
pattern = pattern.split(path4.sep).join("/");
|
|
228592
228592
|
}
|
|
228593
228593
|
this.options = options;
|
|
228594
228594
|
this.set = [];
|
|
@@ -228965,8 +228965,8 @@ var require_minimatch = __commonJS((exports2, module2) => {
|
|
|
228965
228965
|
if (f === "/" && partial)
|
|
228966
228966
|
return true;
|
|
228967
228967
|
var options = this.options;
|
|
228968
|
-
if (
|
|
228969
|
-
f = f.split(
|
|
228968
|
+
if (path4.sep !== "/") {
|
|
228969
|
+
f = f.split(path4.sep).join("/");
|
|
228970
228970
|
}
|
|
228971
228971
|
f = f.split(slashSplit);
|
|
228972
228972
|
this.debug(this.pattern, "split", f);
|
|
@@ -229077,9 +229077,9 @@ var require_recursive_readdir = __commonJS((exports2, module2) => {
|
|
|
229077
229077
|
var p = require("path");
|
|
229078
229078
|
var minimatch = require_minimatch();
|
|
229079
229079
|
function patternMatcher(pattern) {
|
|
229080
|
-
return function(
|
|
229080
|
+
return function(path4, stats) {
|
|
229081
229081
|
var minimatcher = new minimatch.Minimatch(pattern, { matchBase: true });
|
|
229082
|
-
return (!minimatcher.negate || stats.isFile()) && minimatcher.match(
|
|
229082
|
+
return (!minimatcher.negate || stats.isFile()) && minimatcher.match(path4);
|
|
229083
229083
|
};
|
|
229084
229084
|
}
|
|
229085
229085
|
function toMatcherFunction(ignoreEntry) {
|
|
@@ -229089,14 +229089,14 @@ var require_recursive_readdir = __commonJS((exports2, module2) => {
|
|
|
229089
229089
|
return patternMatcher(ignoreEntry);
|
|
229090
229090
|
}
|
|
229091
229091
|
}
|
|
229092
|
-
function readdir(
|
|
229092
|
+
function readdir(path4, ignores, callback) {
|
|
229093
229093
|
if (typeof ignores == "function") {
|
|
229094
229094
|
callback = ignores;
|
|
229095
229095
|
ignores = [];
|
|
229096
229096
|
}
|
|
229097
229097
|
if (!callback) {
|
|
229098
229098
|
return new Promise(function(resolve, reject) {
|
|
229099
|
-
readdir(
|
|
229099
|
+
readdir(path4, ignores || [], function(err, data) {
|
|
229100
229100
|
if (err) {
|
|
229101
229101
|
reject(err);
|
|
229102
229102
|
} else {
|
|
@@ -229107,7 +229107,7 @@ var require_recursive_readdir = __commonJS((exports2, module2) => {
|
|
|
229107
229107
|
}
|
|
229108
229108
|
ignores = ignores.map(toMatcherFunction);
|
|
229109
229109
|
var list = [];
|
|
229110
|
-
fs4.readdir(
|
|
229110
|
+
fs4.readdir(path4, function(err, files) {
|
|
229111
229111
|
if (err) {
|
|
229112
229112
|
return callback(err);
|
|
229113
229113
|
}
|
|
@@ -229116,7 +229116,7 @@ var require_recursive_readdir = __commonJS((exports2, module2) => {
|
|
|
229116
229116
|
return callback(null, list);
|
|
229117
229117
|
}
|
|
229118
229118
|
files.forEach(function(file) {
|
|
229119
|
-
var filePath = p.join(
|
|
229119
|
+
var filePath = p.join(path4, file);
|
|
229120
229120
|
fs4.stat(filePath, function(_err, stats) {
|
|
229121
229121
|
if (_err) {
|
|
229122
229122
|
return callback(_err);
|
|
@@ -230033,7 +230033,7 @@ var require_scheduled_task = __commonJS((exports2, module2) => {
|
|
|
230033
230033
|
var require_background_scheduled_task = __commonJS((exports2, module2) => {
|
|
230034
230034
|
var __dirname = "/home/runner/work/publisher/publisher/node_modules/node-cron/src/background-scheduled-task";
|
|
230035
230035
|
var EventEmitter = require("events");
|
|
230036
|
-
var
|
|
230036
|
+
var path5 = require("path");
|
|
230037
230037
|
var { fork } = require("child_process");
|
|
230038
230038
|
var uuid = require_dist19();
|
|
230039
230039
|
var daemonPath = `${__dirname}/daemon.js`;
|
|
@@ -230069,7 +230069,7 @@ var require_background_scheduled_task = __commonJS((exports2, module2) => {
|
|
|
230069
230069
|
options.scheduled = true;
|
|
230070
230070
|
this.forkProcess.send({
|
|
230071
230071
|
type: "register",
|
|
230072
|
-
path:
|
|
230072
|
+
path: path5.resolve(this.taskPath),
|
|
230073
230073
|
cron: this.cronExpression,
|
|
230074
230074
|
options
|
|
230075
230075
|
});
|
|
@@ -235134,16 +235134,23 @@ var import_cors = __toESM(require_lib4());
|
|
|
235134
235134
|
var import_express = __toESM(require_express2());
|
|
235135
235135
|
var http = __toESM(require("http"));
|
|
235136
235136
|
var import_http_proxy_middleware = __toESM(require_dist());
|
|
235137
|
-
var
|
|
235137
|
+
var path8 = __toESM(require("path"));
|
|
235138
235138
|
|
|
235139
235139
|
// src/errors.ts
|
|
235140
|
+
var import_malloy = require("@malloydata/malloy");
|
|
235140
235141
|
function internalErrorToHttpError(error) {
|
|
235141
235142
|
if (error instanceof BadRequestError) {
|
|
235142
235143
|
return httpError(400, error.message);
|
|
235144
|
+
} else if (error instanceof FrozenConfigError) {
|
|
235145
|
+
return httpError(403, error.message);
|
|
235146
|
+
} else if (error instanceof ProjectNotFoundError) {
|
|
235147
|
+
return httpError(404, error.message);
|
|
235143
235148
|
} else if (error instanceof PackageNotFoundError) {
|
|
235144
235149
|
return httpError(404, error.message);
|
|
235145
235150
|
} else if (error instanceof ModelNotFoundError) {
|
|
235146
235151
|
return httpError(404, error.message);
|
|
235152
|
+
} else if (error instanceof import_malloy.MalloyError) {
|
|
235153
|
+
return httpError(400, error.message);
|
|
235147
235154
|
} else if (error instanceof ConnectionNotFoundError) {
|
|
235148
235155
|
return httpError(404, error.message);
|
|
235149
235156
|
} else if (error instanceof ModelCompilationError) {
|
|
@@ -235212,10 +235219,17 @@ class ModelCompilationError extends Error {
|
|
|
235212
235219
|
}
|
|
235213
235220
|
}
|
|
235214
235221
|
|
|
235222
|
+
class FrozenConfigError extends Error {
|
|
235223
|
+
constructor(message = "Publisher config can't be updated when publisher.config.json has `frozenConfig: true`") {
|
|
235224
|
+
super(message);
|
|
235225
|
+
}
|
|
235226
|
+
}
|
|
235227
|
+
|
|
235215
235228
|
// src/logger.ts
|
|
235216
235229
|
var import_winston = __toESM(require_winston());
|
|
235230
|
+
var isTelemetryEnabled = Boolean(process.env.OTEL_EXPORTER_OTLP_ENDPOINT);
|
|
235217
235231
|
var logger = import_winston.default.createLogger({
|
|
235218
|
-
format: import_winston.default.format.combine(import_winston.default.format.uncolorize(), import_winston.default.format.timestamp(), import_winston.default.format.json()),
|
|
235232
|
+
format: isTelemetryEnabled ? import_winston.default.format.combine(import_winston.default.format.uncolorize(), import_winston.default.format.timestamp(), import_winston.default.format.json()) : import_winston.default.format.combine(import_winston.default.format.colorize(), import_winston.default.format.simple()),
|
|
235219
235233
|
transports: [new import_winston.default.transports.Console]
|
|
235220
235234
|
});
|
|
235221
235235
|
var loggerMiddleware = (req, res, next) => {
|
|
@@ -235352,9 +235366,9 @@ async function getSchemasForConnection(connection) {
|
|
|
235352
235366
|
}
|
|
235353
235367
|
try {
|
|
235354
235368
|
const bigquery = getBigqueryConnection(connection);
|
|
235355
|
-
const
|
|
235356
|
-
|
|
235357
|
-
|
|
235369
|
+
const projectId = connection.bigqueryConnection.defaultProjectId;
|
|
235370
|
+
const options = projectId ? { projectId } : {};
|
|
235371
|
+
const [datasets] = await bigquery.getDatasets(options);
|
|
235358
235372
|
return datasets.filter((dataset) => dataset.id).map((dataset) => {
|
|
235359
235373
|
return {
|
|
235360
235374
|
name: dataset.id,
|
|
@@ -235699,6 +235713,30 @@ class PackageController {
|
|
|
235699
235713
|
const p = await project.getPackage(packageName, reload);
|
|
235700
235714
|
return p.getPackageMetadata();
|
|
235701
235715
|
}
|
|
235716
|
+
async addPackage(projectName, body) {
|
|
235717
|
+
if (this.projectStore.publisherConfigIsFrozen) {
|
|
235718
|
+
throw new FrozenConfigError;
|
|
235719
|
+
}
|
|
235720
|
+
if (!body.name) {
|
|
235721
|
+
throw new BadRequestError("Package name is required");
|
|
235722
|
+
}
|
|
235723
|
+
const project = await this.projectStore.getProject(projectName, false);
|
|
235724
|
+
return project.addPackage(body.name);
|
|
235725
|
+
}
|
|
235726
|
+
async deletePackage(projectName, packageName) {
|
|
235727
|
+
if (this.projectStore.publisherConfigIsFrozen) {
|
|
235728
|
+
throw new FrozenConfigError;
|
|
235729
|
+
}
|
|
235730
|
+
const project = await this.projectStore.getProject(projectName, false);
|
|
235731
|
+
return project.deletePackage(packageName);
|
|
235732
|
+
}
|
|
235733
|
+
async updatePackage(projectName, packageName, body) {
|
|
235734
|
+
if (this.projectStore.publisherConfigIsFrozen) {
|
|
235735
|
+
throw new FrozenConfigError;
|
|
235736
|
+
}
|
|
235737
|
+
const project = await this.projectStore.getProject(projectName, false);
|
|
235738
|
+
return project.updatePackage(packageName, body);
|
|
235739
|
+
}
|
|
235702
235740
|
}
|
|
235703
235741
|
|
|
235704
235742
|
// src/constants.ts
|
|
@@ -243179,7 +243217,7 @@ function registerTools(mcpServer, projectStore) {
|
|
|
243179
243217
|
const mappedResources = await Promise.all(allProjects.map(async (project) => {
|
|
243180
243218
|
const name = project.name;
|
|
243181
243219
|
const projectInstance = await project.project;
|
|
243182
|
-
const metadata = await projectInstance.
|
|
243220
|
+
const metadata = await projectInstance.reloadProjectMetadata();
|
|
243183
243221
|
const readme = metadata.readme;
|
|
243184
243222
|
return {
|
|
243185
243223
|
name,
|
|
@@ -243480,7 +243518,34 @@ function initializeMcpServer(projectStore) {
|
|
|
243480
243518
|
|
|
243481
243519
|
// src/service/project_store.ts
|
|
243482
243520
|
var fs7 = __toESM(require("fs/promises"));
|
|
243483
|
-
var
|
|
243521
|
+
var path7 = __toESM(require("path"));
|
|
243522
|
+
|
|
243523
|
+
// src/utils.ts
|
|
243524
|
+
var fs2 = __toESM(require("fs"));
|
|
243525
|
+
var import_path2 = __toESM(require("path"));
|
|
243526
|
+
var import_url = require("url");
|
|
243527
|
+
var PACKAGE_MANIFEST_NAME = "publisher.json";
|
|
243528
|
+
var CONNECTIONS_MANIFEST_NAME = "publisher.connections.json";
|
|
243529
|
+
var MODEL_FILE_SUFFIX = ".malloy";
|
|
243530
|
+
var NOTEBOOK_FILE_SUFFIX = ".malloynb";
|
|
243531
|
+
var ROW_LIMIT = 1000;
|
|
243532
|
+
var URL_READER = {
|
|
243533
|
+
readURL: (url) => {
|
|
243534
|
+
let path3 = url.toString();
|
|
243535
|
+
if (url.protocol == "file:") {
|
|
243536
|
+
path3 = import_url.fileURLToPath(url);
|
|
243537
|
+
}
|
|
243538
|
+
return fs2.promises.readFile(path3, "utf8");
|
|
243539
|
+
}
|
|
243540
|
+
};
|
|
243541
|
+
var isPublisherConfigFrozen = (serverRoot) => {
|
|
243542
|
+
const publisherConfigPath = import_path2.default.join(serverRoot, "publisher.config.json");
|
|
243543
|
+
if (!fs2.existsSync(publisherConfigPath)) {
|
|
243544
|
+
return false;
|
|
243545
|
+
}
|
|
243546
|
+
const publisherConfig = JSON.parse(fs2.readFileSync(publisherConfigPath, "utf8"));
|
|
243547
|
+
return Boolean(publisherConfig.frozenConfig);
|
|
243548
|
+
};
|
|
243484
243549
|
|
|
243485
243550
|
// ../../node_modules/async-mutex/index.mjs
|
|
243486
243551
|
var E_TIMEOUT = new Error("timeout while waiting for mutex to become available");
|
|
@@ -243692,7 +243757,7 @@ class Mutex {
|
|
|
243692
243757
|
|
|
243693
243758
|
// src/service/project.ts
|
|
243694
243759
|
var fs6 = __toESM(require("fs/promises"));
|
|
243695
|
-
var
|
|
243760
|
+
var path6 = __toESM(require("path"));
|
|
243696
243761
|
|
|
243697
243762
|
// src/service/connection.ts
|
|
243698
243763
|
var import_db_postgres = require("@malloydata/db-postgres");
|
|
@@ -243700,30 +243765,10 @@ var import_db_bigquery = require("@malloydata/db-bigquery");
|
|
|
243700
243765
|
var import_db_snowflake = require("@malloydata/db-snowflake");
|
|
243701
243766
|
var import_db_trino = require("@malloydata/db-trino");
|
|
243702
243767
|
var import_db_mysql = require("@malloydata/db-mysql");
|
|
243703
|
-
var
|
|
243768
|
+
var import_path3 = __toESM(require("path"));
|
|
243704
243769
|
var import_promises = __toESM(require("fs/promises"));
|
|
243705
|
-
|
|
243706
|
-
// src/utils.ts
|
|
243707
|
-
var import_fs2 = require("fs");
|
|
243708
|
-
var import_url = require("url");
|
|
243709
|
-
var PACKAGE_MANIFEST_NAME = "publisher.json";
|
|
243710
|
-
var CONNECTIONS_MANIFEST_NAME = "publisher.connections.json";
|
|
243711
|
-
var MODEL_FILE_SUFFIX = ".malloy";
|
|
243712
|
-
var NOTEBOOK_FILE_SUFFIX = ".malloynb";
|
|
243713
|
-
var ROW_LIMIT = 1000;
|
|
243714
|
-
var URL_READER = {
|
|
243715
|
-
readURL: (url) => {
|
|
243716
|
-
let path2 = url.toString();
|
|
243717
|
-
if (url.protocol == "file:") {
|
|
243718
|
-
path2 = import_url.fileURLToPath(url);
|
|
243719
|
-
}
|
|
243720
|
-
return import_fs2.promises.readFile(path2, "utf8");
|
|
243721
|
-
}
|
|
243722
|
-
};
|
|
243723
|
-
|
|
243724
|
-
// src/service/connection.ts
|
|
243725
243770
|
async function readConnectionConfig(basePath) {
|
|
243726
|
-
const fullPath =
|
|
243771
|
+
const fullPath = import_path3.default.join(basePath, CONNECTIONS_MANIFEST_NAME);
|
|
243727
243772
|
try {
|
|
243728
243773
|
await import_promises.default.stat(fullPath);
|
|
243729
243774
|
} catch {
|
|
@@ -243782,7 +243827,7 @@ async function createConnections(basePath) {
|
|
|
243782
243827
|
}
|
|
243783
243828
|
let serviceAccountKeyPath = undefined;
|
|
243784
243829
|
if (connection.bigqueryConnection.serviceAccountKeyJson) {
|
|
243785
|
-
serviceAccountKeyPath =
|
|
243830
|
+
serviceAccountKeyPath = import_path3.default.join("/tmp", `${connection.name}-${v4_default()}-service-account-key.json`);
|
|
243786
243831
|
await import_promises.default.writeFile(serviceAccountKeyPath, connection.bigqueryConnection.serviceAccountKeyJson);
|
|
243787
243832
|
}
|
|
243788
243833
|
const bigqueryConnectionOptions = {
|
|
@@ -243873,19 +243918,19 @@ function getConnectionAttributes(connection) {
|
|
|
243873
243918
|
|
|
243874
243919
|
// src/service/package.ts
|
|
243875
243920
|
var fs5 = __toESM(require("fs/promises"));
|
|
243876
|
-
var
|
|
243921
|
+
var path5 = __toESM(require("path"));
|
|
243877
243922
|
var import_db_duckdb = require("@malloydata/db-duckdb");
|
|
243878
|
-
var
|
|
243923
|
+
var import_malloy3 = require("@malloydata/malloy");
|
|
243879
243924
|
var import_api2 = __toESM(require_src25());
|
|
243880
243925
|
var import_recursive_readdir = __toESM(require_recursive_readdir());
|
|
243881
243926
|
|
|
243882
243927
|
// src/service/model.ts
|
|
243883
|
-
var
|
|
243928
|
+
var import_malloy2 = require("@malloydata/malloy");
|
|
243884
243929
|
var import_malloy_sql = require("@malloydata/malloy-sql");
|
|
243885
243930
|
var import__package = __toESM(require("@malloydata/malloy/package.json"));
|
|
243886
243931
|
var import_api = __toESM(require_src25());
|
|
243887
243932
|
var fs4 = __toESM(require("fs/promises"));
|
|
243888
|
-
var
|
|
243933
|
+
var path4 = __toESM(require("path"));
|
|
243889
243934
|
|
|
243890
243935
|
// src/data_styles.ts
|
|
243891
243936
|
function compileDataStyles(styles) {
|
|
@@ -243965,7 +244010,7 @@ class Model {
|
|
|
243965
244010
|
this.queries = queries;
|
|
243966
244011
|
this.runnableNotebookCells = runnableNotebookCells;
|
|
243967
244012
|
this.compilationError = compilationError;
|
|
243968
|
-
this.modelInfo = this.modelDef ?
|
|
244013
|
+
this.modelInfo = this.modelDef ? import_malloy2.modelDefToModelInfo(this.modelDef) : undefined;
|
|
243969
244014
|
}
|
|
243970
244015
|
static async create(packageName, packagePath, modelPath, connections) {
|
|
243971
244016
|
const { runtime, modelURL, importBaseURL, dataStyles, modelType } = await Model.getModelRuntime(packagePath, modelPath, connections);
|
|
@@ -243982,7 +244027,7 @@ class Model {
|
|
|
243982
244027
|
return new Model(packageName, modelPath, dataStyles, modelType, modelMaterializer, modelDef, sources, queries, runnableNotebookCells, undefined);
|
|
243983
244028
|
} catch (error) {
|
|
243984
244029
|
let computedError = error;
|
|
243985
|
-
if (error instanceof
|
|
244030
|
+
if (error instanceof import_malloy2.MalloyError) {
|
|
243986
244031
|
computedError = new ModelCompilationError(error);
|
|
243987
244032
|
}
|
|
243988
244033
|
return new Model(packageName, modelPath, dataStyles, modelType, undefined, undefined, undefined, undefined, undefined, computedError);
|
|
@@ -243998,7 +244043,7 @@ class Model {
|
|
|
243998
244043
|
return this.sources;
|
|
243999
244044
|
}
|
|
244000
244045
|
getSourceInfos() {
|
|
244001
|
-
return this.modelDef ?
|
|
244046
|
+
return this.modelDef ? import_malloy2.modelDefToModelInfo(this.modelDef).entries.filter((entry) => {
|
|
244002
244047
|
return entry.kind === "source";
|
|
244003
244048
|
}) : undefined;
|
|
244004
244049
|
}
|
|
@@ -244070,7 +244115,7 @@ run: ${sourceName ? sourceName + "->" : ""}${queryName}`);
|
|
|
244070
244115
|
"malloy.model.query.status": "success"
|
|
244071
244116
|
});
|
|
244072
244117
|
return {
|
|
244073
|
-
result:
|
|
244118
|
+
result: import_malloy2.API.util.wrapResult(queryResults),
|
|
244074
244119
|
modelInfo: this.modelInfo,
|
|
244075
244120
|
dataStyles: this.dataStyles
|
|
244076
244121
|
};
|
|
@@ -244083,7 +244128,7 @@ run: ${sourceName ? sourceName + "->" : ""}${queryName}`);
|
|
|
244083
244128
|
malloyVersion: MALLOY_VERSION,
|
|
244084
244129
|
dataStyles: JSON.stringify(this.dataStyles),
|
|
244085
244130
|
modelDef: JSON.stringify(this.modelDef),
|
|
244086
|
-
modelInfo: JSON.stringify(this.modelDef ?
|
|
244131
|
+
modelInfo: JSON.stringify(this.modelDef ? import_malloy2.modelDefToModelInfo(this.modelDef) : {}),
|
|
244087
244132
|
sourceInfos: this.getSourceInfos()?.map((sourceInfo) => JSON.stringify(sourceInfo)),
|
|
244088
244133
|
sources: this.sources,
|
|
244089
244134
|
queries: this.queries
|
|
@@ -244099,7 +244144,7 @@ run: ${sourceName ? sourceName + "->" : ""}${queryName}`);
|
|
|
244099
244144
|
const result = await cell.runnable.run({ rowLimit });
|
|
244100
244145
|
const query = (await cell.runnable.getPreparedQuery())._query;
|
|
244101
244146
|
queryName = query.as || query.name;
|
|
244102
|
-
queryResult = result?._queryResult && this.modelInfo && JSON.stringify(
|
|
244147
|
+
queryResult = result?._queryResult && this.modelInfo && JSON.stringify(import_malloy2.API.util.wrapResult(result));
|
|
244103
244148
|
} catch {}
|
|
244104
244149
|
}
|
|
244105
244150
|
return {
|
|
@@ -244115,14 +244160,14 @@ run: ${sourceName ? sourceName + "->" : ""}${queryName}`);
|
|
|
244115
244160
|
packageName: this.packageName,
|
|
244116
244161
|
modelPath: this.modelPath,
|
|
244117
244162
|
malloyVersion: MALLOY_VERSION,
|
|
244118
|
-
modelInfo: JSON.stringify(this.modelDef ?
|
|
244163
|
+
modelInfo: JSON.stringify(this.modelDef ? import_malloy2.modelDefToModelInfo(this.modelDef) : {}),
|
|
244119
244164
|
sources: this.modelDef && this.sources,
|
|
244120
244165
|
queries: this.modelDef && this.queries,
|
|
244121
244166
|
notebookCells
|
|
244122
244167
|
};
|
|
244123
244168
|
}
|
|
244124
244169
|
static async getModelRuntime(packagePath, modelPath, connections) {
|
|
244125
|
-
const fullModelPath =
|
|
244170
|
+
const fullModelPath = path4.join(packagePath, modelPath);
|
|
244126
244171
|
try {
|
|
244127
244172
|
if (!(await fs4.stat(fullModelPath)).isFile()) {
|
|
244128
244173
|
throw new ModelNotFoundError(`${modelPath} is not a file.`);
|
|
@@ -244138,12 +244183,12 @@ run: ${sourceName ? sourceName + "->" : ""}${queryName}`);
|
|
|
244138
244183
|
} else {
|
|
244139
244184
|
throw new ModelNotFoundError(`${modelPath} is not a valid model name. Model files must end in .malloy or .malloynb.`);
|
|
244140
244185
|
}
|
|
244141
|
-
const importBaseURL = new URL("file://" +
|
|
244186
|
+
const importBaseURL = new URL("file://" + path4.dirname(fullModelPath) + "/");
|
|
244142
244187
|
const modelURL = new URL("file://" + fullModelPath);
|
|
244143
244188
|
const urlReader = new HackyDataStylesAccumulator(URL_READER);
|
|
244144
|
-
const runtime = new
|
|
244189
|
+
const runtime = new import_malloy2.Runtime({
|
|
244145
244190
|
urlReader,
|
|
244146
|
-
connections: new
|
|
244191
|
+
connections: new import_malloy2.FixedConnectionMap(connections, "duckdb")
|
|
244147
244192
|
});
|
|
244148
244193
|
const dataStyles = urlReader.getHackyAccumulatedDataStyles();
|
|
244149
244194
|
return { runtime, modelURL, importBaseURL, dataStyles, modelType };
|
|
@@ -244157,7 +244202,7 @@ run: ${sourceName ? sourceName + "->" : ""}${queryName}`);
|
|
|
244157
244202
|
}));
|
|
244158
244203
|
}
|
|
244159
244204
|
static getSources(modelPath, modelDef) {
|
|
244160
|
-
return Object.values(modelDef.contents).filter((obj) =>
|
|
244205
|
+
return Object.values(modelDef.contents).filter((obj) => import_malloy2.isSourceDef(obj)).map((sourceObj) => ({
|
|
244161
244206
|
name: sourceObj.as || sourceObj.name,
|
|
244162
244207
|
annotations: sourceObj.annotation?.blockNotes?.filter((note) => note.at.url.includes(modelPath)).map((note) => note.text),
|
|
244163
244208
|
views: sourceObj.fields.filter((turtleObj) => turtleObj.type === "turtle").filter((turtleObj) => turtleObj.pipeline.map((stage) => stage.type).every((type) => type == "reduce")).map((turtleObj) => ({
|
|
@@ -244231,12 +244276,12 @@ run: ${sourceName ? sourceName + "->" : ""}${queryName}`);
|
|
|
244231
244276
|
const importModel = (await runtime.loadModel(modelString, {
|
|
244232
244277
|
importBaseURL
|
|
244233
244278
|
}).getModel())._modelDef;
|
|
244234
|
-
const importModelInfo =
|
|
244279
|
+
const importModelInfo = import_malloy2.modelDefToModelInfo(importModel);
|
|
244235
244280
|
newSources = importModelInfo.entries.filter((entry) => entry.kind === "source").filter((source) => !(source.name in oldSources));
|
|
244236
244281
|
oldImports.push(importLocation.importURL.toString());
|
|
244237
244282
|
}));
|
|
244238
244283
|
}
|
|
244239
|
-
const currentModelInfo =
|
|
244284
|
+
const currentModelInfo = import_malloy2.modelDefToModelInfo(currentModelDef);
|
|
244240
244285
|
newSources = newSources.concat(currentModelInfo.entries.filter((entry) => entry.kind === "source").filter((source) => !(source.name in oldSources)));
|
|
244241
244286
|
for (const source of newSources) {
|
|
244242
244287
|
oldSources[source.name] = source;
|
|
@@ -244266,7 +244311,7 @@ run: ${sourceName ? sourceName + "->" : ""}${queryName}`);
|
|
|
244266
244311
|
return this.modelType;
|
|
244267
244312
|
}
|
|
244268
244313
|
async getFileText(packagePath) {
|
|
244269
|
-
const fullPath =
|
|
244314
|
+
const fullPath = path4.join(packagePath, this.modelPath);
|
|
244270
244315
|
try {
|
|
244271
244316
|
return await fs4.readFile(fullPath, "utf8");
|
|
244272
244317
|
} catch {
|
|
@@ -244577,11 +244622,11 @@ class Package {
|
|
|
244577
244622
|
throw new PackageNotFoundError(`Package config for ${packagePath} does not exist.`);
|
|
244578
244623
|
}
|
|
244579
244624
|
return files.map((fullPath) => {
|
|
244580
|
-
return
|
|
244625
|
+
return path5.relative(packagePath, fullPath).replace(/\\/g, "/");
|
|
244581
244626
|
}).filter((modelPath) => modelPath.endsWith(MODEL_FILE_SUFFIX) || modelPath.endsWith(NOTEBOOK_FILE_SUFFIX));
|
|
244582
244627
|
}
|
|
244583
244628
|
static async validatePackageManifestExistsOrThrowError(packagePath) {
|
|
244584
|
-
const packageConfigPath =
|
|
244629
|
+
const packageConfigPath = path5.join(packagePath, PACKAGE_MANIFEST_NAME);
|
|
244585
244630
|
try {
|
|
244586
244631
|
await fs5.stat(packageConfigPath);
|
|
244587
244632
|
} catch {
|
|
@@ -244589,7 +244634,7 @@ class Package {
|
|
|
244589
244634
|
}
|
|
244590
244635
|
}
|
|
244591
244636
|
static async readPackageConfig(packagePath) {
|
|
244592
|
-
const packageConfigPath =
|
|
244637
|
+
const packageConfigPath = path5.join(packagePath, PACKAGE_MANIFEST_NAME);
|
|
244593
244638
|
const packageConfigContents = await fs5.readFile(packageConfigPath);
|
|
244594
244639
|
const packageManifest = JSON.parse(packageConfigContents.toString());
|
|
244595
244640
|
return {
|
|
@@ -244611,13 +244656,13 @@ class Package {
|
|
|
244611
244656
|
let files = undefined;
|
|
244612
244657
|
files = await import_recursive_readdir.default(packagePath);
|
|
244613
244658
|
return files.map((fullPath) => {
|
|
244614
|
-
return
|
|
244659
|
+
return path5.relative(packagePath, fullPath).replace(/\\/g, "/");
|
|
244615
244660
|
}).filter((modelPath) => modelPath.endsWith(".parquet") || modelPath.endsWith(".csv"));
|
|
244616
244661
|
}
|
|
244617
244662
|
static async getDatabaseInfo(packagePath, databasePath) {
|
|
244618
|
-
const fullPath =
|
|
244619
|
-
const runtime = new
|
|
244620
|
-
urlReader: new
|
|
244663
|
+
const fullPath = path5.join(packagePath, databasePath);
|
|
244664
|
+
const runtime = new import_malloy3.ConnectionRuntime({
|
|
244665
|
+
urlReader: new import_malloy3.EmptyURLReader,
|
|
244621
244666
|
connections: [new import_db_duckdb.DuckDBConnection("duckdb")]
|
|
244622
244667
|
});
|
|
244623
244668
|
const model = runtime.loadModel(`source: temp is duckdb.table('${fullPath}')`);
|
|
@@ -244631,6 +244676,15 @@ class Package {
|
|
|
244631
244676
|
const rowCount = result.data.value[0].row_count?.valueOf();
|
|
244632
244677
|
return { name: databasePath, rowCount, columns: schema };
|
|
244633
244678
|
}
|
|
244679
|
+
setName(name) {
|
|
244680
|
+
this.packageName = name;
|
|
244681
|
+
}
|
|
244682
|
+
setProjectName(projectName) {
|
|
244683
|
+
this.projectName = projectName;
|
|
244684
|
+
}
|
|
244685
|
+
setPackageMetadata(packageMetadata) {
|
|
244686
|
+
this.packageMetadata = packageMetadata;
|
|
244687
|
+
}
|
|
244634
244688
|
}
|
|
244635
244689
|
|
|
244636
244690
|
// src/service/project.ts
|
|
@@ -244642,12 +244696,36 @@ class Project {
|
|
|
244642
244696
|
internalConnections;
|
|
244643
244697
|
projectPath;
|
|
244644
244698
|
projectName;
|
|
244699
|
+
metadata;
|
|
244645
244700
|
constructor(projectName, projectPath, malloyConnections, internalConnections, apiConnections) {
|
|
244646
244701
|
this.projectName = projectName;
|
|
244647
244702
|
this.projectPath = projectPath;
|
|
244648
244703
|
this.malloyConnections = malloyConnections;
|
|
244649
244704
|
this.internalConnections = internalConnections;
|
|
244650
244705
|
this.apiConnections = apiConnections;
|
|
244706
|
+
this.metadata = {
|
|
244707
|
+
resource: `${API_PREFIX}/projects/${this.projectName}`,
|
|
244708
|
+
name: this.projectName
|
|
244709
|
+
};
|
|
244710
|
+
this.reloadProjectMetadata();
|
|
244711
|
+
}
|
|
244712
|
+
async update(payload) {
|
|
244713
|
+
if (payload.name) {
|
|
244714
|
+
this.projectName = payload.name;
|
|
244715
|
+
this.packages.forEach((_package) => {
|
|
244716
|
+
_package.setProjectName(this.projectName);
|
|
244717
|
+
});
|
|
244718
|
+
this.metadata.name = this.projectName;
|
|
244719
|
+
}
|
|
244720
|
+
if (payload.resource) {
|
|
244721
|
+
this.projectPath = payload.resource.replace(`${API_PREFIX}/projects/`, "");
|
|
244722
|
+
if (!await fs6.exists(this.projectPath)) {
|
|
244723
|
+
throw new ProjectNotFoundError(`Project path "${this.projectPath}" not found`);
|
|
244724
|
+
}
|
|
244725
|
+
this.metadata.resource = payload.resource;
|
|
244726
|
+
}
|
|
244727
|
+
this.metadata.readme = payload.readme;
|
|
244728
|
+
return this;
|
|
244651
244729
|
}
|
|
244652
244730
|
static async create(projectName, projectPath) {
|
|
244653
244731
|
if (!(await fs6.stat(projectPath)).isDirectory()) {
|
|
@@ -244663,16 +244741,17 @@ class Project {
|
|
|
244663
244741
|
};
|
|
244664
244742
|
}));
|
|
244665
244743
|
}
|
|
244666
|
-
async
|
|
244744
|
+
async reloadProjectMetadata() {
|
|
244667
244745
|
let readme = "";
|
|
244668
244746
|
try {
|
|
244669
|
-
readme = (await fs6.readFile(
|
|
244747
|
+
readme = (await fs6.readFile(path6.join(this.projectPath, README_NAME))).toString();
|
|
244670
244748
|
} catch {}
|
|
244671
|
-
|
|
244749
|
+
this.metadata = {
|
|
244672
244750
|
resource: `${API_PREFIX}/projects/${this.projectName}`,
|
|
244673
244751
|
name: this.projectName,
|
|
244674
244752
|
readme
|
|
244675
244753
|
};
|
|
244754
|
+
return this.metadata;
|
|
244676
244755
|
}
|
|
244677
244756
|
listApiConnections() {
|
|
244678
244757
|
return this.apiConnections;
|
|
@@ -244729,7 +244808,7 @@ class Project {
|
|
|
244729
244808
|
return _package;
|
|
244730
244809
|
}
|
|
244731
244810
|
try {
|
|
244732
|
-
const _package2 = await Package.create(this.projectName, packageName,
|
|
244811
|
+
const _package2 = await Package.create(this.projectName, packageName, path6.join(this.projectPath, packageName), this.malloyConnections);
|
|
244733
244812
|
this.packages.set(packageName, _package2);
|
|
244734
244813
|
return _package2;
|
|
244735
244814
|
} catch (error) {
|
|
@@ -244738,41 +244817,131 @@ class Project {
|
|
|
244738
244817
|
}
|
|
244739
244818
|
});
|
|
244740
244819
|
}
|
|
244820
|
+
async addPackage(packageName) {
|
|
244821
|
+
const packagePath = path6.join(this.projectPath, packageName);
|
|
244822
|
+
if (!await fs6.exists(packagePath) || !(await fs6.stat(packagePath)).isDirectory()) {
|
|
244823
|
+
throw new PackageNotFoundError(`Package ${packageName} not found`);
|
|
244824
|
+
}
|
|
244825
|
+
this.packages.set(packageName, await Package.create(this.projectName, packageName, packagePath, this.malloyConnections));
|
|
244826
|
+
return this.packages.get(packageName);
|
|
244827
|
+
}
|
|
244828
|
+
async updatePackage(packageName, body) {
|
|
244829
|
+
const _package = this.packages.get(packageName);
|
|
244830
|
+
if (!_package) {
|
|
244831
|
+
throw new PackageNotFoundError(`Package ${packageName} not found`);
|
|
244832
|
+
}
|
|
244833
|
+
if (body.name) {
|
|
244834
|
+
_package.setName(body.name);
|
|
244835
|
+
}
|
|
244836
|
+
_package.setPackageMetadata({
|
|
244837
|
+
name: body.name,
|
|
244838
|
+
description: body.description,
|
|
244839
|
+
resource: body.resource
|
|
244840
|
+
});
|
|
244841
|
+
return _package.getPackageMetadata();
|
|
244842
|
+
}
|
|
244843
|
+
async deletePackage(packageName) {
|
|
244844
|
+
const _package = this.packages.get(packageName);
|
|
244845
|
+
if (!_package) {
|
|
244846
|
+
throw new PackageNotFoundError(`Package ${packageName} not found`);
|
|
244847
|
+
}
|
|
244848
|
+
this.packages.delete(packageName);
|
|
244849
|
+
}
|
|
244741
244850
|
}
|
|
244742
244851
|
|
|
244743
244852
|
// src/service/project_store.ts
|
|
244744
244853
|
class ProjectStore {
|
|
244745
244854
|
serverRootPath;
|
|
244746
244855
|
projects = new Map;
|
|
244856
|
+
publisherConfigIsFrozen;
|
|
244747
244857
|
constructor(serverRootPath) {
|
|
244748
244858
|
this.serverRootPath = serverRootPath;
|
|
244859
|
+
this.initialize();
|
|
244749
244860
|
}
|
|
244750
|
-
async
|
|
244751
|
-
|
|
244752
|
-
|
|
244753
|
-
|
|
244754
|
-
|
|
244755
|
-
|
|
244756
|
-
|
|
244757
|
-
|
|
244758
|
-
|
|
244861
|
+
async initialize() {
|
|
244862
|
+
try {
|
|
244863
|
+
this.publisherConfigIsFrozen = isPublisherConfigFrozen(this.serverRootPath);
|
|
244864
|
+
const projectManifest = await ProjectStore.reloadProjectManifest(this.serverRootPath);
|
|
244865
|
+
for (const projectName of Object.keys(projectManifest.projects)) {
|
|
244866
|
+
const projectPath = projectManifest.projects[projectName];
|
|
244867
|
+
const absoluteProjectPath = path7.join(this.serverRootPath, projectPath);
|
|
244868
|
+
const project = await Project.create(projectName, absoluteProjectPath);
|
|
244869
|
+
this.projects.set(projectName, project);
|
|
244870
|
+
}
|
|
244871
|
+
logger.info("Project store successfully initialized");
|
|
244872
|
+
} catch (error) {
|
|
244873
|
+
logger.error("Error initializing project store", { error });
|
|
244874
|
+
process.exit(1);
|
|
244759
244875
|
}
|
|
244760
244876
|
}
|
|
244877
|
+
listProjects() {
|
|
244878
|
+
return Array.from(this.projects.values()).map((project) => project.metadata);
|
|
244879
|
+
}
|
|
244761
244880
|
async getProject(projectName, reload) {
|
|
244762
244881
|
let project = this.projects.get(projectName);
|
|
244763
244882
|
if (project === undefined || reload) {
|
|
244764
|
-
const projectManifest = await ProjectStore.
|
|
244883
|
+
const projectManifest = await ProjectStore.reloadProjectManifest(this.serverRootPath);
|
|
244765
244884
|
if (!projectManifest.projects || !projectManifest.projects[projectName]) {
|
|
244766
|
-
throw new ProjectNotFoundError(`Project ${projectName} not found in publisher
|
|
244885
|
+
throw new ProjectNotFoundError(`Project "${projectName}" not found in publisher`);
|
|
244767
244886
|
}
|
|
244768
|
-
project = await
|
|
244769
|
-
|
|
244887
|
+
project = await this.addProject({
|
|
244888
|
+
name: projectName,
|
|
244889
|
+
resource: `${API_PREFIX}/projects/${projectName}`
|
|
244890
|
+
});
|
|
244770
244891
|
}
|
|
244771
244892
|
return project;
|
|
244772
244893
|
}
|
|
244773
|
-
|
|
244894
|
+
async addProject(project) {
|
|
244895
|
+
if (this.publisherConfigIsFrozen) {
|
|
244896
|
+
throw new FrozenConfigError;
|
|
244897
|
+
}
|
|
244898
|
+
const projectName = project.name;
|
|
244899
|
+
if (!projectName) {
|
|
244900
|
+
throw new Error("Project name is required");
|
|
244901
|
+
}
|
|
244902
|
+
const projectManifest = await ProjectStore.reloadProjectManifest(this.serverRootPath);
|
|
244903
|
+
const projectPath = projectManifest.projects[projectName];
|
|
244904
|
+
if (!projectPath) {
|
|
244905
|
+
throw new ProjectNotFoundError(`Project "${projectName}" not found in publisher.config.json`);
|
|
244906
|
+
}
|
|
244907
|
+
const absoluteProjectPath = path7.join(this.serverRootPath, projectPath);
|
|
244908
|
+
if (!(await fs7.stat(absoluteProjectPath)).isDirectory()) {
|
|
244909
|
+
throw new ProjectNotFoundError(`Project ${projectName} not found in ${absoluteProjectPath}`);
|
|
244910
|
+
}
|
|
244911
|
+
const newProject = await Project.create(projectName, absoluteProjectPath);
|
|
244912
|
+
this.projects.set(projectName, newProject);
|
|
244913
|
+
return newProject;
|
|
244914
|
+
}
|
|
244915
|
+
async updateProject(project) {
|
|
244916
|
+
if (this.publisherConfigIsFrozen) {
|
|
244917
|
+
throw new FrozenConfigError;
|
|
244918
|
+
}
|
|
244919
|
+
const projectName = project.name;
|
|
244920
|
+
if (!projectName) {
|
|
244921
|
+
throw new Error("Project name is required");
|
|
244922
|
+
}
|
|
244923
|
+
const existingProject = this.projects.get(projectName);
|
|
244924
|
+
if (!existingProject) {
|
|
244925
|
+
throw new ProjectNotFoundError(`Project ${projectName} not found`);
|
|
244926
|
+
}
|
|
244927
|
+
const updatedProject = await existingProject.update(project);
|
|
244928
|
+
this.projects.set(projectName, updatedProject);
|
|
244929
|
+
return updatedProject;
|
|
244930
|
+
}
|
|
244931
|
+
async deleteProject(projectName) {
|
|
244932
|
+
if (this.publisherConfigIsFrozen) {
|
|
244933
|
+
throw new FrozenConfigError;
|
|
244934
|
+
}
|
|
244935
|
+
const project = this.projects.get(projectName);
|
|
244936
|
+
if (!project) {
|
|
244937
|
+
throw new ProjectNotFoundError(`Project ${projectName} not found`);
|
|
244938
|
+
}
|
|
244939
|
+
this.projects.delete(projectName);
|
|
244940
|
+
return project;
|
|
244941
|
+
}
|
|
244942
|
+
static async reloadProjectManifest(serverRootPath) {
|
|
244774
244943
|
try {
|
|
244775
|
-
const projectManifestContent = await fs7.readFile(
|
|
244944
|
+
const projectManifestContent = await fs7.readFile(path7.join(serverRootPath, "publisher.config.json"), "utf8");
|
|
244776
244945
|
return JSON.parse(projectManifestContent);
|
|
244777
244946
|
} catch (error) {
|
|
244778
244947
|
if (error.code !== "ENOENT") {
|
|
@@ -244841,11 +245010,11 @@ var MCP_PORT = Number(process.env.MCP_PORT || 4040);
|
|
|
244841
245010
|
var MCP_ENDPOINT = "/mcp";
|
|
244842
245011
|
var ROOT;
|
|
244843
245012
|
if (require.main) {
|
|
244844
|
-
ROOT =
|
|
245013
|
+
ROOT = path8.join(path8.dirname(require.main.filename), "app");
|
|
244845
245014
|
} else {
|
|
244846
|
-
ROOT =
|
|
245015
|
+
ROOT = path8.join(path8.dirname(process.argv[1] || __filename), "app");
|
|
244847
245016
|
}
|
|
244848
|
-
var SERVER_ROOT =
|
|
245017
|
+
var SERVER_ROOT = path8.resolve(process.cwd(), process.env.SERVER_ROOT || ".");
|
|
244849
245018
|
var API_PREFIX2 = "/api/v0";
|
|
244850
245019
|
var isDevelopment = process.env["NODE_ENV"] === "development";
|
|
244851
245020
|
var app = import_express.default();
|
|
@@ -244859,7 +245028,6 @@ var databaseController = new DatabaseController(projectStore);
|
|
|
244859
245028
|
var queryController = new QueryController(projectStore);
|
|
244860
245029
|
var scheduleController = new ScheduleController(projectStore);
|
|
244861
245030
|
var mcpApp = import_express.default();
|
|
244862
|
-
initProjects();
|
|
244863
245031
|
mcpApp.use(MCP_ENDPOINT, import_express.default.json());
|
|
244864
245032
|
mcpApp.use(MCP_ENDPOINT, import_cors.default());
|
|
244865
245033
|
mcpApp.all(MCP_ENDPOINT, async (req, res) => {
|
|
@@ -244921,14 +245089,14 @@ mcpApp.all(MCP_ENDPOINT, async (req, res) => {
|
|
|
244921
245089
|
});
|
|
244922
245090
|
if (!isDevelopment) {
|
|
244923
245091
|
app.use("/", import_express.default.static(ROOT));
|
|
244924
|
-
app.use("/api-doc.html", import_express.default.static(
|
|
245092
|
+
app.use("/api-doc.html", import_express.default.static(path8.join(ROOT, "api-doc.html")));
|
|
244925
245093
|
} else {
|
|
244926
245094
|
app.use(`${API_PREFIX2}`, loggerMiddleware);
|
|
244927
245095
|
app.use(import_http_proxy_middleware.createProxyMiddleware({
|
|
244928
245096
|
target: "http://localhost:5173",
|
|
244929
245097
|
changeOrigin: true,
|
|
244930
245098
|
ws: true,
|
|
244931
|
-
pathFilter: (
|
|
245099
|
+
pathFilter: (path9) => !path9.startsWith("/api/")
|
|
244932
245100
|
}));
|
|
244933
245101
|
}
|
|
244934
245102
|
var setVersionIdError = (res) => {
|
|
@@ -244946,10 +245114,37 @@ app.get(`${API_PREFIX2}/projects`, async (_req, res) => {
|
|
|
244946
245114
|
res.status(status).json(json2);
|
|
244947
245115
|
}
|
|
244948
245116
|
});
|
|
245117
|
+
app.post(`${API_PREFIX2}/projects`, async (req, res) => {
|
|
245118
|
+
try {
|
|
245119
|
+
res.status(200).json(await projectStore.addProject(req.body));
|
|
245120
|
+
} catch (error) {
|
|
245121
|
+
logger.error(error);
|
|
245122
|
+
const { json: json2, status } = internalErrorToHttpError(error);
|
|
245123
|
+
res.status(status).json(json2);
|
|
245124
|
+
}
|
|
245125
|
+
});
|
|
244949
245126
|
app.get(`${API_PREFIX2}/projects/:projectName`, async (req, res) => {
|
|
244950
245127
|
try {
|
|
244951
245128
|
const project = await projectStore.getProject(req.params.projectName, req.query.reload === "true");
|
|
244952
|
-
res.status(200).json(
|
|
245129
|
+
res.status(200).json(project.metadata);
|
|
245130
|
+
} catch (error) {
|
|
245131
|
+
logger.error(error);
|
|
245132
|
+
const { json: json2, status } = internalErrorToHttpError(error);
|
|
245133
|
+
res.status(status).json(json2);
|
|
245134
|
+
}
|
|
245135
|
+
});
|
|
245136
|
+
app.patch(`${API_PREFIX2}/projects/:projectName`, async (req, res) => {
|
|
245137
|
+
try {
|
|
245138
|
+
res.status(200).json(await projectStore.updateProject(req.body));
|
|
245139
|
+
} catch (error) {
|
|
245140
|
+
logger.error(error);
|
|
245141
|
+
const { json: json2, status } = internalErrorToHttpError(error);
|
|
245142
|
+
res.status(status).json(json2);
|
|
245143
|
+
}
|
|
245144
|
+
});
|
|
245145
|
+
app.delete(`${API_PREFIX2}/projects/:projectName`, async (req, res) => {
|
|
245146
|
+
try {
|
|
245147
|
+
res.status(200).json(await projectStore.deleteProject(req.params.projectName));
|
|
244953
245148
|
} catch (error) {
|
|
244954
245149
|
logger.error(error);
|
|
244955
245150
|
const { json: json2, status } = internalErrorToHttpError(error);
|
|
@@ -245053,6 +245248,15 @@ app.get(`${API_PREFIX2}/projects/:projectName/packages`, async (req, res) => {
|
|
|
245053
245248
|
res.status(status).json(json2);
|
|
245054
245249
|
}
|
|
245055
245250
|
});
|
|
245251
|
+
app.post(`${API_PREFIX2}/projects/:projectName/packages`, async (req, res) => {
|
|
245252
|
+
try {
|
|
245253
|
+
res.status(200).json(await packageController.addPackage(req.params.projectName, req.body));
|
|
245254
|
+
} catch (error) {
|
|
245255
|
+
logger.error(error);
|
|
245256
|
+
const { json: json2, status } = internalErrorToHttpError(error);
|
|
245257
|
+
res.status(status).json(json2);
|
|
245258
|
+
}
|
|
245259
|
+
});
|
|
245056
245260
|
app.get(`${API_PREFIX2}/projects/:projectName/packages/:packageName`, async (req, res) => {
|
|
245057
245261
|
if (req.query.versionId) {
|
|
245058
245262
|
setVersionIdError(res);
|
|
@@ -245066,6 +245270,24 @@ app.get(`${API_PREFIX2}/projects/:projectName/packages/:packageName`, async (req
|
|
|
245066
245270
|
res.status(status).json(json2);
|
|
245067
245271
|
}
|
|
245068
245272
|
});
|
|
245273
|
+
app.patch(`${API_PREFIX2}/projects/:projectName/packages/:packageName`, async (req, res) => {
|
|
245274
|
+
try {
|
|
245275
|
+
res.status(200).json(await packageController.updatePackage(req.params.projectName, req.params.packageName, req.body));
|
|
245276
|
+
} catch (error) {
|
|
245277
|
+
logger.error(error);
|
|
245278
|
+
const { json: json2, status } = internalErrorToHttpError(error);
|
|
245279
|
+
res.status(status).json(json2);
|
|
245280
|
+
}
|
|
245281
|
+
});
|
|
245282
|
+
app.delete(`${API_PREFIX2}/projects/:projectName/packages/:packageName`, async (req, res) => {
|
|
245283
|
+
try {
|
|
245284
|
+
res.status(200).json(await packageController.deletePackage(req.params.projectName, req.params.packageName));
|
|
245285
|
+
} catch (error) {
|
|
245286
|
+
logger.error(error);
|
|
245287
|
+
const { json: json2, status } = internalErrorToHttpError(error);
|
|
245288
|
+
res.status(status).json(json2);
|
|
245289
|
+
}
|
|
245290
|
+
});
|
|
245069
245291
|
app.get(`${API_PREFIX2}/projects/:projectName/packages/:packageName/models`, async (req, res) => {
|
|
245070
245292
|
if (req.query.versionId) {
|
|
245071
245293
|
setVersionIdError(res);
|
|
@@ -245161,9 +245383,9 @@ app.get(`${API_PREFIX2}/projects/:projectName/packages/:packageName/databases`,
|
|
|
245161
245383
|
}
|
|
245162
245384
|
});
|
|
245163
245385
|
if (!isDevelopment) {
|
|
245164
|
-
app.get("*", (_req, res) => res.sendFile(
|
|
245386
|
+
app.get("*", (_req, res) => res.sendFile(path8.resolve(ROOT, "index.html")));
|
|
245165
245387
|
}
|
|
245166
|
-
app.use((err, _req, res) => {
|
|
245388
|
+
app.use((err, _req, res, _next) => {
|
|
245167
245389
|
logger.error("Unhandled error:", err);
|
|
245168
245390
|
const { json: json2, status } = internalErrorToHttpError(err);
|
|
245169
245391
|
res.status(status).json(json2);
|
|
@@ -245179,12 +245401,3 @@ mainServer.listen(PUBLISHER_PORT, PUBLISHER_HOST, () => {
|
|
|
245179
245401
|
var mcpHttpServer = mcpApp.listen(MCP_PORT, PUBLISHER_HOST, () => {
|
|
245180
245402
|
logger.info(`MCP server listening at http://${PUBLISHER_HOST}:${MCP_PORT}`);
|
|
245181
245403
|
});
|
|
245182
|
-
function initProjects() {
|
|
245183
|
-
projectStore.listProjects().then((projects) => {
|
|
245184
|
-
projects.forEach((project) => {
|
|
245185
|
-
projectStore.getProject(project.name, false).then((project2) => {
|
|
245186
|
-
project2.listPackages();
|
|
245187
|
-
});
|
|
245188
|
-
});
|
|
245189
|
-
});
|
|
245190
|
-
}
|