@nocobase/plugin-multi-app-manager 0.12.0-alpha.4 → 0.13.0-alpha.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.
@@ -0,0 +1,136 @@
1
+ 'use strict';
2
+
3
+ var test = require('tape');
4
+ var inspect = require('object-inspect');
5
+ var SaferBuffer = require('safer-buffer').Buffer;
6
+ var forEach = require('for-each');
7
+ var utils = require('../lib/utils');
8
+
9
+ test('merge()', function (t) {
10
+ t.deepEqual(utils.merge(null, true), [null, true], 'merges true into null');
11
+
12
+ t.deepEqual(utils.merge(null, [42]), [null, 42], 'merges null into an array');
13
+
14
+ t.deepEqual(utils.merge({ a: 'b' }, { a: 'c' }), { a: ['b', 'c'] }, 'merges two objects with the same key');
15
+
16
+ var oneMerged = utils.merge({ foo: 'bar' }, { foo: { first: '123' } });
17
+ t.deepEqual(oneMerged, { foo: ['bar', { first: '123' }] }, 'merges a standalone and an object into an array');
18
+
19
+ var twoMerged = utils.merge({ foo: ['bar', { first: '123' }] }, { foo: { second: '456' } });
20
+ t.deepEqual(twoMerged, { foo: { 0: 'bar', 1: { first: '123' }, second: '456' } }, 'merges a standalone and two objects into an array');
21
+
22
+ var sandwiched = utils.merge({ foo: ['bar', { first: '123', second: '456' }] }, { foo: 'baz' });
23
+ t.deepEqual(sandwiched, { foo: ['bar', { first: '123', second: '456' }, 'baz'] }, 'merges an object sandwiched by two standalones into an array');
24
+
25
+ var nestedArrays = utils.merge({ foo: ['baz'] }, { foo: ['bar', 'xyzzy'] });
26
+ t.deepEqual(nestedArrays, { foo: ['baz', 'bar', 'xyzzy'] });
27
+
28
+ var noOptionsNonObjectSource = utils.merge({ foo: 'baz' }, 'bar');
29
+ t.deepEqual(noOptionsNonObjectSource, { foo: 'baz', bar: true });
30
+
31
+ t.test(
32
+ 'avoids invoking array setters unnecessarily',
33
+ { skip: typeof Object.defineProperty !== 'function' },
34
+ function (st) {
35
+ var setCount = 0;
36
+ var getCount = 0;
37
+ var observed = [];
38
+ Object.defineProperty(observed, 0, {
39
+ get: function () {
40
+ getCount += 1;
41
+ return { bar: 'baz' };
42
+ },
43
+ set: function () { setCount += 1; }
44
+ });
45
+ utils.merge(observed, [null]);
46
+ st.equal(setCount, 0);
47
+ st.equal(getCount, 1);
48
+ observed[0] = observed[0]; // eslint-disable-line no-self-assign
49
+ st.equal(setCount, 1);
50
+ st.equal(getCount, 2);
51
+ st.end();
52
+ }
53
+ );
54
+
55
+ t.end();
56
+ });
57
+
58
+ test('assign()', function (t) {
59
+ var target = { a: 1, b: 2 };
60
+ var source = { b: 3, c: 4 };
61
+ var result = utils.assign(target, source);
62
+
63
+ t.equal(result, target, 'returns the target');
64
+ t.deepEqual(target, { a: 1, b: 3, c: 4 }, 'target and source are merged');
65
+ t.deepEqual(source, { b: 3, c: 4 }, 'source is untouched');
66
+
67
+ t.end();
68
+ });
69
+
70
+ test('combine()', function (t) {
71
+ t.test('both arrays', function (st) {
72
+ var a = [1];
73
+ var b = [2];
74
+ var combined = utils.combine(a, b);
75
+
76
+ st.deepEqual(a, [1], 'a is not mutated');
77
+ st.deepEqual(b, [2], 'b is not mutated');
78
+ st.notEqual(a, combined, 'a !== combined');
79
+ st.notEqual(b, combined, 'b !== combined');
80
+ st.deepEqual(combined, [1, 2], 'combined is a + b');
81
+
82
+ st.end();
83
+ });
84
+
85
+ t.test('one array, one non-array', function (st) {
86
+ var aN = 1;
87
+ var a = [aN];
88
+ var bN = 2;
89
+ var b = [bN];
90
+
91
+ var combinedAnB = utils.combine(aN, b);
92
+ st.deepEqual(b, [bN], 'b is not mutated');
93
+ st.notEqual(aN, combinedAnB, 'aN + b !== aN');
94
+ st.notEqual(a, combinedAnB, 'aN + b !== a');
95
+ st.notEqual(bN, combinedAnB, 'aN + b !== bN');
96
+ st.notEqual(b, combinedAnB, 'aN + b !== b');
97
+ st.deepEqual([1, 2], combinedAnB, 'first argument is array-wrapped when not an array');
98
+
99
+ var combinedABn = utils.combine(a, bN);
100
+ st.deepEqual(a, [aN], 'a is not mutated');
101
+ st.notEqual(aN, combinedABn, 'a + bN !== aN');
102
+ st.notEqual(a, combinedABn, 'a + bN !== a');
103
+ st.notEqual(bN, combinedABn, 'a + bN !== bN');
104
+ st.notEqual(b, combinedABn, 'a + bN !== b');
105
+ st.deepEqual([1, 2], combinedABn, 'second argument is array-wrapped when not an array');
106
+
107
+ st.end();
108
+ });
109
+
110
+ t.test('neither is an array', function (st) {
111
+ var combined = utils.combine(1, 2);
112
+ st.notEqual(1, combined, '1 + 2 !== 1');
113
+ st.notEqual(2, combined, '1 + 2 !== 2');
114
+ st.deepEqual([1, 2], combined, 'both arguments are array-wrapped when not an array');
115
+
116
+ st.end();
117
+ });
118
+
119
+ t.end();
120
+ });
121
+
122
+ test('isBuffer()', function (t) {
123
+ forEach([null, undefined, true, false, '', 'abc', 42, 0, NaN, {}, [], function () {}, /a/g], function (x) {
124
+ t.equal(utils.isBuffer(x), false, inspect(x) + ' is not a buffer');
125
+ });
126
+
127
+ var fakeBuffer = { constructor: Buffer };
128
+ t.equal(utils.isBuffer(fakeBuffer), false, 'fake buffer is not a buffer');
129
+
130
+ var saferBuffer = SaferBuffer.from('abc');
131
+ t.equal(utils.isBuffer(saferBuffer), true, 'SaferBuffer instance is a buffer');
132
+
133
+ var buffer = Buffer.from && Buffer.alloc ? Buffer.from('abc') : new Buffer('abc');
134
+ t.equal(utils.isBuffer(buffer), true, 'real Buffer instance is a buffer');
135
+ t.end();
136
+ });
@@ -6,5 +6,5 @@ export interface registerAppOptions extends Transactionable {
6
6
  appOptionsFactory: AppOptionsFactory;
7
7
  }
8
8
  export declare class ApplicationModel extends Model {
9
- registerToMainApp(mainApp: Application, options: registerAppOptions): Application<import("@nocobase/server").DefaultState, import("@nocobase/server").DefaultContext>;
9
+ registerToSupervisor(mainApp: Application, options: registerAppOptions): Application<import("@nocobase/server").DefaultState, import("@nocobase/server").DefaultContext>;
10
10
  }
@@ -4,7 +4,7 @@ var database = require('@nocobase/database');
4
4
  var server = require('@nocobase/server');
5
5
 
6
6
  class ApplicationModel extends database.Model {
7
- registerToMainApp(mainApp, options) {
7
+ registerToSupervisor(mainApp, options) {
8
8
  const appName = this.get("name");
9
9
  const appOptions = this.get("options") || {};
10
10
  const subAppOptions = {
@@ -12,10 +12,7 @@ class ApplicationModel extends database.Model {
12
12
  ...appOptions,
13
13
  name: appName
14
14
  };
15
- const subApp = new server.Application(subAppOptions);
16
- mainApp.appManager.addSubApp(subApp);
17
- console.log(`register application ${appName} to main app`);
18
- return subApp;
15
+ return new server.Application(subAppOptions);
19
16
  }
20
17
  }
21
18
 
@@ -6,9 +6,9 @@ export declare class PluginMultiAppManager extends Plugin {
6
6
  appDbCreator: AppDbCreator;
7
7
  appOptionsFactory: AppOptionsFactory;
8
8
  private beforeGetApplicationMutex;
9
+ static getDatabaseConfig(app: Application): IDatabaseOptions;
9
10
  setAppOptionsFactory(factory: AppOptionsFactory): void;
10
11
  setAppDbCreator(appDbCreator: AppDbCreator): void;
11
- static getDatabaseConfig(app: Application): IDatabaseOptions;
12
12
  beforeLoad(): void;
13
13
  load(): Promise<void>;
14
14
  }
@@ -1,35 +1,19 @@
1
1
  'use strict';
2
2
 
3
- var Database = require('@nocobase/database');
3
+ var database = require('@nocobase/database');
4
4
  var server = require('@nocobase/server');
5
+ var asyncMutex = require('async-mutex');
5
6
  var lodash = require('lodash');
6
7
  var path = require('path');
7
- var application = require('./models/application');
8
- var asyncMutex = require('async-mutex');
8
+ var qs = require('qs');
9
+ var url = require('url');
10
+ var server$1 = require('../server');
9
11
 
10
12
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
11
13
 
12
- function _interopNamespace(e) {
13
- if (e && e.__esModule) return e;
14
- var n = Object.create(null);
15
- if (e) {
16
- Object.keys(e).forEach(function (k) {
17
- if (k !== 'default') {
18
- var d = Object.getOwnPropertyDescriptor(e, k);
19
- Object.defineProperty(n, k, d.get ? d : {
20
- enumerable: true,
21
- get: function () { return e[k]; }
22
- });
23
- }
24
- });
25
- }
26
- n.default = e;
27
- return Object.freeze(n);
28
- }
29
-
30
- var Database__default = /*#__PURE__*/_interopDefault(Database);
31
14
  var lodash__default = /*#__PURE__*/_interopDefault(lodash);
32
- var path__namespace = /*#__PURE__*/_interopNamespace(path);
15
+ var path__default = /*#__PURE__*/_interopDefault(path);
16
+ var qs__default = /*#__PURE__*/_interopDefault(qs);
33
17
 
34
18
  const defaultDbCreator = async (app) => {
35
19
  const databaseOptions = app.options.database;
@@ -53,6 +37,7 @@ const defaultDbCreator = async (app) => {
53
37
  try {
54
38
  await client.query(`CREATE DATABASE "${database}"`);
55
39
  } catch (e) {
40
+ console.log(e);
56
41
  }
57
42
  await client.end();
58
43
  }
@@ -62,8 +47,8 @@ const defaultAppOptionsFactory = (appName, mainApp) => {
62
47
  if (rawDatabaseOptions.dialect === "sqlite") {
63
48
  const mainAppStorage = rawDatabaseOptions.storage;
64
49
  if (mainAppStorage !== ":memory:") {
65
- const mainStorageDir = path__namespace.dirname(mainAppStorage);
66
- rawDatabaseOptions.storage = path__namespace.join(mainStorageDir, `${appName}.sqlite`);
50
+ const mainStorageDir = path__default.default.dirname(mainAppStorage);
51
+ rawDatabaseOptions.storage = path__default.default.join(mainStorageDir, `${appName}.sqlite`);
67
52
  }
68
53
  } else {
69
54
  rawDatabaseOptions.database = appName;
@@ -83,23 +68,79 @@ class PluginMultiAppManager extends server.Plugin {
83
68
  appDbCreator = defaultDbCreator;
84
69
  appOptionsFactory = defaultAppOptionsFactory;
85
70
  beforeGetApplicationMutex = new asyncMutex.Mutex();
71
+ static getDatabaseConfig(app) {
72
+ const oldConfig = app.options.database instanceof database.Database ? app.options.database.options : app.options.database;
73
+ return lodash__default.default.cloneDeep(lodash__default.default.omit(oldConfig, ["migrator"]));
74
+ }
86
75
  setAppOptionsFactory(factory) {
87
76
  this.appOptionsFactory = factory;
88
77
  }
89
78
  setAppDbCreator(appDbCreator) {
90
79
  this.appDbCreator = appDbCreator;
91
80
  }
92
- static getDatabaseConfig(app) {
93
- const oldConfig = app.options.database instanceof Database__default.default ? app.options.database.options : app.options.database;
94
- return lodash__default.default.cloneDeep(lodash__default.default.omit(oldConfig, ["migrator"]));
95
- }
96
81
  beforeLoad() {
97
82
  this.db.registerModels({
98
- ApplicationModel: application.ApplicationModel
83
+ ApplicationModel: server$1.ApplicationModel
99
84
  });
100
85
  }
101
86
  async load() {
102
- this.app.appManager.setAppSelector(async (req) => {
87
+ await this.db.import({
88
+ directory: path.resolve(__dirname, "collections")
89
+ });
90
+ this.db.on("applications.afterCreateWithAssociations", async (model, options) => {
91
+ var _a;
92
+ const { transaction } = options;
93
+ const subApp = model.registerToSupervisor(this.app, {
94
+ appOptionsFactory: this.appOptionsFactory
95
+ });
96
+ await this.appDbCreator(subApp, transaction);
97
+ const startPromise = subApp.runAsCLI(["start", "--quickstart"], { from: "user" });
98
+ if ((_a = options == null ? void 0 : options.context) == null ? void 0 : _a.waitSubAppInstall) {
99
+ await startPromise;
100
+ }
101
+ });
102
+ this.db.on("applications.afterDestroy", async (model) => {
103
+ await server.AppSupervisor.getInstance().removeApp(model.get("name"));
104
+ });
105
+ const self = this;
106
+ async function LazyLoadApplication({
107
+ appSupervisor,
108
+ appName,
109
+ options
110
+ }) {
111
+ const name = appName;
112
+ if (appSupervisor.hasApp(name)) {
113
+ return;
114
+ }
115
+ const applicationRecord = await self.app.db.getRepository("applications").findOne({
116
+ filter: {
117
+ name
118
+ }
119
+ });
120
+ if (!applicationRecord) {
121
+ return;
122
+ }
123
+ const instanceOptions = applicationRecord.get("options");
124
+ if ((instanceOptions == null ? void 0 : instanceOptions.standaloneDeployment) && appSupervisor.runningMode !== "single") {
125
+ return;
126
+ }
127
+ if (!applicationRecord) {
128
+ return;
129
+ }
130
+ const subApp = applicationRecord.registerToSupervisor(self.app, {
131
+ appOptionsFactory: self.appOptionsFactory
132
+ });
133
+ if (!(options == null ? void 0 : options.upgrading)) {
134
+ await subApp.runCommand("start");
135
+ }
136
+ }
137
+ server.AppSupervisor.getInstance().setAppBootstrapper(LazyLoadApplication);
138
+ server.Gateway.getInstance().setAppSelector(async (req) => {
139
+ var _a;
140
+ const appName = (_a = qs__default.default.parse(url.parse(req.url).query)) == null ? void 0 : _a.__appName;
141
+ if (appName) {
142
+ return appName;
143
+ }
103
144
  if (req.headers["x-app"]) {
104
145
  return req.headers["x-app"];
105
146
  }
@@ -119,67 +160,16 @@ class PluginMultiAppManager extends server.Plugin {
119
160
  }
120
161
  return null;
121
162
  });
122
- await this.db.import({
123
- directory: path.resolve(__dirname, "collections")
124
- });
125
- this.db.on("applications.afterCreateWithAssociations", async (model, options) => {
126
- const { transaction } = options;
127
- const subApp = model.registerToMainApp(this.app, {
128
- appOptionsFactory: this.appOptionsFactory
129
- });
130
- await this.appDbCreator(subApp, transaction);
131
- await subApp.reload();
132
- await subApp.db.sync();
133
- await subApp.install();
134
- await subApp.reload();
135
- });
136
- this.db.on("applications.afterDestroy", async (model) => {
137
- await this.app.appManager.removeApplication(model.get("name"));
138
- });
139
- this.app.on(
140
- "beforeGetApplication",
141
- async ({ appManager, name, options }) => {
142
- await this.beforeGetApplicationMutex.runExclusive(async () => {
143
- if (appManager.applications.has(name)) {
144
- return;
145
- }
146
- const applicationRecord = await this.app.db.getRepository("applications").findOne({
147
- filter: {
148
- name
149
- }
150
- });
151
- const instanceOptions = applicationRecord.get("options");
152
- if ((instanceOptions == null ? void 0 : instanceOptions.standaloneDeployment) && appManager.runningMode !== "single") {
153
- return;
154
- }
155
- if (!applicationRecord) {
156
- return;
157
- }
158
- const subApp = await applicationRecord.registerToMainApp(this.app, {
159
- appOptionsFactory: this.appOptionsFactory
160
- });
161
- if (!(options == null ? void 0 : options.upgrading)) {
162
- await subApp.load();
163
- }
164
- });
165
- }
166
- );
167
163
  this.app.on("afterStart", async (app) => {
168
164
  const repository = this.db.getRepository("applications");
169
- const appManager = this.app.appManager;
170
- if (appManager.runningMode == "single") {
165
+ const appSupervisor = server.AppSupervisor.getInstance();
166
+ this.app.setMaintainingMessage("starting sub applications...");
167
+ if (appSupervisor.runningMode == "single") {
168
+ server.Gateway.getInstance().setAppSelector(() => appSupervisor.singleAppName);
171
169
  try {
172
- const subApp = await repository.findOne({
173
- filter: {
174
- name: appManager.singleAppName
175
- }
176
- });
177
- const registeredApp = await subApp.registerToMainApp(this.app, {
178
- appOptionsFactory: this.appOptionsFactory
179
- });
180
- await registeredApp.load();
170
+ await server.AppSupervisor.getInstance().getApp(appSupervisor.singleAppName);
181
171
  } catch (err) {
182
- console.error("Auto register sub application in single mode failed: ", appManager.singleAppName, err);
172
+ console.error("Auto register sub application in single mode failed: ", appSupervisor.singleAppName, err);
183
173
  }
184
174
  return;
185
175
  }
@@ -189,43 +179,47 @@ class PluginMultiAppManager extends server.Plugin {
189
179
  "options.autoStart": true
190
180
  }
191
181
  });
192
- for (const subApp of subApps) {
193
- const registeredApp = await subApp.registerToMainApp(this.app, {
194
- appOptionsFactory: this.appOptionsFactory
195
- });
196
- await registeredApp.load();
182
+ const promises = [];
183
+ for (const subAppInstance of subApps) {
184
+ promises.push(
185
+ (async () => {
186
+ await server.AppSupervisor.getInstance().getApp(subAppInstance.name);
187
+ })()
188
+ );
197
189
  }
190
+ await Promise.all(promises);
198
191
  } catch (err) {
199
192
  console.error("Auto register sub applications failed: ", err);
200
193
  }
201
194
  });
202
195
  this.app.on("afterUpgrade", async (app, options) => {
203
- const cliArgs = options == null ? void 0 : options.cliArgs;
196
+ options == null ? void 0 : options.cliArgs;
204
197
  const repository = this.db.getRepository("applications");
205
198
  const findOptions = {};
206
- const appManager = this.app.appManager;
207
- if (appManager.runningMode == "single") {
199
+ const appSupervisor = server.AppSupervisor.getInstance();
200
+ if (appSupervisor.runningMode == "single") {
208
201
  findOptions["filter"] = {
209
- name: appManager.singleAppName
202
+ name: appSupervisor.singleAppName
210
203
  };
211
204
  }
212
205
  const instances = await repository.find(findOptions);
213
206
  for (const instance of instances) {
214
207
  const instanceOptions = instance.get("options");
215
- if ((instanceOptions == null ? void 0 : instanceOptions.standaloneDeployment) && appManager.runningMode !== "single") {
208
+ if ((instanceOptions == null ? void 0 : instanceOptions.standaloneDeployment) && appSupervisor.runningMode !== "single") {
216
209
  continue;
217
210
  }
218
- const subApp = await appManager.getApplication(instance.name, {
211
+ const beforeSubAppStatus = server.AppSupervisor.getInstance().getAppStatus(instance.name);
212
+ const subApp = await appSupervisor.getApp(instance.name, {
219
213
  upgrading: true
220
214
  });
215
+ console.log({ beforeSubAppStatus });
221
216
  try {
217
+ this.app.setMaintainingMessage(`upgrading sub app ${instance.name}...`);
222
218
  console.log(`${instance.name}: upgrading...`);
223
- await subApp.upgrade({
224
- cliArgs
225
- });
226
- await subApp.stop({
227
- cliArgs
228
- });
219
+ await subApp.runAsCLI(["upgrade"], { from: "user" });
220
+ if (!beforeSubAppStatus && server.AppSupervisor.getInstance().getAppStatus(instance.name) === "initialized") {
221
+ await server.AppSupervisor.getInstance().removeApp(instance.name);
222
+ }
229
223
  } catch (error) {
230
224
  console.log(`${instance.name}: upgrade failed`);
231
225
  this.app.logger.error(error);
@@ -254,6 +248,17 @@ class PluginMultiAppManager extends server.Plugin {
254
248
  applications`,
255
249
  actions: ["applications:*"]
256
250
  });
251
+ this.app.resourcer.use(async (ctx, next) => {
252
+ await next();
253
+ const { actionName, resourceName, params } = ctx.action;
254
+ if (actionName === "list" && resourceName === "applications") {
255
+ const applications = ctx.body.rows;
256
+ for (const application of applications) {
257
+ const appStatus = server.AppSupervisor.getInstance().getAppStatus(application.name, "stopped");
258
+ application.status = appStatus;
259
+ }
260
+ }
261
+ });
257
262
  }
258
263
  }
259
264
 
@@ -0,0 +1,192 @@
1
+ declare const _default: {
2
+ info: {
3
+ title: string;
4
+ };
5
+ tags: any[];
6
+ paths: {
7
+ '/applications:list': {
8
+ get: {
9
+ tags: string[];
10
+ description: string;
11
+ responses: {
12
+ 200: {
13
+ description: string;
14
+ content: {
15
+ 'application/json': {
16
+ schema: {
17
+ $ref: string;
18
+ };
19
+ };
20
+ };
21
+ };
22
+ };
23
+ };
24
+ };
25
+ '/applications:create': {
26
+ post: {
27
+ tags: string[];
28
+ description: string;
29
+ requestBody: {
30
+ required: boolean;
31
+ content: {
32
+ 'application/json': {
33
+ schema: {
34
+ $ref: string;
35
+ };
36
+ };
37
+ };
38
+ };
39
+ responses: {
40
+ 200: {
41
+ description: string;
42
+ content: {
43
+ 'application/json': {
44
+ schema: {
45
+ $ref: string;
46
+ };
47
+ };
48
+ };
49
+ };
50
+ };
51
+ };
52
+ };
53
+ '/applications:update': {
54
+ post: {
55
+ tags: string[];
56
+ description: string;
57
+ parameters: {
58
+ name: string;
59
+ in: string;
60
+ description: string;
61
+ required: boolean;
62
+ schema: {
63
+ type: string;
64
+ };
65
+ }[];
66
+ requestBody: {
67
+ required: boolean;
68
+ content: {
69
+ 'application/json': {
70
+ schema: {
71
+ $ref: string;
72
+ };
73
+ };
74
+ };
75
+ };
76
+ responses: {
77
+ 200: {
78
+ description: string;
79
+ content: {
80
+ 'application/json': {
81
+ schema: {
82
+ $ref: string;
83
+ };
84
+ };
85
+ };
86
+ };
87
+ };
88
+ };
89
+ };
90
+ '/applications:destroy': {
91
+ post: {
92
+ tags: string[];
93
+ description: string;
94
+ parameters: {
95
+ name: string;
96
+ in: string;
97
+ description: string;
98
+ required: boolean;
99
+ schema: {
100
+ type: string;
101
+ };
102
+ }[];
103
+ responses: {
104
+ 200: {
105
+ description: string;
106
+ };
107
+ };
108
+ };
109
+ };
110
+ };
111
+ components: {
112
+ schemas: {
113
+ applicationFrom: {
114
+ allOf: ({
115
+ $ref: string;
116
+ type?: undefined;
117
+ properties?: undefined;
118
+ } | {
119
+ type: string;
120
+ properties: {
121
+ createdAt: {
122
+ readOnly: boolean;
123
+ };
124
+ updatedAt: {
125
+ readOnly: boolean;
126
+ };
127
+ status: {
128
+ readOnly: boolean;
129
+ };
130
+ };
131
+ $ref?: undefined;
132
+ })[];
133
+ };
134
+ application: {
135
+ type: string;
136
+ properties: {
137
+ name: {
138
+ type: string;
139
+ example: string;
140
+ description: string;
141
+ };
142
+ displayName: {
143
+ type: string;
144
+ example: string;
145
+ description: string;
146
+ };
147
+ pinned: {
148
+ type: string;
149
+ example: boolean;
150
+ description: string;
151
+ };
152
+ cname: {
153
+ type: string;
154
+ example: string;
155
+ description: string;
156
+ };
157
+ status: {
158
+ type: string;
159
+ example: string;
160
+ description: string;
161
+ };
162
+ options: {
163
+ type: string;
164
+ properties: {
165
+ standaloneDeployment: {
166
+ type: string;
167
+ example: boolean;
168
+ description: string;
169
+ };
170
+ autoStart: {
171
+ type: string;
172
+ example: boolean;
173
+ description: string;
174
+ };
175
+ };
176
+ };
177
+ createdAt: {
178
+ type: string;
179
+ format: string;
180
+ description: string;
181
+ };
182
+ updatedAt: {
183
+ type: string;
184
+ format: string;
185
+ description: string;
186
+ };
187
+ };
188
+ };
189
+ };
190
+ };
191
+ };
192
+ export default _default;