wrangler 0.0.0-e6733a3 → 0.0.0-e9307365

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 (220) hide show
  1. package/Cloudflare_CA.pem +18 -0
  2. package/README.md +51 -14
  3. package/bin/wrangler.js +159 -27
  4. package/kv-asset-handler.js +1 -0
  5. package/miniflare-dist/index.mjs +5416 -0
  6. package/package.json +171 -124
  7. package/src/__tests__/config-cache-without-cache-dir.test.ts +38 -0
  8. package/src/__tests__/config-cache.test.ts +42 -0
  9. package/src/__tests__/configuration.test.ts +4022 -0
  10. package/src/__tests__/dev.test.tsx +1290 -62
  11. package/src/__tests__/generate.test.ts +93 -0
  12. package/src/__tests__/guess-worker-format.test.ts +85 -0
  13. package/src/__tests__/{clipboardy-mock.js → helpers/clipboardy-mock.js} +0 -0
  14. package/src/__tests__/helpers/cmd-shim.d.ts +11 -0
  15. package/src/__tests__/helpers/mock-account-id.ts +48 -0
  16. package/src/__tests__/helpers/mock-bin.ts +36 -0
  17. package/src/__tests__/helpers/mock-cfetch.ts +263 -0
  18. package/src/__tests__/helpers/mock-console.ts +97 -0
  19. package/src/__tests__/helpers/mock-dialogs.ts +153 -0
  20. package/src/__tests__/helpers/mock-http-server.ts +46 -0
  21. package/src/__tests__/helpers/mock-istty.ts +74 -0
  22. package/src/__tests__/helpers/mock-kv.ts +33 -0
  23. package/src/__tests__/helpers/mock-oauth-flow.ts +250 -0
  24. package/src/__tests__/helpers/mock-process.ts +39 -0
  25. package/src/__tests__/helpers/mock-stdin.ts +108 -0
  26. package/src/__tests__/helpers/mock-web-socket.ts +29 -0
  27. package/src/__tests__/helpers/run-in-tmp.ts +38 -0
  28. package/src/__tests__/helpers/run-wrangler.ts +16 -0
  29. package/src/__tests__/helpers/write-worker-source.ts +31 -0
  30. package/src/__tests__/helpers/write-wrangler-toml.ts +17 -0
  31. package/src/__tests__/https-options.test.ts +163 -0
  32. package/src/__tests__/index.test.ts +242 -284
  33. package/src/__tests__/init.test.ts +1992 -0
  34. package/src/__tests__/jest.setup.ts +138 -10
  35. package/src/__tests__/kv.test.ts +1459 -886
  36. package/src/__tests__/logger.test.ts +141 -0
  37. package/src/__tests__/metrics.test.ts +450 -0
  38. package/src/__tests__/package-manager.test.ts +353 -0
  39. package/src/__tests__/pages.test.ts +1261 -0
  40. package/src/__tests__/parse.test.ts +330 -0
  41. package/src/__tests__/publish.test.ts +6914 -0
  42. package/src/__tests__/pubsub.test.ts +367 -0
  43. package/src/__tests__/r2.test.ts +317 -0
  44. package/src/__tests__/route.test.ts +45 -0
  45. package/src/__tests__/secret.test.ts +492 -0
  46. package/src/__tests__/tail.test.ts +698 -0
  47. package/src/__tests__/test-old-node-version.js +31 -0
  48. package/src/__tests__/user.test.ts +144 -0
  49. package/src/__tests__/validate-dev-props.test.ts +56 -0
  50. package/src/__tests__/version.test.ts +35 -0
  51. package/src/__tests__/whoami.test.tsx +289 -0
  52. package/src/__tests__/worker-namespace.test.ts +327 -0
  53. package/src/abort.d.ts +3 -0
  54. package/src/api/dev.ts +86 -0
  55. package/src/api/index.ts +1 -0
  56. package/src/bundle-reporter.tsx +29 -0
  57. package/src/bundle.ts +472 -0
  58. package/src/cfetch/index.ts +88 -69
  59. package/src/cfetch/internal.ts +156 -44
  60. package/src/cli.ts +24 -6
  61. package/src/config/README.md +107 -0
  62. package/src/config/config.ts +263 -0
  63. package/src/config/diagnostics.ts +80 -0
  64. package/src/config/environment.ts +485 -0
  65. package/src/config/index.ts +251 -0
  66. package/src/config/validation-helpers.ts +584 -0
  67. package/src/config/validation.ts +1856 -0
  68. package/src/config-cache.ts +84 -0
  69. package/src/create-worker-preview.ts +257 -0
  70. package/src/create-worker-upload-form.ts +288 -0
  71. package/src/dev/dev-vars.ts +36 -0
  72. package/src/dev/dev.tsx +531 -0
  73. package/src/dev/local.tsx +385 -0
  74. package/src/dev/remote.tsx +413 -0
  75. package/src/dev/use-esbuild.ts +175 -0
  76. package/src/dev/validate-dev-props.ts +31 -0
  77. package/src/dev-registry.tsx +157 -0
  78. package/src/dev.tsx +603 -758
  79. package/src/dialogs.tsx +117 -59
  80. package/src/durable.ts +102 -0
  81. package/src/entry.ts +328 -0
  82. package/src/environment-variables.ts +35 -0
  83. package/src/errors.ts +11 -0
  84. package/src/faye-websocket.d.ts +6 -0
  85. package/src/generate.ts +131 -0
  86. package/src/git-client.ts +42 -0
  87. package/src/global-wrangler-config-path.ts +26 -0
  88. package/src/https-options.ts +127 -0
  89. package/src/index.tsx +2166 -1956
  90. package/src/init.ts +549 -0
  91. package/src/inspect.ts +703 -477
  92. package/src/intl-polyfill.d.ts +139 -0
  93. package/src/is-interactive.ts +12 -0
  94. package/src/kv.ts +430 -0
  95. package/src/logger.ts +73 -0
  96. package/src/metrics/index.ts +5 -0
  97. package/src/metrics/is-ci.ts +14 -0
  98. package/src/metrics/metrics-config.ts +239 -0
  99. package/src/metrics/metrics-dispatcher.ts +96 -0
  100. package/src/metrics/metrics-usage-headers.ts +24 -0
  101. package/src/metrics/send-event.ts +92 -0
  102. package/src/miniflare-cli/README.md +30 -0
  103. package/src/miniflare-cli/assets.ts +543 -0
  104. package/src/miniflare-cli/enum-keys.ts +17 -0
  105. package/src/miniflare-cli/index.ts +85 -0
  106. package/src/miniflare-cli/request-context.ts +40 -0
  107. package/src/module-collection.ts +247 -53
  108. package/src/open-in-browser.ts +17 -0
  109. package/src/package-manager.ts +219 -0
  110. package/src/pages/build.tsx +204 -0
  111. package/src/pages/constants.ts +8 -0
  112. package/src/pages/deployments.tsx +106 -0
  113. package/src/pages/dev.tsx +414 -0
  114. package/src/pages/functions/buildPlugin.ts +105 -0
  115. package/src/pages/functions/buildWorker.ts +151 -0
  116. package/src/pages/functions/filepath-routing.test.ts +234 -0
  117. package/src/pages/functions/filepath-routing.ts +189 -0
  118. package/src/pages/functions/identifiers.ts +78 -0
  119. package/src/pages/functions/routes.ts +151 -0
  120. package/src/pages/index.tsx +84 -0
  121. package/src/pages/projects.tsx +163 -0
  122. package/src/pages/publish.tsx +338 -0
  123. package/src/pages/types.ts +40 -0
  124. package/src/pages/upload.tsx +415 -0
  125. package/src/pages/utils.ts +12 -0
  126. package/src/parse.ts +286 -0
  127. package/src/paths.ts +26 -0
  128. package/src/preview.ts +31 -0
  129. package/src/proxy.ts +434 -252
  130. package/src/publish.ts +794 -345
  131. package/src/pubsub/index.ts +286 -0
  132. package/src/pubsub/pubsub-commands.tsx +623 -0
  133. package/src/r2.ts +118 -0
  134. package/src/selfsigned.d.ts +29 -0
  135. package/src/sites.tsx +357 -99
  136. package/src/tail/filters.ts +279 -0
  137. package/src/tail/index.ts +299 -0
  138. package/src/tail/printing.ts +67 -0
  139. package/src/update-check.ts +19 -0
  140. package/src/user/choose-account.tsx +69 -0
  141. package/src/user/env-vars.ts +46 -0
  142. package/src/user/generate-auth-url.ts +33 -0
  143. package/src/user/generate-random-state.ts +16 -0
  144. package/src/user/index.ts +3 -0
  145. package/src/user/user.tsx +1189 -0
  146. package/src/whoami.tsx +169 -0
  147. package/src/worker-namespace.ts +206 -0
  148. package/src/worker.ts +203 -0
  149. package/src/zones.ts +76 -0
  150. package/templates/checked-fetch.js +17 -0
  151. package/templates/first-party-worker-module-facade.ts +18 -0
  152. package/templates/format-dev-errors.ts +32 -0
  153. package/templates/gitignore +171 -0
  154. package/templates/new-worker-scheduled.js +17 -0
  155. package/templates/new-worker-scheduled.ts +32 -0
  156. package/templates/new-worker.js +15 -0
  157. package/templates/new-worker.ts +30 -0
  158. package/templates/no-op-worker.js +10 -0
  159. package/templates/pages-shim.ts +9 -0
  160. package/templates/pages-template-plugin.ts +155 -0
  161. package/templates/pages-template-worker.ts +161 -0
  162. package/templates/serve-static-assets.ts +63 -0
  163. package/templates/service-bindings-module-facade.js +51 -0
  164. package/templates/service-bindings-sw-facade.js +39 -0
  165. package/templates/tsconfig.json +105 -0
  166. package/wrangler-dist/cli.d.ts +327 -0
  167. package/wrangler-dist/cli.js +134880 -109997
  168. package/pages/functions/buildWorker.ts +0 -62
  169. package/pages/functions/filepath-routing.test.ts +0 -39
  170. package/pages/functions/filepath-routing.ts +0 -221
  171. package/pages/functions/identifiers.ts +0 -78
  172. package/pages/functions/routes.ts +0 -158
  173. package/pages/functions/template-worker.ts +0 -144
  174. package/src/__tests__/mock-cfetch.ts +0 -171
  175. package/src/__tests__/mock-dialogs.ts +0 -65
  176. package/src/__tests__/run-in-tmp.ts +0 -19
  177. package/src/__tests__/run-wrangler.ts +0 -32
  178. package/src/api/form_data.ts +0 -131
  179. package/src/api/preview.ts +0 -128
  180. package/src/api/worker.ts +0 -155
  181. package/src/config.ts +0 -487
  182. package/src/kv.tsx +0 -267
  183. package/src/pages.tsx +0 -1031
  184. package/src/tail.tsx +0 -73
  185. package/src/user.tsx +0 -1025
  186. package/static-asset-facade.js +0 -47
  187. package/vendor/@cloudflare/kv-asset-handler/CHANGELOG.md +0 -332
  188. package/vendor/@cloudflare/kv-asset-handler/LICENSE_APACHE +0 -176
  189. package/vendor/@cloudflare/kv-asset-handler/LICENSE_MIT +0 -25
  190. package/vendor/@cloudflare/kv-asset-handler/README.md +0 -245
  191. package/vendor/@cloudflare/kv-asset-handler/dist/index.d.ts +0 -32
  192. package/vendor/@cloudflare/kv-asset-handler/dist/index.js +0 -354
  193. package/vendor/@cloudflare/kv-asset-handler/dist/mocks.d.ts +0 -13
  194. package/vendor/@cloudflare/kv-asset-handler/dist/mocks.js +0 -148
  195. package/vendor/@cloudflare/kv-asset-handler/dist/test/getAssetFromKV.d.ts +0 -1
  196. package/vendor/@cloudflare/kv-asset-handler/dist/test/getAssetFromKV.js +0 -436
  197. package/vendor/@cloudflare/kv-asset-handler/dist/test/mapRequestToAsset.d.ts +0 -1
  198. package/vendor/@cloudflare/kv-asset-handler/dist/test/mapRequestToAsset.js +0 -40
  199. package/vendor/@cloudflare/kv-asset-handler/dist/test/serveSinglePageApp.d.ts +0 -1
  200. package/vendor/@cloudflare/kv-asset-handler/dist/test/serveSinglePageApp.js +0 -42
  201. package/vendor/@cloudflare/kv-asset-handler/dist/types.d.ts +0 -26
  202. package/vendor/@cloudflare/kv-asset-handler/dist/types.js +0 -31
  203. package/vendor/@cloudflare/kv-asset-handler/package.json +0 -52
  204. package/vendor/@cloudflare/kv-asset-handler/src/index.ts +0 -296
  205. package/vendor/@cloudflare/kv-asset-handler/src/mocks.ts +0 -136
  206. package/vendor/@cloudflare/kv-asset-handler/src/test/getAssetFromKV.ts +0 -464
  207. package/vendor/@cloudflare/kv-asset-handler/src/test/mapRequestToAsset.ts +0 -33
  208. package/vendor/@cloudflare/kv-asset-handler/src/test/serveSinglePageApp.ts +0 -42
  209. package/vendor/@cloudflare/kv-asset-handler/src/types.ts +0 -39
  210. package/vendor/wrangler-mime/CHANGELOG.md +0 -289
  211. package/vendor/wrangler-mime/LICENSE +0 -21
  212. package/vendor/wrangler-mime/Mime.js +0 -97
  213. package/vendor/wrangler-mime/README.md +0 -187
  214. package/vendor/wrangler-mime/cli.js +0 -46
  215. package/vendor/wrangler-mime/index.js +0 -4
  216. package/vendor/wrangler-mime/lite.js +0 -4
  217. package/vendor/wrangler-mime/package.json +0 -52
  218. package/vendor/wrangler-mime/types/other.js +0 -1
  219. package/vendor/wrangler-mime/types/standard.js +0 -1
  220. package/wrangler-dist/cli.js.map +0 -7
@@ -0,0 +1,353 @@
1
+ import { writeFileSync } from "node:fs";
2
+ import { mockBinary } from "./helpers/mock-bin";
3
+ import { mockConsoleMethods } from "./helpers/mock-console";
4
+ import { runInTempDir } from "./helpers/run-in-tmp";
5
+
6
+ const { getPackageManager, getPackageManagerName } =
7
+ jest.requireActual("../package-manager");
8
+ interface TestCase {
9
+ npm: boolean;
10
+ pnpm: boolean;
11
+ yarn: boolean;
12
+ npmLockFile: boolean;
13
+ yarnLockFile: boolean;
14
+ pnpmLockFile: boolean;
15
+ expectedPackageManager: string;
16
+ }
17
+
18
+ const testCases: TestCase[] = [
19
+ // npm binary only
20
+ {
21
+ npm: true,
22
+ yarn: false,
23
+ pnpm: false,
24
+ npmLockFile: false,
25
+ yarnLockFile: false,
26
+ pnpmLockFile: false,
27
+ expectedPackageManager: "npm",
28
+ },
29
+ {
30
+ npm: true,
31
+ yarn: false,
32
+ pnpm: false,
33
+ npmLockFile: true,
34
+ yarnLockFile: false,
35
+ pnpmLockFile: false,
36
+ expectedPackageManager: "npm",
37
+ },
38
+ {
39
+ npm: true,
40
+ yarn: false,
41
+ pnpm: false,
42
+ npmLockFile: false,
43
+ yarnLockFile: true,
44
+ pnpmLockFile: false,
45
+ expectedPackageManager: "npm",
46
+ },
47
+ {
48
+ npm: true,
49
+ yarn: false,
50
+ pnpm: false,
51
+ npmLockFile: true,
52
+ yarnLockFile: true,
53
+ pnpmLockFile: false,
54
+ expectedPackageManager: "npm",
55
+ },
56
+
57
+ // yarn binary only
58
+ {
59
+ npm: false,
60
+ yarn: true,
61
+ pnpm: false,
62
+ npmLockFile: false,
63
+ yarnLockFile: false,
64
+ pnpmLockFile: false,
65
+ expectedPackageManager: "yarn",
66
+ },
67
+ {
68
+ npm: false,
69
+ yarn: true,
70
+ pnpm: false,
71
+ npmLockFile: true,
72
+ yarnLockFile: false,
73
+ pnpmLockFile: false,
74
+ expectedPackageManager: "yarn",
75
+ },
76
+ {
77
+ npm: false,
78
+ yarn: true,
79
+ pnpm: false,
80
+ npmLockFile: false,
81
+ yarnLockFile: true,
82
+ pnpmLockFile: false,
83
+ expectedPackageManager: "yarn",
84
+ },
85
+ {
86
+ npm: false,
87
+ yarn: true,
88
+ pnpm: false,
89
+ npmLockFile: true,
90
+ yarnLockFile: true,
91
+ pnpmLockFile: false,
92
+ expectedPackageManager: "yarn",
93
+ },
94
+
95
+ // pnpm binary only
96
+ {
97
+ npm: false,
98
+ yarn: false,
99
+ pnpm: true,
100
+ npmLockFile: false,
101
+ yarnLockFile: false,
102
+ pnpmLockFile: true,
103
+ expectedPackageManager: "pnpm",
104
+ },
105
+ {
106
+ npm: false,
107
+ yarn: false,
108
+ pnpm: true,
109
+ npmLockFile: true,
110
+ yarnLockFile: false,
111
+ pnpmLockFile: false,
112
+ expectedPackageManager: "pnpm",
113
+ },
114
+ {
115
+ npm: false,
116
+ yarn: false,
117
+ pnpm: true,
118
+ npmLockFile: false,
119
+ yarnLockFile: true,
120
+ pnpmLockFile: false,
121
+ expectedPackageManager: "pnpm",
122
+ },
123
+ {
124
+ npm: false,
125
+ yarn: false,
126
+ pnpm: true,
127
+ npmLockFile: true,
128
+ yarnLockFile: true,
129
+ pnpmLockFile: true,
130
+ expectedPackageManager: "pnpm",
131
+ },
132
+
133
+ // npm and yarn binaries
134
+ {
135
+ npm: true,
136
+ yarn: true,
137
+ pnpm: false,
138
+ npmLockFile: false,
139
+ yarnLockFile: false,
140
+ pnpmLockFile: false,
141
+ expectedPackageManager: "npm",
142
+ },
143
+ {
144
+ npm: true,
145
+ yarn: true,
146
+ pnpm: false,
147
+ npmLockFile: true,
148
+ yarnLockFile: false,
149
+ pnpmLockFile: false,
150
+ expectedPackageManager: "npm",
151
+ },
152
+ {
153
+ npm: true,
154
+ yarn: true,
155
+ pnpm: false,
156
+ npmLockFile: false,
157
+ yarnLockFile: true,
158
+ pnpmLockFile: false,
159
+ expectedPackageManager: "yarn",
160
+ },
161
+ {
162
+ npm: true,
163
+ yarn: true,
164
+ pnpm: false,
165
+ npmLockFile: true,
166
+ yarnLockFile: true,
167
+ pnpmLockFile: false,
168
+ expectedPackageManager: "npm",
169
+ },
170
+ // npm, yarn and pnpm binaries
171
+ {
172
+ npm: true,
173
+ yarn: true,
174
+ pnpm: true,
175
+ npmLockFile: false,
176
+ yarnLockFile: false,
177
+ pnpmLockFile: false,
178
+ expectedPackageManager: "npm",
179
+ },
180
+ {
181
+ npm: true,
182
+ yarn: true,
183
+ pnpm: true,
184
+ npmLockFile: true,
185
+ yarnLockFile: false,
186
+ pnpmLockFile: false,
187
+ expectedPackageManager: "npm",
188
+ },
189
+ {
190
+ npm: true,
191
+ yarn: true,
192
+ pnpm: true,
193
+ npmLockFile: false,
194
+ yarnLockFile: true,
195
+ pnpmLockFile: false,
196
+ expectedPackageManager: "yarn",
197
+ },
198
+ {
199
+ npm: true,
200
+ yarn: true,
201
+ pnpm: true,
202
+ npmLockFile: false,
203
+ yarnLockFile: false,
204
+ pnpmLockFile: true,
205
+ expectedPackageManager: "pnpm",
206
+ },
207
+ {
208
+ npm: true,
209
+ yarn: true,
210
+ pnpm: true,
211
+ npmLockFile: true,
212
+ yarnLockFile: true,
213
+ pnpmLockFile: true,
214
+ expectedPackageManager: "npm",
215
+ },
216
+ ];
217
+
218
+ describe("getPackageManager()", () => {
219
+ runInTempDir();
220
+ mockConsoleMethods();
221
+
222
+ describe("no supported package manager", () => {
223
+ mockYarn(false);
224
+ mockNpm(false);
225
+ mockPnpm(false);
226
+
227
+ it("should throw an error", async () => {
228
+ await expect(() =>
229
+ getPackageManager(process.cwd())
230
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
231
+ `"Unable to find a package manager. Supported managers are: npm, yarn, and pnpm."`
232
+ );
233
+ });
234
+ });
235
+
236
+ for (const {
237
+ npm,
238
+ yarn,
239
+ pnpm,
240
+ npmLockFile,
241
+ yarnLockFile,
242
+ pnpmLockFile,
243
+ expectedPackageManager,
244
+ } of testCases) {
245
+ describe(
246
+ getTestCaseDescription(
247
+ npm,
248
+ yarn,
249
+ pnpm,
250
+ npmLockFile,
251
+ yarnLockFile,
252
+ pnpmLockFile
253
+ ),
254
+ () => {
255
+ mockYarn(yarn);
256
+ mockNpm(npm);
257
+ mockPnpm(pnpm);
258
+ mockLockFiles(npmLockFile, yarnLockFile, pnpmLockFile);
259
+
260
+ it(`should return the ${expectedPackageManager} package manager`, async () => {
261
+ const actualPackageManager = await getPackageManager(process.cwd());
262
+ expect(getPackageManagerName(actualPackageManager)).toEqual(
263
+ expectedPackageManager
264
+ );
265
+ });
266
+ }
267
+ );
268
+ }
269
+ });
270
+
271
+ /**
272
+ * Create a fake yarn binary
273
+ */
274
+ function mockYarn(succeed: boolean): void {
275
+ let unMock: () => void;
276
+ beforeEach(async () => {
277
+ unMock = await mockBinary("yarn", `process.exit(${succeed ? 0 : 1})`);
278
+ });
279
+ afterEach(() => unMock());
280
+ }
281
+
282
+ /**
283
+ * Create a fake npm binary
284
+ */
285
+ function mockNpm(succeed: boolean): void {
286
+ let unMock: () => void;
287
+ beforeEach(async () => {
288
+ unMock = await mockBinary("npm", `process.exit(${succeed ? 0 : 1})`);
289
+ });
290
+ afterEach(() => unMock());
291
+ }
292
+
293
+ /**
294
+ * Create a fake pnpm binary
295
+ */
296
+ function mockPnpm(succeed: boolean): void {
297
+ let unMock: () => void;
298
+ beforeEach(async () => {
299
+ unMock = await mockBinary("pnpm", `process.exit(${succeed ? 0 : 1})`);
300
+ });
301
+ afterEach(() => unMock());
302
+ }
303
+
304
+ /**
305
+ * Create a fake lock files.
306
+ */
307
+ function mockLockFiles(
308
+ npmLockFile: boolean,
309
+ yarnLockFile: boolean,
310
+ pnpmLockFile: boolean
311
+ ) {
312
+ beforeEach(() => {
313
+ if (npmLockFile) {
314
+ writeFileSync("package-lock.json", "");
315
+ }
316
+ if (yarnLockFile) {
317
+ writeFileSync("yarn.lock", "");
318
+ }
319
+ if (pnpmLockFile) {
320
+ writeFileSync("pnpm-lock.yaml", "");
321
+ }
322
+ });
323
+ }
324
+
325
+ function getTestCaseDescription(
326
+ npm: boolean,
327
+ yarn: boolean,
328
+ pnpm: boolean,
329
+ npmLockFile: boolean,
330
+ yarnLockFile: boolean,
331
+ pnpmLockFile: boolean
332
+ ): string {
333
+ const criteria: string[] = [];
334
+ if (npm) {
335
+ criteria.push("npm");
336
+ }
337
+ if (npmLockFile) {
338
+ criteria.push("package-lock.json");
339
+ }
340
+ if (yarn) {
341
+ criteria.push("yarn");
342
+ }
343
+ if (yarnLockFile) {
344
+ criteria.push("yarn.lock");
345
+ }
346
+ if (pnpm) {
347
+ criteria.push("pnpm");
348
+ }
349
+ if (pnpmLockFile) {
350
+ criteria.push("pnpm-lock.yaml");
351
+ }
352
+ return "using " + criteria.join("; ");
353
+ }