mango-cms 0.3.23 → 0.3.25

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/cli.js CHANGED
@@ -879,6 +879,48 @@ program
879
879
  }
880
880
  });
881
881
 
882
+ program
883
+ .command('launch')
884
+ .description('One-shot server deploy: git pull, install, build the site, and deploy backend + UI')
885
+ .action(async () => {
886
+ try {
887
+ const cwd = process.cwd();
888
+ const useYarn = fs.existsSync(path.join(cwd, 'yarn.lock'));
889
+ const pm = useYarn ? 'yarn' : 'npm';
890
+ const run = (label, cmd) => {
891
+ console.log(`\n→ ${label}\n $ ${cmd}`);
892
+ execSync(cmd, { stdio: 'inherit', cwd });
893
+ };
894
+
895
+ console.log('šŸš€ Launching Mango deployment...');
896
+
897
+ // 1. Pull the latest code for this project.
898
+ run('Pulling latest code', 'git pull');
899
+
900
+ // 2. Install dependencies (picks up any version bumps, incl. mango-cms).
901
+ run('Installing dependencies', useYarn ? 'yarn install' : 'npm install');
902
+
903
+ // 3. Build the public front-end site (-> dist), if a build script exists.
904
+ const pkgPath = path.join(cwd, 'package.json');
905
+ const hasBuildScript = fs.existsSync(pkgPath) && JSON.parse(fs.readFileSync(pkgPath, 'utf8'))?.scripts?.build;
906
+ if (hasBuildScript) {
907
+ run('Building site', useYarn ? 'yarn build' : 'npm run build');
908
+ } else {
909
+ console.log('\n→ Skipping site build (no "build" script found)');
910
+ }
911
+
912
+ // 4. Deploy backend + UI + web server config via the freshly installed mango.
913
+ // `mango deploy` builds the backend, (re)starts PM2 for {db}-mango, {db}
914
+ // and {db}-ui, and writes the nginx/apache blocks for all three domains.
915
+ run('Deploying backend + UI', 'npx mango deploy');
916
+
917
+ console.log('\n✨ Launch complete! Backend, site, and UI are deployed.');
918
+ } catch (error) {
919
+ console.error('\nLaunch failed:', error.message);
920
+ process.exit(1);
921
+ }
922
+ });
923
+
882
924
  program
883
925
  .command('build')
884
926
  .description('Build the Mango CMS for production')
package/lib/dev-proxy.js CHANGED
@@ -6,12 +6,21 @@
6
6
  * Runs on port 80, routes requests by hostname to the correct local dev server.
7
7
  * Supports WebSocket upgrade for Vite HMR and Socket.io.
8
8
  *
9
- * Usage: node lib/dev-proxy.js <frontDomain> <apiDomain> <frontPort> <backendPort> [pidPath] [uiDomain] [uiPort]
9
+ * Usage: node lib/dev-proxy.js <frontDomain> <apiDomain> <frontPort> <backendPort> [pidPath] [uiDomain] [uiPort] [stagingDomain]
10
+ *
11
+ * When [stagingDomain] is provided (or any request comes in with a "staging."
12
+ * Host header), the proxy enables the identity-aware Vibe staging route
13
+ * (HAP-1155): the per-request user identity is resolved by forwarding the
14
+ * Cookie / Authorization header to Mango, the vibeWorkspaces registry is
15
+ * consulted for that (userId, slug) pair, and the request — including the Vite
16
+ * HMR WebSocket upgrade — is proxied to that user's dev server port.
17
+ * See lib/devProxyGateway.js for the demux details.
10
18
  */
11
19
 
12
20
  import http from 'http';
13
21
  import httpProxy from 'http-proxy';
14
22
  import fs from 'fs';
23
+ import { parseStagingHost, resolveStagingTarget, createHttpResolver } from './devProxyGateway.js';
15
24
 
16
25
  const frontDomain = process.argv[2];
17
26
  const apiDomain = process.argv[3];
@@ -20,9 +29,10 @@ const backendPort = parseInt(process.argv[5], 10);
20
29
  const pidPath = process.argv[6];
21
30
  const uiDomain = process.argv[7];
22
31
  const uiPort = process.argv[8] ? parseInt(process.argv[8], 10) : null;
32
+ const stagingDomain = process.argv[9] || null;
23
33
 
24
34
  if (!frontDomain || !apiDomain || !frontendPort || !backendPort) {
25
- console.error('Usage: node lib/dev-proxy.js <frontDomain> <apiDomain> <frontPort> <backendPort> [pidPath] [uiDomain] [uiPort]');
35
+ console.error('Usage: node lib/dev-proxy.js <frontDomain> <apiDomain> <frontPort> <backendPort> [pidPath] [uiDomain] [uiPort] [stagingDomain]');
26
36
  process.exit(1);
27
37
  }
28
38
 
@@ -39,6 +49,10 @@ proxy.on('error', (err, req, res) => {
39
49
  }
40
50
  });
41
51
 
52
+ // Production resolver for the staging route: hits a small Mango endpoint that
53
+ // resolves (cookie/auth → memberId) and looks up vibeWorkspaces by (userId, slug).
54
+ const stagingResolver = createHttpResolver({ backendPort, http });
55
+
42
56
  function getTarget(host) {
43
57
  const hostname = host?.split(':')[0];
44
58
  if (hostname === apiDomain) {
@@ -53,18 +67,70 @@ function getTarget(host) {
53
67
  return null;
54
68
  }
55
69
 
70
+ // Identify the staging request (if any) BEFORE the simple host-route table —
71
+ // staging.<frontDomain> would otherwise fall through to 404.
72
+ function parseStaging(host) {
73
+ return parseStagingHost(host, { stagingDomain });
74
+ }
75
+
76
+ function sendError(res, status, message) {
77
+ if (!res || res.headersSent) return;
78
+ res.writeHead(status, { 'Content-Type': 'text/plain; charset=utf-8' });
79
+ res.end(message);
80
+ }
81
+
82
+ async function handleStagingRequest(req, res, parsed) {
83
+ const outcome = await resolveStagingTarget({ req, slug: parsed.slug, resolve: stagingResolver });
84
+ if (outcome.error) {
85
+ sendError(res, outcome.status || 502, outcome.message || outcome.error);
86
+ return;
87
+ }
88
+ proxy.web(req, res, { target: outcome.target });
89
+ }
90
+
91
+ async function handleStagingUpgrade(req, socket, head, parsed) {
92
+ const outcome = await resolveStagingTarget({ req, slug: parsed.slug, resolve: stagingResolver });
93
+ if (outcome.error) {
94
+ // Don't write an HTTP error onto an upgrade socket — just close it.
95
+ // The browser surfaces this as a WS connect failure (Vite will retry).
96
+ socket.destroy();
97
+ return;
98
+ }
99
+ proxy.ws(req, socket, head, { target: outcome.target });
100
+ }
101
+
56
102
  const server = http.createServer((req, res) => {
57
- const target = getTarget(req.headers.host);
103
+ const host = req.headers.host;
104
+ const staging = parseStaging(host);
105
+ if (staging) {
106
+ handleStagingRequest(req, res, staging).catch((err) => {
107
+ console.error(`Staging request error for ${host}${req.url}:`, err.message);
108
+ sendError(res, 502, `Staging error: ${err.message}`);
109
+ });
110
+ return;
111
+ }
112
+
113
+ const target = getTarget(host);
58
114
  if (!target) {
59
115
  res.writeHead(404);
60
- res.end(`Unknown host: ${req.headers.host}`);
116
+ res.end(`Unknown host: ${host}`);
61
117
  return;
62
118
  }
63
119
  proxy.web(req, res, { target });
64
120
  });
65
121
 
66
122
  server.on('upgrade', (req, socket, head) => {
67
- const target = getTarget(req.headers.host);
123
+ const host = req.headers.host;
124
+ const staging = parseStaging(host);
125
+ if (staging) {
126
+ handleStagingUpgrade(req, socket, head, staging).catch((err) => {
127
+ console.error(`Staging upgrade error for ${host}${req.url}:`, err.message);
128
+ socket.destroy();
129
+ });
130
+ return;
131
+ }
132
+
133
+ const target = getTarget(host);
68
134
  if (target) {
69
135
  proxy.ws(req, socket, head, { target });
70
136
  } else {
@@ -79,6 +145,11 @@ server.listen(80, '0.0.0.0', () => {
79
145
  if (uiDomain && uiPort) {
80
146
  console.log(` ${uiDomain} -> http://127.0.0.1:${uiPort} (ui)`);
81
147
  }
148
+ if (stagingDomain) {
149
+ console.log(` ${stagingDomain} -> per-user Vibe workspace (identity-aware)`);
150
+ } else {
151
+ console.log(` staging.* -> per-user Vibe workspace (identity-aware)`);
152
+ }
82
153
  });
83
154
 
84
155
  // Write PID for cleanup
@@ -0,0 +1,231 @@
1
+ /**
2
+ * Pure helpers for the dev-proxy's identity-aware staging route (HAP-1155).
3
+ *
4
+ * The dev-proxy already host-routes the site's own front / api / ui domains 1:1
5
+ * (see lib/dev-proxy.js). This module adds the multi-user staging route designed
6
+ * in HAP-1096 §5 / R1: ONE shared staging hostname per site that demuxes by the
7
+ * authenticated session identity into the right user's Vibe workspace port.
8
+ *
9
+ * Split into three pure, dependency-injected pieces so the proxy can stay
10
+ * standalone-runnable AND the demux logic stays unit-testable with plain node:
11
+ *
12
+ * parseStagingHost(host, opts) -> { hostname, slug } | null
13
+ * resolveStagingTarget({req,slug,resolve}) -> { port, target } | { error, status, message }
14
+ * createHttpResolver({ backendPort }) -> resolve({ slug, cookieHeader, authHeader })
15
+ *
16
+ * The proxy never owns session state. The HTTP resolver forwards the original
17
+ * Cookie / Authorization headers to Mango on the backend port — Mango identifies
18
+ * the member (`req.session.memberId` for the session cookie, member by
19
+ * password-hash for the Authorization header — same path getMember() uses
20
+ * everywhere else), looks up `vibeWorkspaces` by (userId, slug), and returns
21
+ * the workspace's port. The endpoint that does the lookup is owned by the
22
+ * provisioning service (HAP-1154); the contract is documented on
23
+ * createHttpResolver below.
24
+ */
25
+
26
+ export const DEFAULT_STAGING_PREFIX = 'staging.'
27
+
28
+ // Pure: does this request's Host header look like a staging request, and what
29
+ // site slug does it resolve to?
30
+ //
31
+ // Matches in this order:
32
+ // 1. exact match against opts.stagingDomain (when configured) — slug is the
33
+ // part of the hostname after the staging prefix, or the full hostname if
34
+ // it doesn't have one.
35
+ // 2. any hostname starting with opts.stagingHostPrefix (defaults to
36
+ // "staging.") — slug is the part after that prefix.
37
+ //
38
+ // Returns null when no match, or when the slug would be empty. Port suffixes
39
+ // (":80") and case are normalized away so the matcher is stable across
40
+ // browsers, curl, and the Vite HMR upgrade.
41
+ export function parseStagingHost(hostHeader, opts = {}) {
42
+ if (!hostHeader) return null
43
+ const prefix = String(opts.stagingHostPrefix || DEFAULT_STAGING_PREFIX).toLowerCase()
44
+ const hostname = String(hostHeader).split(':')[0].trim().toLowerCase()
45
+ if (!hostname) return null
46
+
47
+ const configured = opts.stagingDomain ? String(opts.stagingDomain).toLowerCase() : null
48
+ if (configured && hostname === configured) {
49
+ const slug = hostname.startsWith(prefix) ? hostname.slice(prefix.length) : hostname
50
+ if (!slug) return null
51
+ return { hostname, slug }
52
+ }
53
+
54
+ if (hostname.startsWith(prefix)) {
55
+ const slug = hostname.slice(prefix.length)
56
+ if (!slug) return null
57
+ return { hostname, slug }
58
+ }
59
+
60
+ return null
61
+ }
62
+
63
+ // Async: turn a parsed staging request into a concrete proxy target.
64
+ //
65
+ // Delegates the (identity + workspace) lookup to an injected `resolve` function
66
+ // — the proxy never owns session state. `resolve` receives the Cookie and
67
+ // Authorization headers from the original request so the same auth that the
68
+ // browser sent rides through (this is also why HMR lands on the right port:
69
+ // the WS upgrade ships the same cookie, so a second call to resolveStagingTarget
70
+ // from the upgrade handler picks the same port).
71
+ //
72
+ // The error contract is explicit so the proxy can return a clear response
73
+ // instead of misrouting — every failure path names its category:
74
+ // unauthenticated (401) — no Cookie and no Authorization header sent
75
+ // no_workspace (404) — resolver returned nothing for (user, slug)
76
+ // resolver_error (502) — resolver threw / returned a bad shape
77
+ // forbidden (403) — resolver explicitly refused (e.g. wrong site)
78
+ export async function resolveStagingTarget({ req, slug, resolve }) {
79
+ if (typeof resolve !== 'function') {
80
+ return { error: 'resolver_error', status: 502, message: 'No staging resolver configured' }
81
+ }
82
+ const cookieHeader = req?.headers?.cookie || ''
83
+ const authHeader = req?.headers?.authorization || ''
84
+ if (!cookieHeader && !authHeader) {
85
+ return {
86
+ error: 'unauthenticated',
87
+ status: 401,
88
+ message: 'Vibe staging requires an authenticated session (no Cookie / Authorization header)',
89
+ }
90
+ }
91
+
92
+ let result
93
+ try {
94
+ result = await resolve({ slug, cookieHeader, authHeader, req })
95
+ } catch (err) {
96
+ return { error: 'resolver_error', status: 502, message: `Vibe staging resolver error: ${err?.message || err}` }
97
+ }
98
+
99
+ if (!result) {
100
+ return { error: 'no_workspace', status: 404, message: `No Vibe workspace for slug "${slug}"` }
101
+ }
102
+ if (result.error) {
103
+ // resolver may pre-shape an error response (e.g. unauthenticated/forbidden)
104
+ return result
105
+ }
106
+ if (!Number.isInteger(result.port) || result.port <= 0 || result.port > 65535) {
107
+ return {
108
+ error: 'resolver_error',
109
+ status: 502,
110
+ message: `Vibe staging resolver returned invalid port ${JSON.stringify(result.port)}`,
111
+ }
112
+ }
113
+ return { port: result.port, target: `http://127.0.0.1:${result.port}` }
114
+ }
115
+
116
+ /**
117
+ * Production resolver: calls Mango (running on the backend port colocated with
118
+ * this proxy) at a small system endpoint that does identity + workspace lookup.
119
+ *
120
+ * GET <resolverPath>?slug=<slug>
121
+ * forwards: Cookie, Authorization
122
+ *
123
+ * 200 { port: <int> } workspace found, proxy to that port
124
+ * 401 no member could be identified
125
+ * 403 member identified, but not authorized for slug
126
+ * 404 no vibeWorkspaces record for (userId, slug)
127
+ * 5xx / network error surfaced as resolver_error
128
+ *
129
+ * The endpoint implementation lives with the provisioning service (HAP-1154)
130
+ * where the session helpers and vibeWorkspacesService are already wired up.
131
+ * Keeping it in Mango means the proxy never needs Redis / Mongo credentials.
132
+ *
133
+ * `http` is injected so the resolver is unit-testable without binding a real
134
+ * socket. Defaults to node's built-in http module via the dev-proxy entry.
135
+ */
136
+ export function createHttpResolver({
137
+ backendPort,
138
+ resolverPath = '/system/vibe/staging-resolve',
139
+ timeoutMs = 2000,
140
+ http,
141
+ } = {}) {
142
+ if (!Number.isInteger(backendPort)) {
143
+ throw new Error('createHttpResolver: backendPort (integer) is required')
144
+ }
145
+ if (!http || typeof http.request !== 'function') {
146
+ throw new Error('createHttpResolver: http module with request() is required')
147
+ }
148
+
149
+ return function resolve({ slug, cookieHeader, authHeader }) {
150
+ return new Promise((resolvePromise) => {
151
+ const path = `${resolverPath}?slug=${encodeURIComponent(slug)}`
152
+ const headers = {}
153
+ if (cookieHeader) headers.cookie = cookieHeader
154
+ if (authHeader) headers.authorization = authHeader
155
+
156
+ const request = http.request(
157
+ { host: '127.0.0.1', port: backendPort, method: 'GET', path, headers },
158
+ (res) => {
159
+ let body = ''
160
+ res.setEncoding('utf8')
161
+ res.on('data', (chunk) => {
162
+ body += chunk
163
+ })
164
+ res.on('end', () => {
165
+ const status = res.statusCode
166
+ if (status === 401) {
167
+ return resolvePromise({
168
+ error: 'unauthenticated',
169
+ status: 401,
170
+ message: 'Vibe staging: unauthenticated',
171
+ })
172
+ }
173
+ if (status === 403) {
174
+ return resolvePromise({
175
+ error: 'forbidden',
176
+ status: 403,
177
+ message: 'Vibe staging: forbidden for this slug',
178
+ })
179
+ }
180
+ if (status === 404) {
181
+ return resolvePromise({
182
+ error: 'no_workspace',
183
+ status: 404,
184
+ message: `Vibe staging: no workspace for "${slug}"`,
185
+ })
186
+ }
187
+ if (status < 200 || status >= 300) {
188
+ return resolvePromise({
189
+ error: 'resolver_error',
190
+ status: 502,
191
+ message: `Vibe staging resolver returned ${status}: ${body.slice(0, 200)}`,
192
+ })
193
+ }
194
+ let parsed
195
+ try {
196
+ parsed = JSON.parse(body)
197
+ } catch (err) {
198
+ return resolvePromise({
199
+ error: 'resolver_error',
200
+ status: 502,
201
+ message: `Vibe staging resolver returned non-JSON: ${err.message}`,
202
+ })
203
+ }
204
+ if (!Number.isInteger(parsed?.port)) {
205
+ return resolvePromise({
206
+ error: 'resolver_error',
207
+ status: 502,
208
+ message: 'Vibe staging resolver returned no integer port',
209
+ })
210
+ }
211
+ return resolvePromise({ port: parsed.port })
212
+ })
213
+ },
214
+ )
215
+
216
+ const onError = (err) => {
217
+ resolvePromise({
218
+ error: 'resolver_error',
219
+ status: 502,
220
+ message: `Vibe staging resolver request failed: ${err?.message || err}`,
221
+ })
222
+ }
223
+
224
+ request.setTimeout(timeoutMs, () => {
225
+ request.destroy(new Error(`timed out after ${timeoutMs}ms`))
226
+ })
227
+ request.on('error', onError)
228
+ request.end()
229
+ })
230
+ }
231
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mango-cms",
3
- "version": "0.3.23",
3
+ "version": "0.3.25",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "exports": {
@@ -1 +0,0 @@
1
- [{"name":"members","ssrModel":null,"titleName":"Members","singular":"member","titleSingular":"Member","humanName":" Members","humanSingular":" Member","fields":[{"name":"title","relationship":false,"instanceOf":null,"options":null,"humanName":"title","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":true,"customField":false,"global":true,"fields":null},{"name":"author","relationship":"members","instanceOf":"relationship","options":null,"humanName":"author","type":"Member","inputType":null,"computed":true,"complex":false,"translate":true,"required":false,"customField":false,"global":true,"fields":null},{"name":"editId","relationship":false,"instanceOf":null,"options":null,"humanName":"edit Id","type":"String","inputType":null,"computed":true,"complex":false,"translate":false,"required":false,"customField":false,"global":true,"fields":null},{"name":"created","relationship":false,"instanceOf":null,"options":null,"humanName":"created","type":"Float","inputType":null,"computed":true,"complex":false,"translate":false,"required":false,"customField":false,"global":true,"fields":null},{"name":"updated","relationship":false,"instanceOf":null,"options":null,"humanName":"updated","type":"Float","inputType":null,"computed":true,"complex":false,"translate":false,"required":false,"customField":false,"global":true,"fields":null},{"name":"slug","relationship":false,"instanceOf":null,"options":null,"humanName":"slug","type":"String","inputType":null,"computed":true,"complex":false,"translate":false,"required":false,"customField":false,"global":true,"fields":null},{"name":"startDate","relationship":false,"instanceOf":null,"options":null,"humanName":"start Date","type":"DateTime","inputType":"DateTime","computed":false,"complex":false,"translate":true,"required":false,"customField":false,"global":true,"fields":null},{"name":"endDate","relationship":false,"instanceOf":null,"options":null,"humanName":"end Date","type":"DateTime","inputType":"DateTime","computed":false,"complex":false,"translate":true,"required":false,"customField":false,"global":true,"fields":null},{"name":"email","relationship":false,"instanceOf":null,"options":null,"humanName":"email","type":"String","inputType":"String","computed":false,"complex":false,"translate":true,"required":false,"customField":false,"global":false,"fields":null},{"name":"password","relationship":false,"instanceOf":null,"options":null,"humanName":"password","type":"MembersPassword","inputType":"String","computed":false,"complex":true,"translate":true,"required":true,"customField":false,"global":false,"fields":[{"name":"salt","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"salt","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"hash","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"hash","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"apiKey","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"api Key","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null}]},{"name":"roles","relationship":false,"instanceOf":"select","options":["admin","member","contributor","editor"],"humanName":"roles","type":"[String]","inputType":"[String]","computed":false,"complex":false,"translate":true,"required":false,"customField":false,"global":false,"fields":null},{"name":"firstName","relationship":false,"instanceOf":null,"options":null,"humanName":"first Name","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"lastName","relationship":false,"instanceOf":null,"options":null,"humanName":"last Name","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null}]},{"name":"examples","ssrModel":null,"titleName":"Examples","singular":"example","titleSingular":"Example","humanName":" Examples","humanSingular":" Example","fields":[{"name":"title","relationship":false,"instanceOf":null,"options":null,"humanName":"title","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":true,"customField":false,"global":true,"fields":null},{"name":"author","relationship":"members","instanceOf":"relationship","options":null,"humanName":"author","type":"Member","inputType":null,"computed":true,"complex":false,"translate":true,"required":false,"customField":false,"global":true,"fields":null},{"name":"editId","relationship":false,"instanceOf":null,"options":null,"humanName":"edit Id","type":"String","inputType":null,"computed":true,"complex":false,"translate":false,"required":false,"customField":false,"global":true,"fields":null},{"name":"created","relationship":false,"instanceOf":null,"options":null,"humanName":"created","type":"Float","inputType":null,"computed":true,"complex":false,"translate":false,"required":false,"customField":false,"global":true,"fields":null},{"name":"updated","relationship":false,"instanceOf":null,"options":null,"humanName":"updated","type":"Float","inputType":null,"computed":true,"complex":false,"translate":false,"required":false,"customField":false,"global":true,"fields":null},{"name":"slug","relationship":false,"instanceOf":null,"options":null,"humanName":"slug","type":"String","inputType":null,"computed":true,"complex":false,"translate":false,"required":false,"customField":false,"global":true,"fields":null},{"name":"startDate","relationship":false,"instanceOf":null,"options":null,"humanName":"start Date","type":"DateTime","inputType":"DateTime","computed":false,"complex":false,"translate":true,"required":false,"customField":false,"global":true,"fields":null},{"name":"endDate","relationship":false,"instanceOf":null,"options":null,"humanName":"end Date","type":"DateTime","inputType":"DateTime","computed":false,"complex":false,"translate":true,"required":false,"customField":false,"global":true,"fields":null},{"name":"someData","relationship":false,"instanceOf":null,"options":null,"humanName":"some Data","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"anotherField","relationship":false,"instanceOf":null,"options":null,"humanName":"another Field","type":"Int","inputType":"Int","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"anArrayOfInts","array":true,"relationship":false,"instanceOf":null,"options":null,"humanName":"an Array Of Ints","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"image","relationship":false,"instanceOf":"image","options":null,"humanName":"image","type":"ExamplesImage","inputType":"String","computed":false,"complex":true,"translate":true,"required":false,"customField":false,"global":false,"fields":[{"name":"width","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"width","type":"Int","inputType":"Int","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"height","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"height","type":"Int","inputType":"Int","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"url","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"url","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null}]},{"name":"exampleRelationship","relationship":"examples","instanceOf":"relationship","options":null,"humanName":"example Relationship","type":"[Example]","inputType":"[String]","computed":false,"complex":false,"translate":true,"required":false,"customField":false,"global":false,"fields":null},{"name":"someLegitData","relationship":false,"instanceOf":null,"options":null,"humanName":"some Legit Data","type":"ExamplesSomeLegitData","inputType":"CreateExamplesSomeLegitDataInput","computed":false,"complex":true,"translate":false,"required":false,"customField":true,"global":false,"fields":[{"name":"coordinates","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"coordinates","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null}]},{"name":"productOfXY","relationship":false,"instanceOf":null,"options":null,"humanName":"product Of X Y","type":"String","inputType":null,"computed":true,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"vimeo","relationship":false,"instanceOf":null,"options":null,"humanName":"vimeo","type":"ExamplesVimeo","inputType":"Int","computed":false,"complex":true,"translate":true,"required":false,"customField":false,"global":false,"fields":[{"name":"id","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"id","type":"Int","inputType":"Int","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"url","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"url","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null}]}]},{"name":"items","ssrModel":null,"titleName":"Items","singular":"item","titleSingular":"Item","humanName":" Items","humanSingular":" Item","library":"Mango-stand","fields":[{"name":"title","relationship":false,"instanceOf":null,"options":null,"humanName":"title","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":true,"customField":false,"global":true,"fields":null},{"name":"author","relationship":"members","instanceOf":"relationship","options":null,"humanName":"author","type":"Member","inputType":null,"computed":true,"complex":false,"translate":true,"required":false,"customField":false,"global":true,"fields":null},{"name":"editId","relationship":false,"instanceOf":null,"options":null,"humanName":"edit Id","type":"String","inputType":null,"computed":true,"complex":false,"translate":false,"required":false,"customField":false,"global":true,"fields":null},{"name":"created","relationship":false,"instanceOf":null,"options":null,"humanName":"created","type":"Float","inputType":null,"computed":true,"complex":false,"translate":false,"required":false,"customField":false,"global":true,"fields":null},{"name":"updated","relationship":false,"instanceOf":null,"options":null,"humanName":"updated","type":"Float","inputType":null,"computed":true,"complex":false,"translate":false,"required":false,"customField":false,"global":true,"fields":null},{"name":"slug","relationship":false,"instanceOf":null,"options":null,"humanName":"slug","type":"String","inputType":null,"computed":true,"complex":false,"translate":false,"required":false,"customField":false,"global":true,"fields":null},{"name":"startDate","relationship":false,"instanceOf":null,"options":null,"humanName":"start Date","type":"DateTime","inputType":"DateTime","computed":false,"complex":false,"translate":true,"required":false,"customField":false,"global":true,"fields":null},{"name":"endDate","relationship":false,"instanceOf":null,"options":null,"humanName":"end Date","type":"DateTime","inputType":"DateTime","computed":false,"complex":false,"translate":true,"required":false,"customField":false,"global":true,"fields":null},{"name":"price","relationship":false,"instanceOf":null,"options":null,"humanName":"price","type":"Int","inputType":"Int","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"stock","relationship":false,"instanceOf":null,"options":null,"humanName":"stock","type":"Int","inputType":"Int","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"description","relationship":false,"instanceOf":null,"options":null,"humanName":"description","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null}]},{"name":"carts","ssrModel":null,"titleName":"Carts","singular":"cart","titleSingular":"Cart","humanName":" Carts","humanSingular":" Cart","library":"Mango-stand","fields":[{"name":"title","relationship":false,"instanceOf":null,"options":null,"humanName":"title","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"author","relationship":"members","instanceOf":"relationship","options":null,"humanName":"author","type":"Member","inputType":null,"computed":true,"complex":false,"translate":true,"required":false,"customField":false,"global":true,"fields":null},{"name":"editId","relationship":false,"instanceOf":null,"options":null,"humanName":"edit Id","type":"String","inputType":null,"computed":true,"complex":false,"translate":false,"required":false,"customField":false,"global":true,"fields":null},{"name":"created","relationship":false,"instanceOf":null,"options":null,"humanName":"created","type":"Float","inputType":null,"computed":true,"complex":false,"translate":false,"required":false,"customField":false,"global":true,"fields":null},{"name":"updated","relationship":false,"instanceOf":null,"options":null,"humanName":"updated","type":"Float","inputType":null,"computed":true,"complex":false,"translate":false,"required":false,"customField":false,"global":true,"fields":null},{"name":"slug","relationship":false,"instanceOf":null,"options":null,"humanName":"slug","type":"String","inputType":null,"computed":true,"complex":false,"translate":false,"required":false,"customField":false,"global":true,"fields":null},{"name":"startDate","relationship":false,"instanceOf":null,"options":null,"humanName":"start Date","type":"DateTime","inputType":"DateTime","computed":false,"complex":false,"translate":true,"required":false,"customField":false,"global":true,"fields":null},{"name":"endDate","relationship":false,"instanceOf":null,"options":null,"humanName":"end Date","type":"DateTime","inputType":"DateTime","computed":false,"complex":false,"translate":true,"required":false,"customField":false,"global":true,"fields":null},{"name":"transactionId","relationship":false,"instanceOf":null,"options":null,"humanName":"transaction Id","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"finalized","relationship":false,"instanceOf":null,"options":null,"humanName":"finalized","type":"Boolean","inputType":"Boolean","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"completed","relationship":false,"instanceOf":null,"options":null,"humanName":"completed","type":"Boolean","inputType":"Boolean","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"completedDate","relationship":false,"instanceOf":null,"options":null,"humanName":"completed Date","type":"DateTime","inputType":"DateTime","computed":false,"complex":false,"translate":true,"required":false,"customField":false,"global":false,"fields":null},{"name":"cartItems","array":true,"relationship":false,"instanceOf":null,"options":null,"humanName":"cart Items","type":"CartsCartItems","inputType":"CreateCartsCartItemsInput","computed":false,"complex":true,"translate":false,"required":false,"customField":true,"global":false,"fields":[{"name":"quantity","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"quantity","type":"Int","inputType":"Int","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"discount","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"discount","type":"Float","inputType":"Float","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"item","array":false,"relationship":"items","instanceOf":"relationship","options":null,"humanName":"item","type":"Item","inputType":"String","computed":false,"complex":false,"translate":true,"required":false,"customField":false,"global":false,"fields":null}]},{"name":"coupons","relationship":"discounts","instanceOf":"relationship","options":null,"humanName":"coupons","type":"[Discount]","inputType":"[String]","computed":false,"complex":false,"translate":true,"required":false,"customField":false,"global":false,"fields":null},{"name":"customerId","relationship":false,"instanceOf":null,"options":null,"humanName":"customer Id","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"billing","relationship":false,"instanceOf":null,"options":null,"humanName":"billing","type":"CartsBilling","inputType":"CreateCartsBillingInput","computed":false,"complex":true,"translate":false,"required":false,"customField":true,"global":false,"fields":[{"name":"paymentId","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"payment Id","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"firstName","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"first Name","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"lastName","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"last Name","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"phoneNumber","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"phone Number","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"address","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"address","type":"CartsBillingAddress","inputType":"CreateCartsBillingAddressInput","computed":false,"complex":true,"translate":false,"required":false,"customField":true,"global":false,"fields":[{"name":"venue","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"venue","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"address","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"address","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"city","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"city","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"state","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"state","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"zip","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"zip","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"country","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"country","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"human","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"human","type":"String","inputType":null,"computed":true,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"coordinates","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"coordinates","type":"CartsBillingAddressCoordinates","inputType":null,"computed":true,"complex":true,"translate":false,"required":false,"customField":true,"global":false,"fields":[{"name":"lat","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"lat","type":"Float","inputType":"Float","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"lng","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"lng","type":"Float","inputType":"Float","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null}]}]},{"name":"payment","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"payment","type":"CartsBillingPayment","inputType":"CreateCartsBillingPaymentInput","computed":false,"complex":true,"translate":false,"required":false,"customField":true,"global":false,"fields":[{"name":"creditCard","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"credit Card","type":"CartsBillingPaymentCreditCard","inputType":"CreateCartsBillingPaymentCreditCardInput","computed":false,"complex":true,"translate":false,"required":false,"customField":true,"global":false,"fields":[{"name":"cardNumber","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"card Number","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"cardType","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"card Type","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"expirationDate","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"expiration Date","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null}]},{"name":"bankAccount","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"bank Account","type":"CartsBillingPaymentBankAccount","inputType":"CreateCartsBillingPaymentBankAccountInput","computed":false,"complex":true,"translate":false,"required":false,"customField":true,"global":false,"fields":[{"name":"accountNumber","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"account Number","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"accountType","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"account Type","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"echeckType","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"echeck Type","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"nameOnAccount","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"name On Account","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"routingNumber","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"routing Number","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null}]}]}]},{"name":"shipping","relationship":false,"instanceOf":null,"options":null,"humanName":"shipping","type":"CartsShipping","inputType":"CreateCartsShippingInput","computed":false,"complex":true,"translate":false,"required":false,"customField":true,"global":false,"fields":[{"name":"method","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"method","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"price","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"price","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"addressId","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"address Id","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"firstName","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"first Name","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"lastName","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"last Name","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"phoneNumber","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"phone Number","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"address","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"address","type":"CartsShippingAddress","inputType":"CreateCartsShippingAddressInput","computed":false,"complex":true,"translate":false,"required":false,"customField":true,"global":false,"fields":[{"name":"venue","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"venue","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"address","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"address","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"city","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"city","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"state","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"state","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"zip","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"zip","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"country","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"country","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"human","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"human","type":"String","inputType":null,"computed":true,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"coordinates","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"coordinates","type":"CartsShippingAddressCoordinates","inputType":null,"computed":true,"complex":true,"translate":false,"required":false,"customField":true,"global":false,"fields":[{"name":"lat","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"lat","type":"Float","inputType":"Float","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"lng","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"lng","type":"Float","inputType":"Float","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null}]}]},{"name":"free","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"free","type":"Boolean","inputType":null,"computed":true,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null}]},{"name":"price","relationship":false,"instanceOf":null,"options":null,"humanName":"price","type":"CartsPrice","inputType":null,"computed":true,"complex":true,"translate":false,"required":false,"customField":true,"global":false,"fields":[{"name":"subtotal","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"subtotal","type":"Float","inputType":"Float","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"discount","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"discount","type":"Float","inputType":"Float","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"total","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"total","type":"Float","inputType":"Float","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null}]}]},{"name":"discounts","ssrModel":null,"titleName":"Discounts","singular":"discount","titleSingular":"Discount","humanName":" Discounts","humanSingular":" Discount","library":"Mango-stand","fields":[{"name":"title","relationship":false,"instanceOf":null,"options":null,"humanName":"title","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":true,"customField":false,"global":true,"fields":null},{"name":"author","relationship":"members","instanceOf":"relationship","options":null,"humanName":"author","type":"Member","inputType":null,"computed":true,"complex":false,"translate":true,"required":false,"customField":false,"global":true,"fields":null},{"name":"editId","relationship":false,"instanceOf":null,"options":null,"humanName":"edit Id","type":"String","inputType":null,"computed":true,"complex":false,"translate":false,"required":false,"customField":false,"global":true,"fields":null},{"name":"created","relationship":false,"instanceOf":null,"options":null,"humanName":"created","type":"Float","inputType":null,"computed":true,"complex":false,"translate":false,"required":false,"customField":false,"global":true,"fields":null},{"name":"updated","relationship":false,"instanceOf":null,"options":null,"humanName":"updated","type":"Float","inputType":null,"computed":true,"complex":false,"translate":false,"required":false,"customField":false,"global":true,"fields":null},{"name":"slug","relationship":false,"instanceOf":null,"options":null,"humanName":"slug","type":"String","inputType":null,"computed":true,"complex":false,"translate":false,"required":false,"customField":false,"global":true,"fields":null},{"name":"startDate","relationship":false,"instanceOf":null,"options":null,"humanName":"start Date","type":"DateTime","inputType":"DateTime","computed":false,"complex":false,"translate":true,"required":false,"customField":false,"global":true,"fields":null},{"name":"endDate","relationship":false,"instanceOf":null,"options":null,"humanName":"end Date","type":"DateTime","inputType":"DateTime","computed":false,"complex":false,"translate":true,"required":false,"customField":false,"global":true,"fields":null},{"name":"type","relationship":false,"instanceOf":"select","options":["coupon","sale"],"humanName":"type","type":"String","inputType":"String","computed":false,"complex":false,"translate":true,"required":true,"customField":false,"global":false,"fields":null},{"name":"code","relationship":false,"instanceOf":null,"options":null,"humanName":"code","type":"String","inputType":"String","computed":false,"complex":false,"translate":true,"required":true,"customField":false,"global":false,"fields":null},{"name":"limitations","relationship":false,"instanceOf":null,"options":null,"humanName":"limitations","type":"DiscountsLimitations","inputType":"CreateDiscountsLimitationsInput","computed":false,"complex":true,"translate":false,"required":false,"customField":true,"global":false,"fields":[{"name":"items","array":false,"relationship":"items","instanceOf":"relationship","options":null,"humanName":"items","type":"[Item]","inputType":"[String]","computed":false,"complex":false,"translate":true,"required":false,"customField":false,"global":false,"fields":null},{"name":"perCustomer","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"per Customer","type":"Int","inputType":"Int","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"totalUses","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"total Uses","type":"Int","inputType":"Int","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"perOrder","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"per Order","type":"Int","inputType":"Int","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"quantity","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"quantity","type":"Int","inputType":"Int","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null}]},{"name":"freeShipping","relationship":false,"instanceOf":null,"options":null,"humanName":"free Shipping","type":"Boolean","inputType":"Boolean","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"discount","relationship":false,"instanceOf":null,"options":null,"humanName":"discount","type":"DiscountsDiscount","inputType":"String","computed":false,"complex":true,"translate":true,"required":false,"customField":false,"example":"$12.50 or 50% etc.","global":false,"fields":[{"name":"type","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"type","type":"String","inputType":"String","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null},{"name":"value","array":false,"relationship":false,"instanceOf":null,"options":null,"humanName":"value","type":"Float","inputType":"Float","computed":false,"complex":false,"translate":false,"required":false,"customField":false,"global":false,"fields":null}]}]}]
@@ -1,14 +0,0 @@
1
- {
2
- "account/login": [
3
- "post"
4
- ],
5
- "account/resetPassword": [
6
- "post"
7
- ],
8
- "account/sendResetInstructions": [
9
- "post"
10
- ],
11
- "test": [
12
- "get"
13
- ]
14
- }