@liquidmetal-ai/drizzle 0.0.4 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/.changeset/slow-guests-stare.md +7 -0
  2. package/.changeset/tasty-tigers-wash.md +6 -0
  3. package/.turbo/turbo-build.log +1 -1
  4. package/.turbo/turbo-lint.log +1 -1
  5. package/.turbo/turbo-test.log +211 -0
  6. package/dist/appify/build.d.ts +1 -0
  7. package/dist/appify/build.d.ts.map +1 -1
  8. package/dist/appify/build.js +4 -3
  9. package/dist/appify/build.test.js +1 -3
  10. package/dist/appify/index.test.js +2 -2
  11. package/dist/appify/parse.test.js +0 -1
  12. package/dist/appify/validate.d.ts.map +1 -1
  13. package/dist/appify/validate.js +34 -7
  14. package/dist/appify/validate.test.js +119 -26
  15. package/dist/codestore.d.ts +40 -0
  16. package/dist/codestore.d.ts.map +1 -1
  17. package/dist/codestore.js +15 -0
  18. package/dist/liquidmetal/v1alpha1/catalog_connect.d.ts +12 -12
  19. package/dist/liquidmetal/v1alpha1/catalog_connect.d.ts.map +1 -1
  20. package/dist/liquidmetal/v1alpha1/catalog_connect.js +12 -12
  21. package/dist/liquidmetal/v1alpha1/catalog_pb.d.ts +119 -77
  22. package/dist/liquidmetal/v1alpha1/catalog_pb.d.ts.map +1 -1
  23. package/dist/liquidmetal/v1alpha1/catalog_pb.js +177 -107
  24. package/dist/raindrop/index.d.ts +2 -0
  25. package/dist/raindrop/index.d.ts.map +1 -0
  26. package/dist/raindrop/index.js +4 -0
  27. package/dist/raindrop/index.test.d.ts +2 -0
  28. package/dist/raindrop/index.test.d.ts.map +1 -0
  29. package/dist/raindrop/index.test.js +5 -0
  30. package/dist/unsafe/codestore.d.ts +5 -0
  31. package/dist/unsafe/codestore.d.ts.map +1 -1
  32. package/dist/unsafe/codestore.js +5 -1
  33. package/dist/unsafe/framework.d.ts +11 -0
  34. package/dist/unsafe/framework.d.ts.map +1 -0
  35. package/dist/unsafe/framework.js +96 -0
  36. package/dist/unsafe/framework.test.d.ts +2 -0
  37. package/dist/unsafe/framework.test.d.ts.map +1 -0
  38. package/dist/unsafe/framework.test.js +175 -0
  39. package/eslint.config.mjs +1 -2
  40. package/package.json +1 -1
  41. package/src/appify/build.test.ts +1 -3
  42. package/src/appify/build.ts +4 -3
  43. package/src/appify/index.test.ts +2 -2
  44. package/src/appify/parse.test.ts +0 -1
  45. package/src/appify/validate.test.ts +123 -26
  46. package/src/appify/validate.ts +39 -7
  47. package/src/codestore.ts +40 -1
  48. package/src/liquidmetal/v1alpha1/catalog_connect.ts +12 -12
  49. package/src/liquidmetal/v1alpha1/catalog_pb.ts +213 -127
  50. package/src/raindrop/index.test.ts +6 -0
  51. package/src/raindrop/index.ts +4 -0
  52. package/src/unsafe/codestore.ts +7 -3
  53. package/src/unsafe/framework.test.ts +205 -0
  54. package/src/unsafe/framework.ts +113 -0
  55. package/tsconfig.json +3 -9
  56. package/tsconfig.tsbuildinfo +1 -1
@@ -215,6 +215,133 @@ export class ApplicationsResponse_Application extends Message<ApplicationsRespon
215
215
  }
216
216
  }
217
217
 
218
+ /**
219
+ * @generated from message liquidmetal.v1alpha1.BootstrapRequest
220
+ */
221
+ export class BootstrapRequest extends Message<BootstrapRequest> {
222
+ /**
223
+ * @generated from field: string user_id = 1;
224
+ */
225
+ userId = "";
226
+
227
+ /**
228
+ * @generated from field: string organization_id = 2;
229
+ */
230
+ organizationId = "";
231
+
232
+ /**
233
+ * token is a special string interpreted by the catalog service to prove that
234
+ * bootstrapping is desired from a trusted caller.
235
+ *
236
+ * @generated from field: string token = 3;
237
+ */
238
+ token = "";
239
+
240
+ /**
241
+ * cloudflare_account_id is cloudflare's account identifier tag.
242
+ * <= 32 characters
243
+ * Example:
244
+ * eb78d65290b24279ba6f44721b3ea3c4
245
+ *
246
+ * @generated from field: string cloudflare_account_id = 4;
247
+ */
248
+ cloudflareAccountId = "";
249
+
250
+ /**
251
+ * cloudflare_bearer_token is an API key used with an http header
252
+ * "Authorization: Bearer {cloudflare_bearer_token}".
253
+ *
254
+ * @generated from field: string cloudflare_bearer_token = 5;
255
+ */
256
+ cloudflareBearerToken = "";
257
+
258
+ /**
259
+ * liquidmetal_services_domain is a domain allocated for running services like
260
+ * catalog api within the tenant account. The zone managing records for this
261
+ * domain already exists in the provided account specified by
262
+ * cloudflare_account_id.
263
+ *
264
+ * e.g. 01j5980p15smvppgf3zbbw491h.tenant.liquidmetal.run
265
+ *
266
+ * @generated from field: string liquidmetal_services_domain = 6;
267
+ */
268
+ liquidmetalServicesDomain = "";
269
+
270
+ /**
271
+ * customer_services_domain is a domain allocated for running
272
+ * customer-deployed applications. The zone managing records for this domain
273
+ * already exists in the provided account specified by cloudflare_account_id.
274
+ * e.g. 01j5980p15smvppgf3zbbw491h.lmapp.run
275
+ *
276
+ * @generated from field: string customer_services_domain = 7;
277
+ */
278
+ customerServicesDomain = "";
279
+
280
+ constructor(data?: PartialMessage<BootstrapRequest>) {
281
+ super();
282
+ proto3.util.initPartial(data, this);
283
+ }
284
+
285
+ static readonly runtime: typeof proto3 = proto3;
286
+ static readonly typeName = "liquidmetal.v1alpha1.BootstrapRequest";
287
+ static readonly fields: FieldList = proto3.util.newFieldList(() => [
288
+ { no: 1, name: "user_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
289
+ { no: 2, name: "organization_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
290
+ { no: 3, name: "token", kind: "scalar", T: 9 /* ScalarType.STRING */ },
291
+ { no: 4, name: "cloudflare_account_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
292
+ { no: 5, name: "cloudflare_bearer_token", kind: "scalar", T: 9 /* ScalarType.STRING */ },
293
+ { no: 6, name: "liquidmetal_services_domain", kind: "scalar", T: 9 /* ScalarType.STRING */ },
294
+ { no: 7, name: "customer_services_domain", kind: "scalar", T: 9 /* ScalarType.STRING */ },
295
+ ]);
296
+
297
+ static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): BootstrapRequest {
298
+ return new BootstrapRequest().fromBinary(bytes, options);
299
+ }
300
+
301
+ static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): BootstrapRequest {
302
+ return new BootstrapRequest().fromJson(jsonValue, options);
303
+ }
304
+
305
+ static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): BootstrapRequest {
306
+ return new BootstrapRequest().fromJsonString(jsonString, options);
307
+ }
308
+
309
+ static equals(a: BootstrapRequest | PlainMessage<BootstrapRequest> | undefined, b: BootstrapRequest | PlainMessage<BootstrapRequest> | undefined): boolean {
310
+ return proto3.util.equals(BootstrapRequest, a, b);
311
+ }
312
+ }
313
+
314
+ /**
315
+ * @generated from message liquidmetal.v1alpha1.BootstrapResponse
316
+ */
317
+ export class BootstrapResponse extends Message<BootstrapResponse> {
318
+ constructor(data?: PartialMessage<BootstrapResponse>) {
319
+ super();
320
+ proto3.util.initPartial(data, this);
321
+ }
322
+
323
+ static readonly runtime: typeof proto3 = proto3;
324
+ static readonly typeName = "liquidmetal.v1alpha1.BootstrapResponse";
325
+ static readonly fields: FieldList = proto3.util.newFieldList(() => [
326
+ ]);
327
+
328
+ static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): BootstrapResponse {
329
+ return new BootstrapResponse().fromBinary(bytes, options);
330
+ }
331
+
332
+ static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): BootstrapResponse {
333
+ return new BootstrapResponse().fromJson(jsonValue, options);
334
+ }
335
+
336
+ static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): BootstrapResponse {
337
+ return new BootstrapResponse().fromJsonString(jsonString, options);
338
+ }
339
+
340
+ static equals(a: BootstrapResponse | PlainMessage<BootstrapResponse> | undefined, b: BootstrapResponse | PlainMessage<BootstrapResponse> | undefined): boolean {
341
+ return proto3.util.equals(BootstrapResponse, a, b);
342
+ }
343
+ }
344
+
218
345
  /**
219
346
  * InternalApplicationsRequestPaginationToken is what we serialize into an
220
347
  * opaque string that is interpreted within internal backend systems
@@ -307,6 +434,43 @@ export class CreateApplicationsRequest extends Message<CreateApplicationsRequest
307
434
  }
308
435
  }
309
436
 
437
+ /**
438
+ * @generated from message liquidmetal.v1alpha1.CreateApplicationsRequest.ApplicationMetadata
439
+ */
440
+ export class CreateApplicationsRequest_ApplicationMetadata extends Message<CreateApplicationsRequest_ApplicationMetadata> {
441
+ /**
442
+ * @generated from field: string runtime_version = 1;
443
+ */
444
+ runtimeVersion = "";
445
+
446
+ constructor(data?: PartialMessage<CreateApplicationsRequest_ApplicationMetadata>) {
447
+ super();
448
+ proto3.util.initPartial(data, this);
449
+ }
450
+
451
+ static readonly runtime: typeof proto3 = proto3;
452
+ static readonly typeName = "liquidmetal.v1alpha1.CreateApplicationsRequest.ApplicationMetadata";
453
+ static readonly fields: FieldList = proto3.util.newFieldList(() => [
454
+ { no: 1, name: "runtime_version", kind: "scalar", T: 9 /* ScalarType.STRING */ },
455
+ ]);
456
+
457
+ static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): CreateApplicationsRequest_ApplicationMetadata {
458
+ return new CreateApplicationsRequest_ApplicationMetadata().fromBinary(bytes, options);
459
+ }
460
+
461
+ static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): CreateApplicationsRequest_ApplicationMetadata {
462
+ return new CreateApplicationsRequest_ApplicationMetadata().fromJson(jsonValue, options);
463
+ }
464
+
465
+ static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): CreateApplicationsRequest_ApplicationMetadata {
466
+ return new CreateApplicationsRequest_ApplicationMetadata().fromJsonString(jsonString, options);
467
+ }
468
+
469
+ static equals(a: CreateApplicationsRequest_ApplicationMetadata | PlainMessage<CreateApplicationsRequest_ApplicationMetadata> | undefined, b: CreateApplicationsRequest_ApplicationMetadata | PlainMessage<CreateApplicationsRequest_ApplicationMetadata> | undefined): boolean {
470
+ return proto3.util.equals(CreateApplicationsRequest_ApplicationMetadata, a, b);
471
+ }
472
+ }
473
+
310
474
  /**
311
475
  * @generated from message liquidmetal.v1alpha1.CreateApplicationsRequest.Application
312
476
  */
@@ -348,6 +512,11 @@ export class CreateApplicationsRequest_Application extends Message<CreateApplica
348
512
  */
349
513
  isActive = false;
350
514
 
515
+ /**
516
+ * @generated from field: liquidmetal.v1alpha1.CreateApplicationsRequest.ApplicationMetadata metadata = 7;
517
+ */
518
+ metadata?: CreateApplicationsRequest_ApplicationMetadata;
519
+
351
520
  constructor(data?: PartialMessage<CreateApplicationsRequest_Application>) {
352
521
  super();
353
522
  proto3.util.initPartial(data, this);
@@ -362,6 +531,7 @@ export class CreateApplicationsRequest_Application extends Message<CreateApplica
362
531
  { no: 4, name: "manifest", kind: "scalar", T: 9 /* ScalarType.STRING */ },
363
532
  { no: 5, name: "manifest_json", kind: "scalar", T: 9 /* ScalarType.STRING */ },
364
533
  { no: 6, name: "is_active", kind: "scalar", T: 8 /* ScalarType.BOOL */ },
534
+ { no: 7, name: "metadata", kind: "message", T: CreateApplicationsRequest_ApplicationMetadata },
365
535
  ]);
366
536
 
367
537
  static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): CreateApplicationsRequest_Application {
@@ -1349,133 +1519,6 @@ export class GetEnvResponse extends Message<GetEnvResponse> {
1349
1519
  }
1350
1520
  }
1351
1521
 
1352
- /**
1353
- * @generated from message liquidmetal.v1alpha1.BootstrapRequest
1354
- */
1355
- export class BootstrapRequest extends Message<BootstrapRequest> {
1356
- /**
1357
- * @generated from field: string user_id = 1;
1358
- */
1359
- userId = "";
1360
-
1361
- /**
1362
- * @generated from field: string organization_id = 2;
1363
- */
1364
- organizationId = "";
1365
-
1366
- /**
1367
- * token is a special string interpreted by the catalog service to prove that
1368
- * bootstrapping is desired from a trusted caller.
1369
- *
1370
- * @generated from field: string token = 3;
1371
- */
1372
- token = "";
1373
-
1374
- /**
1375
- * cloudflare_account_id is cloudflare's account identifier tag.
1376
- * <= 32 characters
1377
- * Example:
1378
- * eb78d65290b24279ba6f44721b3ea3c4
1379
- *
1380
- * @generated from field: string cloudflare_account_id = 4;
1381
- */
1382
- cloudflareAccountId = "";
1383
-
1384
- /**
1385
- * cloudflare_bearer_token is an API key used with an http header
1386
- * "Authorization: Bearer {cloudflare_bearer_token}".
1387
- *
1388
- * @generated from field: string cloudflare_bearer_token = 5;
1389
- */
1390
- cloudflareBearerToken = "";
1391
-
1392
- /**
1393
- * liquidmetal_services_domain is a domain allocated for running services like
1394
- * catalog api within the tenant account. The zone managing records for this
1395
- * domain already exists in the provided account specified by
1396
- * cloudflare_account_id.
1397
- *
1398
- * e.g. 01j5980p15smvppgf3zbbw491h.tenant.liquidmetal.run
1399
- *
1400
- * @generated from field: string liquidmetal_services_domain = 6;
1401
- */
1402
- liquidmetalServicesDomain = "";
1403
-
1404
- /**
1405
- * customer_services_domain is a domain allocated for running
1406
- * customer-deployed applications. The zone managing records for this domain
1407
- * already exists in the provided account specified by cloudflare_account_id.
1408
- * e.g. 01j5980p15smvppgf3zbbw491h.lmapp.run
1409
- *
1410
- * @generated from field: string customer_services_domain = 7;
1411
- */
1412
- customerServicesDomain = "";
1413
-
1414
- constructor(data?: PartialMessage<BootstrapRequest>) {
1415
- super();
1416
- proto3.util.initPartial(data, this);
1417
- }
1418
-
1419
- static readonly runtime: typeof proto3 = proto3;
1420
- static readonly typeName = "liquidmetal.v1alpha1.BootstrapRequest";
1421
- static readonly fields: FieldList = proto3.util.newFieldList(() => [
1422
- { no: 1, name: "user_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
1423
- { no: 2, name: "organization_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
1424
- { no: 3, name: "token", kind: "scalar", T: 9 /* ScalarType.STRING */ },
1425
- { no: 4, name: "cloudflare_account_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
1426
- { no: 5, name: "cloudflare_bearer_token", kind: "scalar", T: 9 /* ScalarType.STRING */ },
1427
- { no: 6, name: "liquidmetal_services_domain", kind: "scalar", T: 9 /* ScalarType.STRING */ },
1428
- { no: 7, name: "customer_services_domain", kind: "scalar", T: 9 /* ScalarType.STRING */ },
1429
- ]);
1430
-
1431
- static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): BootstrapRequest {
1432
- return new BootstrapRequest().fromBinary(bytes, options);
1433
- }
1434
-
1435
- static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): BootstrapRequest {
1436
- return new BootstrapRequest().fromJson(jsonValue, options);
1437
- }
1438
-
1439
- static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): BootstrapRequest {
1440
- return new BootstrapRequest().fromJsonString(jsonString, options);
1441
- }
1442
-
1443
- static equals(a: BootstrapRequest | PlainMessage<BootstrapRequest> | undefined, b: BootstrapRequest | PlainMessage<BootstrapRequest> | undefined): boolean {
1444
- return proto3.util.equals(BootstrapRequest, a, b);
1445
- }
1446
- }
1447
-
1448
- /**
1449
- * @generated from message liquidmetal.v1alpha1.BootstrapResponse
1450
- */
1451
- export class BootstrapResponse extends Message<BootstrapResponse> {
1452
- constructor(data?: PartialMessage<BootstrapResponse>) {
1453
- super();
1454
- proto3.util.initPartial(data, this);
1455
- }
1456
-
1457
- static readonly runtime: typeof proto3 = proto3;
1458
- static readonly typeName = "liquidmetal.v1alpha1.BootstrapResponse";
1459
- static readonly fields: FieldList = proto3.util.newFieldList(() => [
1460
- ]);
1461
-
1462
- static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): BootstrapResponse {
1463
- return new BootstrapResponse().fromBinary(bytes, options);
1464
- }
1465
-
1466
- static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): BootstrapResponse {
1467
- return new BootstrapResponse().fromJson(jsonValue, options);
1468
- }
1469
-
1470
- static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): BootstrapResponse {
1471
- return new BootstrapResponse().fromJsonString(jsonString, options);
1472
- }
1473
-
1474
- static equals(a: BootstrapResponse | PlainMessage<BootstrapResponse> | undefined, b: BootstrapResponse | PlainMessage<BootstrapResponse> | undefined): boolean {
1475
- return proto3.util.equals(BootstrapResponse, a, b);
1476
- }
1477
- }
1478
-
1479
1522
  /**
1480
1523
  * @generated from message liquidmetal.v1alpha1.SetApplicationActiveStatesRequest
1481
1524
  */
@@ -1709,6 +1752,43 @@ export class SetApplicationManifestsRequest extends Message<SetApplicationManife
1709
1752
  }
1710
1753
  }
1711
1754
 
1755
+ /**
1756
+ * @generated from message liquidmetal.v1alpha1.SetApplicationManifestsRequest.ApplicationMetadata
1757
+ */
1758
+ export class SetApplicationManifestsRequest_ApplicationMetadata extends Message<SetApplicationManifestsRequest_ApplicationMetadata> {
1759
+ /**
1760
+ * @generated from field: string runtime_version = 1;
1761
+ */
1762
+ runtimeVersion = "";
1763
+
1764
+ constructor(data?: PartialMessage<SetApplicationManifestsRequest_ApplicationMetadata>) {
1765
+ super();
1766
+ proto3.util.initPartial(data, this);
1767
+ }
1768
+
1769
+ static readonly runtime: typeof proto3 = proto3;
1770
+ static readonly typeName = "liquidmetal.v1alpha1.SetApplicationManifestsRequest.ApplicationMetadata";
1771
+ static readonly fields: FieldList = proto3.util.newFieldList(() => [
1772
+ { no: 1, name: "runtime_version", kind: "scalar", T: 9 /* ScalarType.STRING */ },
1773
+ ]);
1774
+
1775
+ static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): SetApplicationManifestsRequest_ApplicationMetadata {
1776
+ return new SetApplicationManifestsRequest_ApplicationMetadata().fromBinary(bytes, options);
1777
+ }
1778
+
1779
+ static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): SetApplicationManifestsRequest_ApplicationMetadata {
1780
+ return new SetApplicationManifestsRequest_ApplicationMetadata().fromJson(jsonValue, options);
1781
+ }
1782
+
1783
+ static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): SetApplicationManifestsRequest_ApplicationMetadata {
1784
+ return new SetApplicationManifestsRequest_ApplicationMetadata().fromJsonString(jsonString, options);
1785
+ }
1786
+
1787
+ static equals(a: SetApplicationManifestsRequest_ApplicationMetadata | PlainMessage<SetApplicationManifestsRequest_ApplicationMetadata> | undefined, b: SetApplicationManifestsRequest_ApplicationMetadata | PlainMessage<SetApplicationManifestsRequest_ApplicationMetadata> | undefined): boolean {
1788
+ return proto3.util.equals(SetApplicationManifestsRequest_ApplicationMetadata, a, b);
1789
+ }
1790
+ }
1791
+
1712
1792
  /**
1713
1793
  * @generated from message liquidmetal.v1alpha1.SetApplicationManifestsRequest.Manifest
1714
1794
  */
@@ -1728,6 +1808,11 @@ export class SetApplicationManifestsRequest_Manifest extends Message<SetApplicat
1728
1808
  */
1729
1809
  manifest = "";
1730
1810
 
1811
+ /**
1812
+ * @generated from field: liquidmetal.v1alpha1.SetApplicationManifestsRequest.ApplicationMetadata metadata = 4;
1813
+ */
1814
+ metadata?: SetApplicationManifestsRequest_ApplicationMetadata;
1815
+
1731
1816
  constructor(data?: PartialMessage<SetApplicationManifestsRequest_Manifest>) {
1732
1817
  super();
1733
1818
  proto3.util.initPartial(data, this);
@@ -1739,6 +1824,7 @@ export class SetApplicationManifestsRequest_Manifest extends Message<SetApplicat
1739
1824
  { no: 1, name: "name", kind: "scalar", T: 9 /* ScalarType.STRING */ },
1740
1825
  { no: 2, name: "version_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
1741
1826
  { no: 3, name: "manifest", kind: "scalar", T: 9 /* ScalarType.STRING */ },
1827
+ { no: 4, name: "metadata", kind: "message", T: SetApplicationManifestsRequest_ApplicationMetadata },
1742
1828
  ]);
1743
1829
 
1744
1830
  static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): SetApplicationManifestsRequest_Manifest {
@@ -0,0 +1,6 @@
1
+ import { expect, test } from 'vitest';
2
+ import { urlifyOrganizationId } from './index.js';
3
+
4
+ test('urlifyOrganizationId', async () => {
5
+ expect(urlifyOrganizationId('org_01J99WVZ3PKE5W1CHW5H3HD8EN')).toBe('01j99wvz3pke5w1chw5h3hd8en');
6
+ });
@@ -0,0 +1,4 @@
1
+ // urlifyOrganizationId converts an organizationId for usage in URLs
2
+ export function urlifyOrganizationId(organizationId: string): string {
3
+ return organizationId.replace('org_', '').toLowerCase();
4
+ }
@@ -2,7 +2,11 @@ import * as fs from 'node:fs/promises';
2
2
  import * as path from 'node:path';
3
3
  import { Bundle, BundleBase } from '../codestore.js';
4
4
 
5
- // FileSystemBundle is a Bundle backed by the file system.
5
+ /**
6
+ * A Bundle implementation backed by the local filesystem
7
+ * Provides direct access to files and directories on disk
8
+ * Note: This implementation is marked as "unsafe" since it requires filesystem access
9
+ */
6
10
  export class FileSystemBundle extends BundleBase implements Bundle {
7
11
  private root: string;
8
12
 
@@ -13,8 +17,8 @@ export class FileSystemBundle extends BundleBase implements Bundle {
13
17
 
14
18
  async list(): Promise<string[]> {
15
19
  // readdir is fine but we have to filter out the directories
16
- const flatList = await fs.readdir(this.root, { recursive: true })
17
- const files = []
20
+ const flatList = await fs.readdir(this.root, { recursive: true });
21
+ const files = [];
18
22
  for (const ent of flatList) {
19
23
  const stat = await fs.stat(path.join(this.root, ent));
20
24
  if (stat.isFile()) {
@@ -0,0 +1,205 @@
1
+ import { exec } from 'node:child_process';
2
+ import { mkdir, writeFile } from 'node:fs/promises';
3
+ import { tmpdir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
6
+ import { getPackageVersion } from './framework.js';
7
+
8
+ vi.mock('node:child_process', () => ({
9
+ exec: vi.fn(),
10
+ }));
11
+
12
+ describe('getPackageVersion', () => {
13
+ let tempDir: string;
14
+
15
+ beforeEach(async () => {
16
+ vi.resetAllMocks();
17
+ // Create a new temp directory for each test
18
+ tempDir = join(tmpdir(), `test-${Date.now()}`);
19
+ await mkdir(tempDir, { recursive: true });
20
+
21
+ // Mock process.cwd() to return our temp directory
22
+ vi.spyOn(process, 'cwd').mockReturnValue(tempDir);
23
+ });
24
+
25
+ it('should detect npm package version', async () => {
26
+ // Create package-lock.json to indicate npm
27
+ await writeFile(join(tempDir, 'package-lock.json'), JSON.stringify({ name: 'test' }));
28
+
29
+ // Mock npm list command output
30
+ vi.mocked(exec).mockImplementation((command, callback) => {
31
+ if (command.includes('npm list')) {
32
+ (callback as unknown as (error: null, result: { stdout: string; stderr: string }) => void)(null, {
33
+ stdout: JSON.stringify({
34
+ dependencies: {
35
+ 'test-package': {
36
+ version: '1.2.3',
37
+ },
38
+ },
39
+ }),
40
+ stderr: '',
41
+ });
42
+ }
43
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
44
+ return {} as any;
45
+ });
46
+
47
+ const version = await getPackageVersion('test-package');
48
+ expect(version).toBe('1.2.3');
49
+ });
50
+
51
+ it('should detect yarn package version', async () => {
52
+ // Create yarn.lock to indicate yarn
53
+ await writeFile(join(tempDir, 'yarn.lock'), 'yarn lock contents');
54
+
55
+ // Mock yarn list command output
56
+ vi.mocked(exec).mockImplementation((command, callback) => {
57
+ if (command.includes('yarn list')) {
58
+ (callback as unknown as (error: null, result: { stdout: string; stderr: string }) => void)(null, {
59
+ stdout: JSON.stringify({
60
+ data: {
61
+ trees: [
62
+ {
63
+ name: 'test-package',
64
+ version: '2.3.4',
65
+ },
66
+ ],
67
+ },
68
+ }),
69
+ stderr: '',
70
+ });
71
+ }
72
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
73
+ return {} as any;
74
+ });
75
+
76
+ const version = await getPackageVersion('test-package');
77
+ expect(version).toBe('2.3.4');
78
+ });
79
+
80
+ it('should detect pnpm package version', async () => {
81
+ // Create pnpm-lock.yaml to indicate pnpm
82
+ await writeFile(join(tempDir, 'pnpm-lock.yaml'), 'pnpm lock contents');
83
+
84
+ // Mock pnpm list command output
85
+ vi.mocked(exec).mockImplementation((command, callback) => {
86
+ if (command.includes('pnpm list')) {
87
+ (callback as unknown as (error: null, result: { stdout: string; stderr: string }) => void)(null, {
88
+ stdout: JSON.stringify({
89
+ dependencies: {
90
+ 'test-package': {
91
+ version: '3.4.5',
92
+ },
93
+ },
94
+ }),
95
+ stderr: '',
96
+ });
97
+ }
98
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
99
+ return {} as any;
100
+ });
101
+
102
+ const version = await getPackageVersion('test-package');
103
+ expect(version).toBe('3.4.5');
104
+ });
105
+
106
+ it('should handle nested dependencies', async () => {
107
+ await writeFile(join(tempDir, 'package-lock.json'), JSON.stringify({ name: 'test' }));
108
+
109
+ vi.mocked(exec).mockImplementation((command, callback) => {
110
+ if (command.includes('npm list')) {
111
+ (callback as unknown as (error: null, result: { stdout: string; stderr: string }) => void)(null, {
112
+ stdout: JSON.stringify({
113
+ dependencies: {
114
+ 'parent-package': {
115
+ version: '1.0.0',
116
+ dependencies: {
117
+ 'test-package': {
118
+ version: '4.5.6',
119
+ },
120
+ },
121
+ },
122
+ },
123
+ }),
124
+ stderr: '',
125
+ });
126
+ }
127
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
128
+ return {} as any;
129
+ });
130
+
131
+ const version = await getPackageVersion('test-package');
132
+ expect(version).toBe('4.5.6');
133
+ });
134
+
135
+ it('should return null when package is not found', async () => {
136
+ await writeFile(join(tempDir, 'package-lock.json'), JSON.stringify({ name: 'test' }));
137
+
138
+ vi.mocked(exec).mockImplementation((command, callback) => {
139
+ if (command.includes('npm list')) {
140
+ (callback as unknown as (error: null, result: { stdout: string; stderr: string }) => void)(null, {
141
+ stdout: JSON.stringify({
142
+ dependencies: {},
143
+ }),
144
+ stderr: '',
145
+ });
146
+ }
147
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
148
+ return {} as any;
149
+ });
150
+
151
+ const version = await getPackageVersion('non-existent-package');
152
+ expect(version).toBeNull();
153
+ });
154
+
155
+ it('should search parent directories for package manager files', async () => {
156
+ // Create a nested directory structure
157
+ const nestedDir = join(tempDir, 'nested', 'deeper');
158
+ await mkdir(nestedDir, { recursive: true });
159
+
160
+ // Create package-lock.json in parent directory
161
+ await writeFile(join(tempDir, 'package-lock.json'), JSON.stringify({ name: 'test' }));
162
+
163
+ // Set cwd to nested directory
164
+ vi.spyOn(process, 'cwd').mockReturnValue(nestedDir);
165
+
166
+ vi.mocked(exec).mockImplementation((command, callback) => {
167
+ if (command.includes('npm list')) {
168
+ (callback as unknown as (error: null, result: { stdout: string; stderr: string }) => void)(null, {
169
+ stdout: JSON.stringify({
170
+ dependencies: {
171
+ 'test-package': {
172
+ version: '5.6.7',
173
+ },
174
+ },
175
+ }),
176
+ stderr: '',
177
+ });
178
+ }
179
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
180
+ return {} as any;
181
+ });
182
+
183
+ const version = await getPackageVersion('test-package');
184
+ expect(version).toBe('5.6.7');
185
+ });
186
+
187
+ it('should handle command execution errors', async () => {
188
+ await writeFile(join(tempDir, 'package-lock.json'), JSON.stringify({ name: 'test' }));
189
+
190
+ vi.mocked(exec).mockImplementation((_command, callback) => {
191
+ (callback as unknown as (error: Error, result: { stdout: string; stderr: string }) => void)(
192
+ new Error('Command failed'),
193
+ {
194
+ stdout: '',
195
+ stderr: 'failure',
196
+ },
197
+ );
198
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
199
+ return {} as any;
200
+ });
201
+
202
+ const version = await getPackageVersion('test-package');
203
+ expect(version).toBeNull();
204
+ });
205
+ });