wrangler 0.0.0-beta.6 → 0.0.0-bfbb0be

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.
Files changed (179) hide show
  1. package/Cloudflare_CA.pem +18 -0
  2. package/README.md +27 -14
  3. package/bin/wrangler.js +106 -5
  4. package/kv-asset-handler.js +1 -0
  5. package/miniflare-dist/index.mjs +4886 -0
  6. package/package.json +77 -35
  7. package/src/__tests__/config-cache.test.ts +36 -0
  8. package/src/__tests__/configuration.test.ts +3548 -0
  9. package/src/__tests__/dev.test.tsx +1055 -0
  10. package/src/__tests__/guess-worker-format.test.ts +85 -0
  11. package/src/__tests__/{clipboardy-mock.js → helpers/clipboardy-mock.js} +0 -0
  12. package/src/__tests__/helpers/cmd-shim.d.ts +11 -0
  13. package/src/__tests__/helpers/faye-websocket.d.ts +6 -0
  14. package/src/__tests__/helpers/mock-account-id.ts +48 -0
  15. package/src/__tests__/helpers/mock-bin.ts +36 -0
  16. package/src/__tests__/helpers/mock-cfetch.ts +211 -0
  17. package/src/__tests__/helpers/mock-console.ts +97 -0
  18. package/src/__tests__/helpers/mock-dialogs.ts +153 -0
  19. package/src/__tests__/helpers/mock-http-server.ts +46 -0
  20. package/src/__tests__/helpers/mock-istty.ts +32 -0
  21. package/src/__tests__/helpers/mock-kv.ts +33 -0
  22. package/src/__tests__/helpers/mock-oauth-flow.ts +250 -0
  23. package/src/__tests__/helpers/mock-process.ts +39 -0
  24. package/src/__tests__/helpers/mock-stdin.ts +108 -0
  25. package/src/__tests__/helpers/mock-web-socket.ts +29 -0
  26. package/src/__tests__/helpers/run-in-tmp.ts +39 -0
  27. package/src/__tests__/helpers/run-wrangler.ts +16 -0
  28. package/src/__tests__/helpers/write-worker-source.ts +31 -0
  29. package/src/__tests__/helpers/write-wrangler-toml.ts +17 -0
  30. package/src/__tests__/https-options.test.ts +130 -0
  31. package/src/__tests__/index.test.ts +235 -130
  32. package/src/__tests__/init.test.ts +1992 -0
  33. package/src/__tests__/jest.setup.ts +107 -0
  34. package/src/__tests__/kv.test.ts +1619 -0
  35. package/src/__tests__/logger.test.ts +141 -0
  36. package/src/__tests__/package-manager.test.ts +353 -0
  37. package/src/__tests__/pages.test.ts +1242 -0
  38. package/src/__tests__/parse.test.ts +330 -0
  39. package/src/__tests__/publish.test.ts +6188 -0
  40. package/src/__tests__/r2.test.ts +233 -0
  41. package/src/__tests__/route.test.ts +45 -0
  42. package/src/__tests__/secret.test.ts +486 -0
  43. package/src/__tests__/tail.test.ts +690 -0
  44. package/src/__tests__/user.test.ts +132 -0
  45. package/src/__tests__/whoami.test.tsx +139 -0
  46. package/src/abort.d.ts +3 -0
  47. package/src/bundle-reporter.tsx +29 -0
  48. package/src/bundle.ts +204 -0
  49. package/src/cfetch/index.ts +121 -0
  50. package/src/cfetch/internal.ts +142 -0
  51. package/src/cli.ts +10 -7
  52. package/src/config/README.md +107 -0
  53. package/src/config/config.ts +243 -0
  54. package/src/config/diagnostics.ts +80 -0
  55. package/src/config/environment.ts +420 -0
  56. package/src/config/index.ts +225 -0
  57. package/src/config/validation-helpers.ts +584 -0
  58. package/src/config/validation.ts +1580 -0
  59. package/src/config-cache.ts +44 -0
  60. package/src/create-worker-preview.ts +185 -0
  61. package/src/create-worker-upload-form.ts +254 -0
  62. package/src/dev/dev-vars.ts +36 -0
  63. package/src/dev/dev.tsx +399 -0
  64. package/src/dev/local.tsx +321 -0
  65. package/src/dev/remote.tsx +282 -0
  66. package/src/dev/use-esbuild.ts +112 -0
  67. package/src/dialogs.tsx +68 -18
  68. package/src/durable.ts +102 -0
  69. package/src/entry.ts +328 -0
  70. package/src/environment-variables.ts +35 -0
  71. package/src/errors.ts +11 -0
  72. package/src/git-client.ts +42 -0
  73. package/src/https-options.ts +123 -0
  74. package/src/index.tsx +2100 -1002
  75. package/src/inspect.ts +662 -0
  76. package/src/intl-polyfill.d.ts +139 -0
  77. package/src/kv.ts +408 -0
  78. package/src/logger.ts +73 -0
  79. package/src/miniflare-cli/README.md +30 -0
  80. package/src/miniflare-cli/enum-keys.ts +17 -0
  81. package/src/miniflare-cli/index.ts +41 -0
  82. package/src/miniflare-cli/request-context.ts +40 -0
  83. package/src/module-collection.ts +258 -0
  84. package/src/open-in-browser.ts +17 -0
  85. package/src/package-manager.ts +174 -0
  86. package/src/pages/build.tsx +202 -0
  87. package/src/pages/constants.ts +7 -0
  88. package/src/pages/deployments.tsx +101 -0
  89. package/src/pages/dev.tsx +948 -0
  90. package/src/pages/functions/buildPlugin.ts +105 -0
  91. package/src/pages/functions/buildWorker.ts +151 -0
  92. package/src/pages/functions/filepath-routing.test.ts +234 -0
  93. package/src/pages/functions/filepath-routing.ts +189 -0
  94. package/src/pages/functions/identifiers.ts +78 -0
  95. package/src/pages/functions/routes.ts +151 -0
  96. package/src/pages/index.tsx +84 -0
  97. package/src/pages/projects.tsx +157 -0
  98. package/src/pages/publish.tsx +325 -0
  99. package/src/pages/types.ts +40 -0
  100. package/src/pages/upload.tsx +363 -0
  101. package/src/pages/utils.ts +12 -0
  102. package/src/parse.ts +222 -0
  103. package/src/paths.ts +26 -0
  104. package/src/proxy.ts +476 -0
  105. package/src/publish.ts +666 -215
  106. package/src/r2.ts +50 -0
  107. package/src/selfsigned.d.ts +29 -0
  108. package/src/sites.tsx +316 -59
  109. package/src/tail/filters.ts +279 -0
  110. package/src/tail/index.ts +299 -0
  111. package/src/tail/printing.ts +67 -0
  112. package/src/update-check.ts +19 -0
  113. package/src/user/choose-account.tsx +60 -0
  114. package/src/user/env-vars.ts +17 -0
  115. package/src/user/generate-auth-url.ts +33 -0
  116. package/src/user/generate-random-state.ts +16 -0
  117. package/src/user/index.ts +3 -0
  118. package/src/{user.tsx → user/user.tsx} +380 -276
  119. package/src/whoami.tsx +71 -0
  120. package/src/worker.ts +181 -0
  121. package/src/zones.ts +73 -0
  122. package/templates/gitignore +171 -0
  123. package/templates/new-worker-scheduled.js +17 -0
  124. package/templates/new-worker-scheduled.ts +32 -0
  125. package/templates/new-worker.js +15 -0
  126. package/templates/new-worker.ts +30 -0
  127. package/templates/no-op-worker.js +10 -0
  128. package/templates/pages-template-plugin.ts +155 -0
  129. package/templates/pages-template-worker.ts +161 -0
  130. package/{static-asset-facade.js → templates/static-asset-facade.js} +3 -7
  131. package/templates/tsconfig.json +105 -0
  132. package/wrangler-dist/cli.js +108270 -117183
  133. package/src/__tests__/fixtures/init/.gitkeep +0 -0
  134. package/src/__tests__/mock-cfetch.js +0 -46
  135. package/src/api/form_data.ts +0 -125
  136. package/src/api/inspect.ts +0 -441
  137. package/src/api/preview.ts +0 -123
  138. package/src/api/worker.ts +0 -140
  139. package/src/cfetch.ts +0 -72
  140. package/src/config.ts +0 -100
  141. package/src/dev.tsx +0 -687
  142. package/src/kv.tsx +0 -211
  143. package/src/pages.tsx +0 -340
  144. package/src/tail.tsx +0 -71
  145. package/src/util/fetch.ts +0 -74
  146. package/vendor/@cloudflare/kv-asset-handler/CHANGELOG.md +0 -332
  147. package/vendor/@cloudflare/kv-asset-handler/LICENSE_APACHE +0 -176
  148. package/vendor/@cloudflare/kv-asset-handler/LICENSE_MIT +0 -25
  149. package/vendor/@cloudflare/kv-asset-handler/README.md +0 -245
  150. package/vendor/@cloudflare/kv-asset-handler/dist/index.d.ts +0 -32
  151. package/vendor/@cloudflare/kv-asset-handler/dist/index.js +0 -354
  152. package/vendor/@cloudflare/kv-asset-handler/dist/mocks.d.ts +0 -13
  153. package/vendor/@cloudflare/kv-asset-handler/dist/mocks.js +0 -148
  154. package/vendor/@cloudflare/kv-asset-handler/dist/test/getAssetFromKV.d.ts +0 -1
  155. package/vendor/@cloudflare/kv-asset-handler/dist/test/getAssetFromKV.js +0 -436
  156. package/vendor/@cloudflare/kv-asset-handler/dist/test/mapRequestToAsset.d.ts +0 -1
  157. package/vendor/@cloudflare/kv-asset-handler/dist/test/mapRequestToAsset.js +0 -40
  158. package/vendor/@cloudflare/kv-asset-handler/dist/test/serveSinglePageApp.d.ts +0 -1
  159. package/vendor/@cloudflare/kv-asset-handler/dist/test/serveSinglePageApp.js +0 -42
  160. package/vendor/@cloudflare/kv-asset-handler/dist/types.d.ts +0 -26
  161. package/vendor/@cloudflare/kv-asset-handler/dist/types.js +0 -31
  162. package/vendor/@cloudflare/kv-asset-handler/package.json +0 -52
  163. package/vendor/@cloudflare/kv-asset-handler/src/index.ts +0 -296
  164. package/vendor/@cloudflare/kv-asset-handler/src/mocks.ts +0 -136
  165. package/vendor/@cloudflare/kv-asset-handler/src/test/getAssetFromKV.ts +0 -464
  166. package/vendor/@cloudflare/kv-asset-handler/src/test/mapRequestToAsset.ts +0 -33
  167. package/vendor/@cloudflare/kv-asset-handler/src/test/serveSinglePageApp.ts +0 -42
  168. package/vendor/@cloudflare/kv-asset-handler/src/types.ts +0 -39
  169. package/vendor/wrangler-mime/CHANGELOG.md +0 -289
  170. package/vendor/wrangler-mime/LICENSE +0 -21
  171. package/vendor/wrangler-mime/Mime.js +0 -97
  172. package/vendor/wrangler-mime/README.md +0 -187
  173. package/vendor/wrangler-mime/cli.js +0 -46
  174. package/vendor/wrangler-mime/index.js +0 -4
  175. package/vendor/wrangler-mime/lite.js +0 -4
  176. package/vendor/wrangler-mime/package.json +0 -52
  177. package/vendor/wrangler-mime/types/other.js +0 -1
  178. package/vendor/wrangler-mime/types/standard.js +0 -1
  179. package/wrangler-dist/cli.js.map +0 -7
@@ -1,123 +0,0 @@
1
- import cfetch from "../cfetch";
2
- import { fetchJson } from "../util/fetch";
3
- import { toFormData } from "./form_data";
4
- import type { CfAccount, CfWorkerInit } from "./worker";
5
-
6
- /**
7
- * A preview mode.
8
- *
9
- * * If true, then using a `workers.dev` subdomain.
10
- * * Otherwise, a list of routes under a single zone.
11
- */
12
- export type CfPreviewMode = { workers_dev: boolean } | { routes: string[] };
13
-
14
- /**
15
- * A preview token.
16
- */
17
- export interface CfPreviewToken {
18
- /**
19
- * The header value required to trigger a preview.
20
- *
21
- * @example
22
- * const headers = { 'cf-workers-preview-token': value }
23
- * const response = await fetch('https://' + host, { headers })
24
- */
25
- value: string;
26
- /**
27
- * The host where the preview is available.
28
- */
29
- host: string;
30
- /**
31
- * A websocket url to a DevTools inspector.
32
- *
33
- * Workers does not have a fully-featured implementation
34
- * of the Chrome DevTools protocol, but supports the following:
35
- * * `console.log()` output.
36
- * * `Error` stack traces.
37
- * * `fetch()` events.
38
- *
39
- * There is no support for breakpoints, but we want to implement
40
- * this eventually.
41
- *
42
- * @link https://chromedevtools.github.io/devtools-protocol/
43
- */
44
- inspectorUrl: URL;
45
- /**
46
- * A url to prewarm the preview session.
47
- *
48
- * @example
49
- * fetch(prewarmUrl, { method: 'POST' })
50
- */
51
- prewarmUrl: URL;
52
- }
53
-
54
- /**
55
- * Generates a preview session token.
56
- */
57
- async function sessionToken(account: CfAccount): Promise<CfPreviewToken> {
58
- const { accountId, zoneId } = account;
59
- const initUrl = zoneId
60
- ? `/zones/${zoneId}/workers/edge-preview`
61
- : `/accounts/${accountId}/workers/subdomain/edge-preview`;
62
-
63
- const { exchange_url: tokenUrl } = await cfetch<{ exchange_url: string }>(
64
- initUrl
65
- );
66
- const { inspector_websocket: url, token } = await fetchJson()(tokenUrl);
67
- const { host } = new URL(url);
68
- const query = `cf_workers_preview_token=${token}`;
69
-
70
- return {
71
- value: token,
72
- host,
73
- inspectorUrl: new URL(`${url}?${query}`),
74
- prewarmUrl: new URL(
75
- `https://${host}/cdn-cgi/workers/preview/prewarm?${query}`
76
- ),
77
- };
78
- }
79
-
80
- // Credit: https://stackoverflow.com/a/2117523
81
- function randomId(): string {
82
- return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
83
- const r = (Math.random() * 16) | 0,
84
- v = c == "x" ? r : (r & 0x3) | 0x8;
85
- return v.toString(16);
86
- });
87
- }
88
-
89
- /**
90
- * Creates a preview token.
91
- */
92
- export async function previewToken(
93
- account: CfAccount,
94
- worker: CfWorkerInit
95
- ): Promise<CfPreviewToken> {
96
- const { value, host, inspectorUrl, prewarmUrl } = await sessionToken(account);
97
-
98
- const { accountId, zoneId } = account;
99
- const scriptId = zoneId ? randomId() : host.split(".")[0];
100
- const url = `/accounts/${accountId}/workers/scripts/${scriptId}/edge-preview`;
101
-
102
- const mode = zoneId ? { routes: ["*/*"] } : { workers_dev: true };
103
- const formData = toFormData(worker);
104
- formData.set("wrangler-session-config", JSON.stringify(mode));
105
-
106
- const { preview_token: token } = await cfetch<{ preview_token: string }>(
107
- url,
108
- {
109
- method: "POST",
110
- // @ts-expect-error TODO: fix this
111
- body: formData,
112
- headers: {
113
- "cf-preview-upload-config-token": value,
114
- },
115
- }
116
- );
117
- return {
118
- value: token,
119
- host,
120
- inspectorUrl,
121
- prewarmUrl,
122
- };
123
- }
package/src/api/worker.ts DELETED
@@ -1,140 +0,0 @@
1
- import type { CfPreviewToken } from "./preview";
2
- import { previewToken } from "./preview";
3
- import fetch from "node-fetch";
4
-
5
- /**
6
- * A Cloudflare account.
7
- */
8
- export interface CfAccount {
9
- /**
10
- * An API token.
11
- *
12
- * @link https://api.cloudflare.com/#user-api-tokens-properties
13
- */
14
- apiToken: string;
15
- /**
16
- * An account ID.
17
- */
18
- accountId: string;
19
- /**
20
- * A zone ID, only required if not using `workers.dev`.
21
- */
22
- zoneId?: string;
23
- }
24
-
25
- /**
26
- * A module type.
27
- */
28
- export type CfModuleType =
29
- | "esm"
30
- | "commonjs"
31
- | "compiled-wasm"
32
- | "text"
33
- | "buffer";
34
-
35
- /**
36
- * An imported module.
37
- */
38
- export interface CfModule {
39
- /**
40
- * The module name.
41
- *
42
- * @example
43
- * './src/index.js'
44
- */
45
- name: string;
46
- /**
47
- * The module content, usually JavaScript or WASM code.
48
- *
49
- * @example
50
- * export default {
51
- * async fetch(request) {
52
- * return new Response('Ok')
53
- * }
54
- * }
55
- */
56
- content: string | BufferSource;
57
- /**
58
- * The module type.
59
- *
60
- * If absent, will default to the main module's type.
61
- */
62
- type?: CfModuleType;
63
- }
64
-
65
- /**
66
- * A KV namespace.
67
- */
68
- export interface CfKvNamespace {
69
- /**
70
- * The namespace ID.
71
- */
72
- namespaceId: string;
73
- }
74
-
75
- /**
76
- * A `WebCrypto` key.
77
- *
78
- * @link https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey
79
- */
80
- export interface CfCryptoKey {
81
- /**
82
- * The format.
83
- */
84
- format: string;
85
- /**
86
- * The algorithm.
87
- */
88
- algorithm: string;
89
- /**
90
- * The usages.
91
- */
92
- usages: string[];
93
- /**
94
- * The data.
95
- */
96
- data: BufferSource | JsonWebKey;
97
- }
98
-
99
- /**
100
- * A variable (aka. environment variable).
101
- */
102
- export type CfVariable = string | CfKvNamespace | CfCryptoKey;
103
-
104
- /**
105
- * Options for creating a `CfWorker`.
106
- */
107
- export interface CfWorkerInit {
108
- /**
109
- * The entrypoint module.
110
- */
111
- main: CfModule;
112
- /**
113
- * The list of additional modules.
114
- */
115
- modules: void | CfModule[];
116
- /**
117
- * The map of names to variables. (aka. environment variables)
118
- */
119
- variables?: { [name: string]: CfVariable };
120
- compatibility_date?: string;
121
- usage_model?: void | "bundled" | "unbound";
122
- }
123
-
124
- /**
125
- * A stub to create a Cloudflare Worker preview.
126
- *
127
- * @example
128
- * const {value, host} = await createWorker(init, acct);
129
- */
130
- export async function createWorker(
131
- init: CfWorkerInit,
132
- account: CfAccount
133
- ): Promise<CfPreviewToken> {
134
- const token = await previewToken(account, init);
135
- const response = await fetch(token.prewarmUrl.href, { method: "POST" });
136
- if (!response.ok) {
137
- // console.error("worker failed to prewarm: ", response.statusText);
138
- }
139
- return token;
140
- }
package/src/cfetch.ts DELETED
@@ -1,72 +0,0 @@
1
- import fetch from "node-fetch";
2
- import type { RequestInit } from "node-fetch";
3
- import { getAPIToken } from "./user";
4
- import { loginOrRefreshIfRequired } from "./user";
5
-
6
- export const CF_API_BASE_URL =
7
- process.env.CF_API_BASE_URL || "https://api.cloudflare.com/client/v4";
8
-
9
- export default async function fetchWithAuthAndLoginIfRequired<ResponseType>(
10
- resource: string,
11
- init: RequestInit = {}
12
- ): Promise<ResponseType> {
13
- const loggedIn = await loginOrRefreshIfRequired();
14
- if (!loggedIn) {
15
- throw new Error("Not logged in");
16
- }
17
- const apiToken = getAPIToken();
18
- if (!apiToken) {
19
- throw new Error("No API token found");
20
- }
21
- // @ts-expect-error Authorization isn't non HeadersInit, annoyingly
22
- if (init.headers?.Authorization) {
23
- throw new Error(
24
- "fetchWithAuthAndLoginIfRequired will not add an authorisation header a request that already specifies it"
25
- );
26
- }
27
- // should I bother with response code?
28
- // maybe I can just throw the json error?
29
-
30
- const response = await fetch(`${CF_API_BASE_URL}${resource}`, {
31
- method: "GET",
32
- ...init,
33
- headers: {
34
- ...(init.headers || {}),
35
- Authorization: `Bearer ${apiToken}`,
36
- },
37
- });
38
- const text = await response.text();
39
- let json;
40
- try {
41
- json = JSON.parse(text);
42
- } catch (parseError) {
43
- // hate this edge case
44
- // the only api call I know that doesn't return json is kv:key get <key>
45
-
46
- // maybe it's a plain response
47
- if (response.ok) {
48
- // @ts-expect-error bleh
49
- return text;
50
- } else {
51
- // UGH.
52
- throw new Error(`${response.status}: ${response.statusText}`);
53
- }
54
- }
55
-
56
- if (json.success) {
57
- return json.result;
58
- } else {
59
- const errorDesc = json.errors?.[0];
60
- if (errorDesc) {
61
- // TODO: map .message to real human readable strings
62
- const error = new Error(`${errorDesc.code}: ${errorDesc.message}`);
63
- // @ts-expect-error hacksss
64
- error.code = errorDesc.code;
65
- throw error;
66
- } else {
67
- // This should almost never happen.
68
- // ... which means it'll probably happen, lol.
69
- throw new Error(`${response.status}: ${response.statusText}`);
70
- }
71
- }
72
- }
package/src/config.ts DELETED
@@ -1,100 +0,0 @@
1
- // we're going to manually write both the type definition AND
2
- // the validator for the config, so that we can give better error messages
3
-
4
- type Project = "webpack" | "javascript" | "rust";
5
-
6
- type Site = {
7
- // inherited
8
- bucket: string;
9
- "entry-point": string;
10
- include?: string[];
11
- exclude?: string[];
12
- };
13
-
14
- type Dev = {
15
- ip?: string;
16
- port?: number;
17
- local_protocol?: string;
18
- upstream_protocol?: string;
19
- };
20
-
21
- type Vars = { [key: string]: string };
22
-
23
- type Cron = string; // TODO: we should be able to parse a cron pattern with ts
24
-
25
- type KVNamespace = {
26
- binding?: string;
27
- preview_id: string;
28
- id: string;
29
- };
30
-
31
- type Build = {
32
- command?: string;
33
- cwd?: string;
34
- watch_dir?: string;
35
- } & (
36
- | {
37
- upload?: {
38
- format: "service-worker";
39
- main: string;
40
- };
41
- }
42
- | {
43
- upload?: {
44
- format: "modules";
45
- dir?: string;
46
- main?: string;
47
- rules?: {
48
- type: "ESModule" | "CommonJS" | "Text" | "Data" | "CompiledWasm";
49
- globs: string[]; // can we use typescript for these patterns?
50
- fallthrough?: boolean;
51
- };
52
- };
53
- }
54
- );
55
-
56
- type UsageModel = "bundled" | "unbound";
57
-
58
- type Env = {
59
- name?: string; // inherited
60
- account_id?: string; // inherited
61
- workers_dev?: boolean; // inherited
62
- zone_id?: string; // inherited
63
- routes?: string[]; // inherited
64
- route?: string; // inherited
65
- webpack_config?: string; // inherited
66
- site?: Site;
67
- jsxFactory?: string; // inherited
68
- jsxFragment?: string; // inherited
69
- // we should use typescript to parse cron patterns
70
- triggers?: { crons: Cron[] }; // inherited
71
- kv_namespaces?: KVNamespace[];
72
- };
73
-
74
- export type Config = {
75
- name?: string; // inherited
76
- account_id?: string; // inherited
77
- // @deprecated Don't use this
78
- type?: Project; // top level
79
- // -- there's some mutually exclusive logic for this next block,
80
- // but I didn't bother for now
81
- workers_dev?: boolean; // inherited
82
- zone_id?: string; // inherited
83
- routes?: string[]; // inherited
84
- route?: string; // inherited
85
- // -- end mutually exclusive stuff
86
- // @deprecated Don't use this
87
- webpack_config?: string; // inherited
88
- jsxFactory?: string; // inherited
89
- jsxFragment?: string; // inherited
90
- vars?: Vars;
91
- kv_namespaces?: KVNamespace[];
92
- site?: Site; // inherited
93
- // we should use typescript to parse cron patterns
94
- triggers?: { crons: Cron[] }; // inherited
95
- dev?: Dev;
96
- usage_model?: UsageModel; // inherited
97
- // top level
98
- build?: Build;
99
- env?: { [envName: string]: Env };
100
- };