@tailor-platform/sdk 1.9.2 → 1.10.0

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.
@@ -1,4 +1,4 @@
1
- import { a as OAuth2ClientSchema, c as tailorUserMap, d as styles, f as symbols, i as ExecutorSchema, l as loadFilesWithIgnores, n as WorkflowJobSchema, o as ResolverSchema, r as WorkflowSchema, s as stringifyFunction, t as defineApplication, u as logger } from "./application-_ArEfxmV.mjs";
1
+ import { a as OAuth2ClientSchema, c as tailorUserMap, d as styles, f as symbols, i as ExecutorSchema, l as loadFilesWithIgnores, n as WorkflowJobSchema, o as ResolverSchema, r as WorkflowSchema, s as stringifyFunction, t as defineApplication, u as logger } from "./application-R26DC-sK.mjs";
2
2
  import { createRequire } from "node:module";
3
3
  import { arg, defineCommand } from "politty";
4
4
  import { z } from "zod";
@@ -519,7 +519,7 @@ const file_tailor_v1_function_registry = /* @__PURE__ */ fileDesc("CiF0YWlsb3Ivd
519
519
  /**
520
520
  * Describes the file tailor/v1/idp_resource.proto.
521
521
  */
522
- const file_tailor_v1_idp_resource = /* @__PURE__ */ fileDesc("Chx0YWlsb3IvdjEvaWRwX3Jlc291cmNlLnByb3RvEgl0YWlsb3IudjEi3gEKCklkUFNlcnZpY2USJwoJbmFtZXNwYWNlGAEgASgLMhQudGFpbG9yLnYxLk5hbWVzcGFjZRIVCg1hdXRob3JpemF0aW9uGAIgASgJEhkKDHByb3ZpZGVyX3VybBgDIAEoCUID4EEDEjYKEHVzZXJfYXV0aF9wb2xpY3kYBCABKAsyHC50YWlsb3IudjEuSWRQVXNlckF1dGhQb2xpY3kSIAoEbGFuZxgFIAEoDjISLnRhaWxvci52MS5JZFBMYW5nEhsKE3B1Ymxpc2hfdXNlcl9ldmVudHMYBiABKAgiTQoJSWRQQ2xpZW50EgwKBG5hbWUYASABKAkSFgoJY2xpZW50X2lkGAIgASgJQgPgQQMSGgoNY2xpZW50X3NlY3JldBgDIAEoCUID4EEDIrcGChFJZFBVc2VyQXV0aFBvbGljeRIgChh1c2Vfbm9uX2VtYWlsX2lkZW50aWZpZXIYASABKAgSIQoZYWxsb3dfc2VsZl9wYXNzd29yZF9yZXNldBgCIAEoCBIiChpwYXNzd29yZF9yZXF1aXJlX3VwcGVyY2FzZRgDIAEoCBIiChpwYXNzd29yZF9yZXF1aXJlX2xvd2VyY2FzZRgEIAEoCBIpCiFwYXNzd29yZF9yZXF1aXJlX25vbl9hbHBoYW51bWVyaWMYBSABKAgSIAoYcGFzc3dvcmRfcmVxdWlyZV9udW1lcmljGAYgASgIEqYBChNwYXNzd29yZF9taW5fbGVuZ3RoGAcgASgFQogBukiEAboBgAEKGXBhc3N3b3JkX21pbl9sZW5ndGhfcmFuZ2USO3Bhc3N3b3JkX21pbl9sZW5ndGggbXVzdCBiZSAwIChkZWZhdWx0KSBvciBiZXR3ZWVuIDYgYW5kIDMwGiZ0aGlzID09IDAgfHwgKHRoaXMgPj0gNiAmJiB0aGlzIDw9IDMwKRKqAQoTcGFzc3dvcmRfbWF4X2xlbmd0aBgIIAEoBUKMAbpIiAG6AYQBChlwYXNzd29yZF9tYXhfbGVuZ3RoX3JhbmdlEj1wYXNzd29yZF9tYXhfbGVuZ3RoIG11c3QgYmUgMCAoZGVmYXVsdCkgb3IgYmV0d2VlbiA2IGFuZCA0MDk2Gih0aGlzID09IDAgfHwgKHRoaXMgPj0gNiAmJiB0aGlzIDw9IDQwOTYpOvEBukjtARrqAQobcGFzc3dvcmRfbGVuZ3RoX2NvbnNpc3RlbmN5EkVwYXNzd29yZF9taW5fbGVuZ3RoIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHBhc3N3b3JkX21heF9sZW5ndGgagwEodGhpcy5wYXNzd29yZF9taW5fbGVuZ3RoID09IDAgPyA2IDogdGhpcy5wYXNzd29yZF9taW5fbGVuZ3RoKSA8PSAodGhpcy5wYXNzd29yZF9tYXhfbGVuZ3RoID09IDAgPyA0MDk2IDogdGhpcy5wYXNzd29yZF9tYXhfbGVuZ3RoKSpICgdJZFBMYW5nEhkKFUlEX1BfTEFOR19VTlNQRUNJRklFRBAAEhAKDElEX1BfTEFOR19FThABEhAKDElEX1BfTEFOR19KQRACYgZwcm90bzM", [
522
+ const file_tailor_v1_idp_resource = /* @__PURE__ */ fileDesc("Chx0YWlsb3IvdjEvaWRwX3Jlc291cmNlLnByb3RvEgl0YWlsb3IudjEi3gEKCklkUFNlcnZpY2USJwoJbmFtZXNwYWNlGAEgASgLMhQudGFpbG9yLnYxLk5hbWVzcGFjZRIVCg1hdXRob3JpemF0aW9uGAIgASgJEhkKDHByb3ZpZGVyX3VybBgDIAEoCUID4EEDEjYKEHVzZXJfYXV0aF9wb2xpY3kYBCABKAsyHC50YWlsb3IudjEuSWRQVXNlckF1dGhQb2xpY3kSIAoEbGFuZxgFIAEoDjISLnRhaWxvci52MS5JZFBMYW5nEhsKE3B1Ymxpc2hfdXNlcl9ldmVudHMYBiABKAgiTQoJSWRQQ2xpZW50EgwKBG5hbWUYASABKAkSFgoJY2xpZW50X2lkGAIgASgJQgPgQQMSGgoNY2xpZW50X3NlY3JldBgDIAEoCUID4EEDIrEIChFJZFBVc2VyQXV0aFBvbGljeRIgChh1c2Vfbm9uX2VtYWlsX2lkZW50aWZpZXIYASABKAgSIQoZYWxsb3dfc2VsZl9wYXNzd29yZF9yZXNldBgCIAEoCBIiChpwYXNzd29yZF9yZXF1aXJlX3VwcGVyY2FzZRgDIAEoCBIiChpwYXNzd29yZF9yZXF1aXJlX2xvd2VyY2FzZRgEIAEoCBIpCiFwYXNzd29yZF9yZXF1aXJlX25vbl9hbHBoYW51bWVyaWMYBSABKAgSIAoYcGFzc3dvcmRfcmVxdWlyZV9udW1lcmljGAYgASgIEqYBChNwYXNzd29yZF9taW5fbGVuZ3RoGAcgASgFQogBukiEAboBgAEKGXBhc3N3b3JkX21pbl9sZW5ndGhfcmFuZ2USO3Bhc3N3b3JkX21pbl9sZW5ndGggbXVzdCBiZSAwIChkZWZhdWx0KSBvciBiZXR3ZWVuIDYgYW5kIDMwGiZ0aGlzID09IDAgfHwgKHRoaXMgPj0gNiAmJiB0aGlzIDw9IDMwKRKqAQoTcGFzc3dvcmRfbWF4X2xlbmd0aBgIIAEoBUKMAbpIiAG6AYQBChlwYXNzd29yZF9tYXhfbGVuZ3RoX3JhbmdlEj1wYXNzd29yZF9tYXhfbGVuZ3RoIG11c3QgYmUgMCAoZGVmYXVsdCkgb3IgYmV0d2VlbiA2IGFuZCA0MDk2Gih0aGlzID09IDAgfHwgKHRoaXMgPj0gNiAmJiB0aGlzIDw9IDQwOTYpEi8KFWFsbG93ZWRfZW1haWxfZG9tYWlucxgJIAMoCUIQukgNkgEKEGQYASIEcgJoATq6A7pItgMa6gEKG3Bhc3N3b3JkX2xlbmd0aF9jb25zaXN0ZW5jeRJFcGFzc3dvcmRfbWluX2xlbmd0aCBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byBwYXNzd29yZF9tYXhfbGVuZ3RoGoMBKHRoaXMucGFzc3dvcmRfbWluX2xlbmd0aCA9PSAwID8gNiA6IHRoaXMucGFzc3dvcmRfbWluX2xlbmd0aCkgPD0gKHRoaXMucGFzc3dvcmRfbWF4X2xlbmd0aCA9PSAwID8gNDA5NiA6IHRoaXMucGFzc3dvcmRfbWF4X2xlbmd0aCkaxgEKL2FsbG93ZWRfZW1haWxfZG9tYWluc19yZXF1aXJlc19lbWFpbF9pZGVudGlmaWVyEklhbGxvd2VkX2VtYWlsX2RvbWFpbnMgY2Fubm90IGJlIHNldCB3aGVuIHVzZV9ub25fZW1haWxfaWRlbnRpZmllciBpcyB0cnVlGkh0aGlzLmFsbG93ZWRfZW1haWxfZG9tYWlucy5zaXplKCkgPT0gMCB8fCAhdGhpcy51c2Vfbm9uX2VtYWlsX2lkZW50aWZpZXIqSAoHSWRQTGFuZxIZChVJRF9QX0xBTkdfVU5TUEVDSUZJRUQQABIQCgxJRF9QX0xBTkdfRU4QARIQCgxJRF9QX0xBTkdfSkEQAmIGcHJvdG8z", [
523
523
  file_buf_validate_validate,
524
524
  file_google_api_field_behavior,
525
525
  file_tailor_v1_resource
@@ -930,7 +930,8 @@ function waitRetryBackoff(attempt) {
930
930
  function isRetirable(error, idempotency) {
931
931
  if (!(error instanceof ConnectError)) return false;
932
932
  switch (error.code) {
933
- case Code.ResourceExhausted | Code.Unavailable: return true;
933
+ case Code.ResourceExhausted:
934
+ case Code.Unavailable: return true;
934
935
  case Code.Internal: return idempotency === MethodOptions_IdempotencyLevel.NO_SIDE_EFFECTS || idempotency === MethodOptions_IdempotencyLevel.IDEMPOTENT;
935
936
  default: return false;
936
937
  }
@@ -3226,39 +3227,6 @@ function createKyselyGenerator(options) {
3226
3227
  };
3227
3228
  }
3228
3229
 
3229
- //#endregion
3230
- //#region src/cli/generator/builtin/seed/gql-ingest-processor.ts
3231
- /**
3232
- * Processes TailorDB types to generate GraphQL Ingest metadata
3233
- * @param type - Parsed TailorDB type
3234
- * @param namespace - Namespace of the type
3235
- * @returns Generated GraphQL Ingest metadata
3236
- */
3237
- function processGqlIngest(type, namespace) {
3238
- const dependencies = Array.from(Object.values(type.fields).reduce((set, field) => {
3239
- if (field.relation?.targetType && field.relation.targetType !== type.name) set.add(field.relation.targetType);
3240
- return set;
3241
- }, /* @__PURE__ */ new Set()));
3242
- const graphql = `mutation Create${type.name}($input: ${type.name}CreateInput!) {
3243
- create${type.name}(input: $input) {
3244
- id
3245
- }
3246
- }
3247
- `;
3248
- return {
3249
- name: type.name,
3250
- namespace,
3251
- dependencies,
3252
- mapping: {
3253
- dataFile: `data/${type.name}.jsonl`,
3254
- dataFormat: "jsonl",
3255
- graphqlFile: `graphql/${type.name}.graphql`,
3256
- mapping: { input: "$" }
3257
- },
3258
- graphql
3259
- };
3260
- }
3261
-
3262
3230
  //#endregion
3263
3231
  //#region src/cli/generator/builtin/seed/idp-user-processor.ts
3264
3232
  /**
@@ -3272,13 +3240,8 @@ function processIdpUser(auth) {
3272
3240
  return {
3273
3241
  name: "_User",
3274
3242
  dependencies: [typeName],
3275
- mapping: {
3276
- dataFile: "data/_User.jsonl",
3277
- dataFormat: "jsonl",
3278
- graphqlFile: "graphql/_User.graphql",
3279
- mapping: { input: "$" }
3280
- },
3281
- graphql: `mutation CreateUser($input: _CreateUserInput!) {
3243
+ dataFile: "data/_User.jsonl",
3244
+ mutation: `mutation CreateUser($input: _CreateUserInput!) {
3282
3245
  _createUser(input: $input) {
3283
3246
  id
3284
3247
  }
@@ -3427,28 +3390,123 @@ function generateLinesDbSchemaFile(metadata, importPath) {
3427
3390
  `;
3428
3391
  }
3429
3392
 
3393
+ //#endregion
3394
+ //#region src/cli/generator/builtin/seed/seed-type-processor.ts
3395
+ /**
3396
+ * Processes TailorDB types to extract seed type information
3397
+ * @param type - Parsed TailorDB type
3398
+ * @param namespace - Namespace of the type
3399
+ * @returns Seed type information
3400
+ */
3401
+ function processSeedTypeInfo(type, namespace) {
3402
+ const dependencies = Array.from(Object.values(type.fields).reduce((set, field) => {
3403
+ const targetType = field.relation?.targetType ?? field.config.foreignKeyType;
3404
+ if (targetType && targetType !== type.name) set.add(targetType);
3405
+ return set;
3406
+ }, /* @__PURE__ */ new Set()));
3407
+ return {
3408
+ name: type.name,
3409
+ namespace,
3410
+ dependencies,
3411
+ dataFile: `data/${type.name}.jsonl`
3412
+ };
3413
+ }
3414
+
3430
3415
  //#endregion
3431
3416
  //#region src/cli/generator/builtin/seed/index.ts
3432
3417
  const SeedGeneratorID = "@tailor-platform/seed";
3433
3418
  /**
3434
- * Generates the exec.mjs script content (Node.js executable) using gql-ingest Programmatic API
3419
+ * Generate the IdP user seed function code
3420
+ * @param hasIdpUser - Whether IdP user is included
3421
+ * @returns JavaScript code for IdP user seeding function
3422
+ */
3423
+ function generateIdpUserSeedFunction(hasIdpUser) {
3424
+ if (!hasIdpUser) return "";
3425
+ return ml`
3426
+ // Seed _User via GraphQL mutation
3427
+ const seedIdpUser = async () => {
3428
+ console.log(styleText("cyan", " Seeding _User via GraphQL mutation..."));
3429
+ const dataDir = join(configDir, "data");
3430
+ const data = loadSeedData(dataDir, ["_User"]);
3431
+ const rows = data["_User"] || [];
3432
+ if (rows.length === 0) {
3433
+ console.log(styleText("dim", " No _User data to seed"));
3434
+ return { success: true };
3435
+ }
3436
+ console.log(styleText("dim", \` Processing _User...\`));
3437
+ const mutation = \`mutation CreateUser($input: _CreateUserInput!) { _createUser(input: $input) { id } }\`;
3438
+ let successCount = 0;
3439
+ let failCount = 0;
3440
+ for (let i = 0; i < rows.length; i++) {
3441
+ try {
3442
+ const response = await fetch(endpoint, {
3443
+ method: "POST",
3444
+ headers: { "Content-Type": "application/json", Authorization: \`Bearer \${tokenInfo.accessToken}\` },
3445
+ body: JSON.stringify({ query: mutation, variables: { input: rows[i] } }),
3446
+ });
3447
+ const result = await response.json();
3448
+ if (result.errors) {
3449
+ failCount++;
3450
+ console.error(styleText("red", \` ✗ Row \${i} in _User failed: \${result.errors[0].message}\`));
3451
+ } else {
3452
+ successCount++;
3453
+ }
3454
+ } catch (error) {
3455
+ failCount++;
3456
+ console.error(styleText("red", \` ✗ Row \${i} in _User failed: \${error.message}\`));
3457
+ }
3458
+ }
3459
+ console.log(styleText("green", \` ✓ _User: \${successCount} rows processed\`));
3460
+ if (failCount > 0) {
3461
+ console.error(styleText("red", \` ✗ _User: \${failCount} rows failed\`));
3462
+ }
3463
+ return { success: failCount === 0 };
3464
+ };
3465
+ `;
3466
+ }
3467
+ /**
3468
+ * Generate the IdP user seed call code
3469
+ * @param hasIdpUser - Whether IdP user is included
3470
+ * @returns JavaScript code for calling IdP user seeding
3471
+ */
3472
+ function generateIdpUserSeedCall(hasIdpUser) {
3473
+ if (!hasIdpUser) return "";
3474
+ return ml`
3475
+ // Seed _User if included and not skipped
3476
+ const shouldSeedUser = !skipIdp && (!entitiesToProcess || entitiesToProcess.includes("_User"));
3477
+ if (hasIdpUser && shouldSeedUser) {
3478
+ const result = await seedIdpUser();
3479
+ if (!result.success) {
3480
+ allSuccess = false;
3481
+ }
3482
+ }
3483
+ `;
3484
+ }
3485
+ /**
3486
+ * Generates the exec.mjs script content using testExecScript API for TailorDB types
3487
+ * and GraphQL mutation for _User (IdP managed)
3435
3488
  * @param machineUserName - Machine user name for token retrieval
3436
3489
  * @param relativeConfigPath - Config path relative to exec script
3437
- * @param entityDependencies - Entity dependencies mapping
3490
+ * @param namespaceConfigs - Namespace configurations with types and dependencies
3491
+ * @param hasIdpUser - Whether _User is included
3438
3492
  * @returns exec.mjs file contents
3439
3493
  */
3440
- function generateExecScript(machineUserName, relativeConfigPath, entityDependencies) {
3441
- const namespaceMap = /* @__PURE__ */ new Map();
3442
- for (const [type, meta] of Object.entries(entityDependencies)) if (meta.namespace) {
3443
- if (!namespaceMap.has(meta.namespace)) namespaceMap.set(meta.namespace, []);
3444
- namespaceMap.get(meta.namespace).push(type);
3445
- }
3494
+ function generateExecScript(machineUserName, relativeConfigPath, namespaceConfigs, hasIdpUser) {
3446
3495
  return ml`
3447
- import { GQLIngest } from "@jackchuka/gql-ingest";
3496
+ import { readFileSync } from "node:fs";
3448
3497
  import { join } from "node:path";
3449
3498
  import { parseArgs, styleText } from "node:util";
3450
3499
  import { createInterface } from "node:readline";
3451
- import { show, getMachineUserToken, truncate } from "@tailor-platform/sdk/cli";
3500
+ import {
3501
+ show,
3502
+ getMachineUserToken,
3503
+ truncate,
3504
+ bundleSeedScript,
3505
+ executeScript,
3506
+ initOperatorClient,
3507
+ loadAccessToken,
3508
+ loadWorkspaceId,
3509
+ } from "@tailor-platform/sdk/cli";
3452
3510
 
3453
3511
  // Parse command-line arguments
3454
3512
  const { values, positionals } = parseArgs({
@@ -3457,6 +3515,7 @@ function generateExecScript(machineUserName, relativeConfigPath, entityDependenc
3457
3515
  "skip-idp": { type: "boolean", default: false },
3458
3516
  truncate: { type: "boolean", default: false },
3459
3517
  yes: { type: "boolean", default: false },
3518
+ profile: { type: "string", short: "p" },
3460
3519
  help: { type: "boolean", short: "h", default: false },
3461
3520
  },
3462
3521
  allowPositionals: true,
@@ -3471,6 +3530,7 @@ function generateExecScript(machineUserName, relativeConfigPath, entityDependenc
3471
3530
  --skip-idp Skip IdP user (_User) entity
3472
3531
  --truncate Truncate tables before seeding
3473
3532
  --yes Skip confirmation prompts (for truncate)
3533
+ -p, --profile <name> Workspace profile name
3474
3534
  -h, --help Show help
3475
3535
 
3476
3536
  Examples:
@@ -3504,15 +3564,19 @@ function generateExecScript(machineUserName, relativeConfigPath, entityDependenc
3504
3564
  const configDir = import.meta.dirname;
3505
3565
  const configPath = join(configDir, "${relativeConfigPath}");
3506
3566
 
3507
- console.log(styleText("cyan", "Starting seed data generation..."));
3508
-
3509
3567
  // Entity configuration
3510
3568
  const namespaceEntities = {
3511
- ${Array.from(namespaceMap.entries()).map(([namespace, entities]) => {
3512
- return ` ${namespace}: [\n${entities.map((e) => ` "${e}",`).join("\n")}\n ]`;
3569
+ ${namespaceConfigs.map(({ namespace, types }) => {
3570
+ return ` "${namespace}": [\n${types.map((e) => ` "${e}",`).join("\n")}\n ]`;
3571
+ }).join(",\n")}
3572
+ };
3573
+ const namespaceDeps = {
3574
+ ${namespaceConfigs.map(({ namespace, dependencies }) => {
3575
+ return ` "${namespace}": {\n${Object.entries(dependencies).map(([type, deps]) => ` "${type}": [${deps.map((d) => `"${d}"`).join(", ")}]`).join(",\n")}\n }`;
3513
3576
  }).join(",\n")}
3514
3577
  };
3515
3578
  const entities = Object.values(namespaceEntities).flat();
3579
+ const hasIdpUser = ${String(hasIdpUser)};
3516
3580
 
3517
3581
  // Determine which entities to process
3518
3582
  let entitiesToProcess = null;
@@ -3552,9 +3616,10 @@ ${Array.from(namespaceMap.entries()).map(([namespace, entities]) => {
3552
3616
  if (hasTypes) {
3553
3617
  const requestedTypes = positionals;
3554
3618
  const notFoundTypes = [];
3619
+ const allTypes = hasIdpUser ? [...entities, "_User"] : entities;
3555
3620
 
3556
3621
  entitiesToProcess = requestedTypes.filter((type) => {
3557
- if (!entities.includes(type)) {
3622
+ if (!allTypes.includes(type)) {
3558
3623
  notFoundTypes.push(type);
3559
3624
  return false;
3560
3625
  }
@@ -3563,7 +3628,7 @@ ${Array.from(namespaceMap.entries()).map(([namespace, entities]) => {
3563
3628
 
3564
3629
  if (notFoundTypes.length > 0) {
3565
3630
  console.error(styleText("red", \`Error: The following types were not found: \${notFoundTypes.join(", ")}\`));
3566
- console.error(styleText("yellow", \`Available types: \${entities.join(", ")}\`));
3631
+ console.error(styleText("yellow", \`Available types: \${allTypes.join(", ")}\`));
3567
3632
  process.exit(1);
3568
3633
  }
3569
3634
 
@@ -3573,106 +3638,229 @@ ${Array.from(namespaceMap.entries()).map(([namespace, entities]) => {
3573
3638
  // Apply --skip-idp filter
3574
3639
  if (skipIdp) {
3575
3640
  if (entitiesToProcess) {
3576
- // Filter out _User from already filtered list
3577
3641
  entitiesToProcess = entitiesToProcess.filter((entity) => entity !== "_User");
3578
3642
  } else {
3579
- // Get all entities except _User
3580
3643
  entitiesToProcess = entities.filter((entity) => entity !== "_User");
3581
3644
  }
3582
- console.log(styleText("dim", \`Skipping IdP user (_User)\`));
3583
3645
  }
3584
3646
 
3585
3647
  // Truncate tables if requested
3586
- // Note: --skip-idp only affects seeding, not truncation
3587
3648
  if (values.truncate) {
3588
- // Prompt user for confirmation
3589
3649
  const answer = values.yes ? "y" : await promptConfirmation("Are you sure you want to truncate? (y/n): ");
3590
3650
  if (answer !== "y") {
3591
3651
  console.log(styleText("yellow", "Truncate cancelled."));
3592
3652
  process.exit(0);
3593
3653
  }
3594
3654
 
3595
- console.log(styleText("cyan", "\\nTruncating tables..."));
3655
+ console.log(styleText("cyan", "Truncating tables..."));
3596
3656
 
3597
3657
  try {
3598
3658
  if (hasNamespace) {
3599
- // Truncate specific namespace
3600
3659
  await truncate({
3601
3660
  configPath,
3661
+ profile: values.profile,
3602
3662
  namespace: values.namespace,
3603
3663
  });
3604
3664
  } else if (hasTypes) {
3605
- // Truncate specific types
3606
- await truncate({
3607
- configPath,
3608
- types: entitiesToProcess,
3609
- });
3665
+ const typesToTruncate = entitiesToProcess.filter((t) => t !== "_User");
3666
+ if (typesToTruncate.length > 0) {
3667
+ await truncate({
3668
+ configPath,
3669
+ profile: values.profile,
3670
+ types: typesToTruncate,
3671
+ });
3672
+ } else {
3673
+ console.log(styleText("dim", "No TailorDB types to truncate (only _User was specified)."));
3674
+ }
3610
3675
  } else {
3611
- // Truncate all (--skip-idp does not affect truncation)
3612
3676
  await truncate({
3613
3677
  configPath,
3678
+ profile: values.profile,
3614
3679
  all: true,
3615
3680
  });
3616
3681
  }
3617
- console.log(styleText("green", "Truncate completed.\\n"));
3682
+ console.log(styleText("green", "Truncate completed."));
3618
3683
  } catch (error) {
3619
3684
  console.error(styleText("red", \`Truncate failed: \${error.message}\`));
3620
3685
  process.exit(1);
3621
3686
  }
3622
3687
  }
3623
3688
 
3624
- // Get application info and endpoint
3625
- const appInfo = await show({ configPath });
3689
+ console.log(styleText("cyan", "\\nStarting seed data generation..."));
3690
+ if (skipIdp) {
3691
+ console.log(styleText("dim", \` Skipping IdP user (_User)\`));
3692
+ }
3693
+
3694
+ // Get application info
3695
+ const appInfo = await show({ configPath, profile: values.profile });
3626
3696
  const endpoint = \`\${appInfo.url}/query\`;
3697
+ const authNamespace = appInfo.auth;
3627
3698
 
3628
3699
  // Get machine user token
3629
- const tokenInfo = await getMachineUserToken({ name: "${machineUserName}", configPath });
3630
-
3631
- // Initialize GQLIngest client
3632
- const client = new GQLIngest({
3633
- endpoint,
3634
- headers: {
3635
- Authorization: \`Bearer \${tokenInfo.accessToken}\`,
3636
- },
3700
+ const tokenInfo = await getMachineUserToken({
3701
+ name: "${machineUserName}",
3702
+ configPath,
3703
+ profile: values.profile,
3637
3704
  });
3638
3705
 
3639
- // Progress monitoring event handlers
3640
- client.on("started", (payload) => {
3641
- console.log(styleText("cyan", \`Processing \${payload.totalEntities} entities...\`));
3642
- });
3706
+ // Load seed data from JSONL files
3707
+ const loadSeedData = (dataDir, typeNames) => {
3708
+ const data = {};
3709
+ for (const typeName of typeNames) {
3710
+ const jsonlPath = join(dataDir, \`\${typeName}.jsonl\`);
3711
+ try {
3712
+ const content = readFileSync(jsonlPath, "utf-8").trim();
3713
+ if (content) {
3714
+ data[typeName] = content.split("\\n").map((line) => JSON.parse(line));
3715
+ } else {
3716
+ data[typeName] = [];
3717
+ }
3718
+ } catch (error) {
3719
+ if (error.code === "ENOENT") {
3720
+ data[typeName] = [];
3721
+ } else {
3722
+ throw error;
3723
+ }
3724
+ }
3725
+ }
3726
+ return data;
3727
+ };
3643
3728
 
3644
- client.on("entityStart", (payload) => {
3645
- console.log(styleText("dim", \` Processing \${payload.entityName}...\`));
3646
- });
3729
+ // Topological sort for dependency order
3730
+ const topologicalSort = (types, deps) => {
3731
+ const visited = new Set();
3732
+ const result = [];
3733
+
3734
+ const visit = (type) => {
3735
+ if (visited.has(type)) return;
3736
+ visited.add(type);
3737
+ const typeDeps = deps[type] || [];
3738
+ for (const dep of typeDeps) {
3739
+ if (types.includes(dep)) {
3740
+ visit(dep);
3741
+ }
3742
+ }
3743
+ result.push(type);
3744
+ };
3647
3745
 
3648
- client.on("entityComplete", (payload) => {
3649
- const { entityName, metrics: { rowsProcessed } } = payload;
3650
- console.log(styleText("green", \` ✓ \${entityName}: \${rowsProcessed} rows processed\`));
3651
- });
3746
+ for (const type of types) {
3747
+ visit(type);
3748
+ }
3749
+ return result;
3750
+ };
3652
3751
 
3653
- client.on("rowFailure", (payload) => {
3654
- console.error(styleText("red", \` ✗ Row \${payload.rowIndex} in \${payload.entityName} failed: \${payload.error.message}\`));
3655
- });
3752
+ // Initialize operator client (once for all namespaces)
3753
+ const accessToken = await loadAccessToken({ profile: values.profile, useProfile: true });
3754
+ const workspaceId = await loadWorkspaceId({ profile: values.profile });
3755
+ const operatorClient = await initOperatorClient(accessToken);
3756
+
3757
+ // Seed TailorDB types via testExecScript
3758
+ const seedViaTestExecScript = async (namespace, typesToSeed, deps) => {
3759
+ const dataDir = join(configDir, "data");
3760
+ const sortedTypes = topologicalSort(typesToSeed, deps);
3761
+ const data = loadSeedData(dataDir, sortedTypes);
3762
+
3763
+ // Skip if no data
3764
+ const typesWithData = sortedTypes.filter((t) => data[t] && data[t].length > 0);
3765
+ if (typesWithData.length === 0) {
3766
+ console.log(styleText("dim", \` [\${namespace}] No data to seed\`));
3767
+ return { success: true, processed: {} };
3768
+ }
3656
3769
 
3657
- // Run ingestion
3658
- try {
3659
- let result;
3660
- if (entitiesToProcess && entitiesToProcess.length > 0) {
3661
- result = await client.ingestEntities(configDir, entitiesToProcess);
3662
- } else {
3663
- result = await client.ingest(configDir);
3770
+ console.log(styleText("cyan", \` [\${namespace}] Seeding \${typesWithData.length} types via Kysely batch insert...\`));
3771
+
3772
+ // Bundle seed script
3773
+ const bundled = await bundleSeedScript(namespace, typesWithData);
3774
+
3775
+ // Execute seed script
3776
+ const result = await executeScript({
3777
+ client: operatorClient,
3778
+ workspaceId,
3779
+ name: \`seed-\${namespace}.ts\`,
3780
+ code: bundled.bundledCode,
3781
+ arg: JSON.stringify({ data, order: sortedTypes }),
3782
+ invoker: {
3783
+ namespace: authNamespace,
3784
+ machineUserName: "${machineUserName}",
3785
+ },
3786
+ });
3787
+
3788
+ // Parse result and display logs
3789
+ if (result.logs) {
3790
+ for (const line of result.logs.split("\\n").filter(Boolean)) {
3791
+ console.log(styleText("dim", \` \${line}\`));
3792
+ }
3664
3793
  }
3665
3794
 
3666
3795
  if (result.success) {
3796
+ let parsed;
3797
+ try {
3798
+ const parsedResult = JSON.parse(result.result || "{}");
3799
+ parsed = parsedResult && typeof parsedResult === "object" ? parsedResult : {};
3800
+ } catch (error) {
3801
+ const message = error instanceof Error ? error.message : String(error);
3802
+ console.error(styleText("red", \` ✗ Failed to parse seed result: \${message}\`));
3803
+ return { success: false, error: message };
3804
+ }
3805
+
3806
+ const processed = parsed.processed || {};
3807
+ for (const [type, count] of Object.entries(processed)) {
3808
+ console.log(styleText("green", \` ✓ \${type}: \${count} rows inserted\`));
3809
+ }
3810
+
3811
+ if (!parsed.success) {
3812
+ const errors = Array.isArray(parsed.errors) ? parsed.errors : [];
3813
+ const errorMessage =
3814
+ errors.length > 0 ? errors.join("\\n") : "Seed script reported failure";
3815
+ console.error(styleText("red", \` ✗ Seed failed: \${errorMessage}\`));
3816
+ return { success: false, error: errorMessage };
3817
+ }
3818
+
3819
+ return { success: true, processed };
3820
+ } else {
3821
+ console.error(styleText("red", \` ✗ Seed failed: \${result.error}\`));
3822
+ return { success: false, error: result.error };
3823
+ }
3824
+ };
3825
+
3826
+ ${generateIdpUserSeedFunction(hasIdpUser)}
3827
+
3828
+ // Main execution
3829
+ try {
3830
+ let allSuccess = true;
3831
+
3832
+ // Determine which namespaces and types to process
3833
+ const namespacesToProcess = hasNamespace
3834
+ ? [values.namespace]
3835
+ : Object.keys(namespaceEntities);
3836
+
3837
+ for (const namespace of namespacesToProcess) {
3838
+ const nsTypes = namespaceEntities[namespace] || [];
3839
+ const nsDeps = namespaceDeps[namespace] || {};
3840
+
3841
+ // Filter types if specific types requested
3842
+ let typesToSeed = entitiesToProcess
3843
+ ? nsTypes.filter((t) => entitiesToProcess.includes(t))
3844
+ : nsTypes;
3845
+
3846
+ if (typesToSeed.length === 0) continue;
3847
+
3848
+ const result = await seedViaTestExecScript(namespace, typesToSeed, nsDeps);
3849
+ if (!result.success) {
3850
+ allSuccess = false;
3851
+ }
3852
+ }
3853
+
3854
+ ${generateIdpUserSeedCall(hasIdpUser)}
3855
+
3856
+ if (allSuccess) {
3667
3857
  console.log(styleText("green", "\\n✓ Seed data generation completed successfully"));
3668
- console.log(client.getMetricsSummary());
3669
3858
  } else {
3670
- console.error(styleText("red", "\\n✗ Seed data generation failed"));
3671
- console.error(client.getMetricsSummary());
3859
+ console.error(styleText("red", "\\n✗ Seed data generation completed with errors"));
3672
3860
  process.exit(1);
3673
3861
  }
3674
3862
  } catch (error) {
3675
- console.error(styleText("red", \`\\n✗ Seed data generation failed with error: \${error.message}\`));
3863
+ console.error(styleText("red", \`\\n✗ Seed data generation failed: \${error.message}\`));
3676
3864
  process.exit(1);
3677
3865
  }
3678
3866
 
@@ -3680,45 +3868,38 @@ ${Array.from(namespaceMap.entries()).map(([namespace, entities]) => {
3680
3868
  }
3681
3869
  /**
3682
3870
  * Factory function to create a Seed generator.
3683
- * Combines GraphQL Ingest and lines-db schema generation.
3871
+ * Combines Kysely batch insert and lines-db schema generation.
3684
3872
  * @param options - Seed generator options
3685
3873
  * @returns Seed generator
3686
3874
  */
3687
3875
  function createSeedGenerator(options) {
3688
3876
  return {
3689
3877
  id: SeedGeneratorID,
3690
- description: "Generates seed data files (GraphQL Ingest + lines-db schema)",
3878
+ description: "Generates seed data files (Kysely batch insert + GraphQL mutation for _User)",
3691
3879
  dependencies: ["tailordb"],
3692
3880
  processType: ({ type, source, namespace }) => {
3693
3881
  return {
3694
- gqlIngest: processGqlIngest(type, namespace),
3882
+ typeInfo: processSeedTypeInfo(type, namespace),
3695
3883
  linesDb: processLinesDb(type, source)
3696
3884
  };
3697
3885
  },
3698
3886
  processTailorDBNamespace: ({ types }) => types,
3699
3887
  aggregate: ({ input, configPath }) => {
3700
- const entityDependencies = {};
3701
3888
  const files = [];
3889
+ const namespaceConfigs = [];
3702
3890
  for (const nsResult of input.tailordb) {
3703
3891
  if (!nsResult.types) continue;
3704
3892
  const outputBaseDir = options.distPath;
3705
- if (!(outputBaseDir in entityDependencies)) entityDependencies[outputBaseDir] = {};
3893
+ const types = [];
3894
+ const dependencies = {};
3706
3895
  for (const [_typeName, metadata] of Object.entries(nsResult.types)) {
3707
- const { gqlIngest, linesDb } = metadata;
3708
- entityDependencies[outputBaseDir][gqlIngest.name] = {
3709
- namespace: gqlIngest.namespace,
3710
- dependencies: gqlIngest.dependencies
3711
- };
3896
+ const { typeInfo, linesDb } = metadata;
3897
+ types.push(typeInfo.name);
3898
+ dependencies[typeInfo.name] = typeInfo.dependencies;
3712
3899
  files.push({
3713
- path: path.join(outputBaseDir, "mappings", `${gqlIngest.name}.json`),
3714
- content: JSON.stringify(gqlIngest.mapping, null, 2) + "\n"
3715
- }, {
3716
- path: path.join(outputBaseDir, gqlIngest.mapping.dataFile),
3900
+ path: path.join(outputBaseDir, typeInfo.dataFile),
3717
3901
  content: "",
3718
3902
  skipIfExists: true
3719
- }, {
3720
- path: path.join(outputBaseDir, gqlIngest.mapping.graphqlFile),
3721
- content: gqlIngest.graphql
3722
3903
  });
3723
3904
  const schemaOutputPath = path.join(outputBaseDir, "data", `${linesDb.typeName}.schema.ts`);
3724
3905
  const importPath = path.relative(path.dirname(schemaOutputPath), linesDb.importPath);
@@ -3728,46 +3909,32 @@ function createSeedGenerator(options) {
3728
3909
  content: generateLinesDbSchemaFile(linesDb, normalizedImportPath)
3729
3910
  });
3730
3911
  }
3912
+ namespaceConfigs.push({
3913
+ namespace: nsResult.namespace,
3914
+ types,
3915
+ dependencies
3916
+ });
3731
3917
  }
3732
- if (input.auth) {
3733
- const idpUser = processIdpUser(input.auth);
3734
- if (idpUser) {
3735
- const outputBaseDir = options.distPath;
3736
- if (!(outputBaseDir in entityDependencies)) entityDependencies[outputBaseDir] = {};
3737
- entityDependencies[outputBaseDir][idpUser.name] = { dependencies: idpUser.dependencies };
3738
- files.push({
3739
- path: path.join(outputBaseDir, idpUser.mapping.graphqlFile),
3740
- content: idpUser.graphql
3741
- });
3742
- files.push({
3743
- path: path.join(outputBaseDir, "mappings", `${idpUser.name}.json`),
3744
- content: JSON.stringify(idpUser.mapping, null, 2) + "\n"
3745
- });
3746
- files.push({
3747
- path: path.join(outputBaseDir, idpUser.mapping.dataFile),
3748
- content: "",
3749
- skipIfExists: true
3750
- });
3751
- files.push({
3752
- path: path.join(outputBaseDir, "data", `${idpUser.name}.schema.ts`),
3753
- content: generateIdpUserSchemaFile(idpUser.schema.usernameField, idpUser.schema.userTypeName)
3754
- });
3755
- }
3918
+ const idpUser = input.auth ? processIdpUser(input.auth) : null;
3919
+ const hasIdpUser = idpUser !== null;
3920
+ if (idpUser) {
3921
+ const outputBaseDir = options.distPath;
3922
+ files.push({
3923
+ path: path.join(outputBaseDir, idpUser.dataFile),
3924
+ content: "",
3925
+ skipIfExists: true
3926
+ });
3927
+ files.push({
3928
+ path: path.join(outputBaseDir, "data", `${idpUser.name}.schema.ts`),
3929
+ content: generateIdpUserSchemaFile(idpUser.schema.usernameField, idpUser.schema.userTypeName)
3930
+ });
3756
3931
  }
3757
- for (const [outputDir, dependencies] of Object.entries(entityDependencies)) {
3932
+ if (options.machineUserName) {
3933
+ const relativeConfigPath = path.relative(options.distPath, configPath);
3758
3934
  files.push({
3759
- path: path.join(outputDir, "config.yaml"),
3760
- content: `entityDependencies:
3761
- ${Object.entries(dependencies).map(([type, deps]) => `${type}: [${deps.dependencies.join(", ")}]`).join("\n ")}
3762
- `
3935
+ path: path.join(options.distPath, "exec.mjs"),
3936
+ content: generateExecScript(options.machineUserName, relativeConfigPath, namespaceConfigs, hasIdpUser)
3763
3937
  });
3764
- if (options.machineUserName) {
3765
- const relativeConfigPath = path.relative(outputDir, configPath);
3766
- files.push({
3767
- path: path.join(outputDir, "exec.mjs"),
3768
- content: generateExecScript(options.machineUserName, relativeConfigPath, dependencies)
3769
- });
3770
- }
3771
3938
  }
3772
3939
  return { files };
3773
3940
  }
@@ -11890,7 +12057,7 @@ async function generate(options) {
11890
12057
  return;
11891
12058
  }
11892
12059
  if (options.init) await handleInitOption(namespacesWithMigrations, options.yes);
11893
- const { defineApplication: defineApplication$1 } = await import("./application-BdZ8qL7I.mjs");
12060
+ const { defineApplication: defineApplication$1 } = await import("./application-COnpGp0d.mjs");
11894
12061
  const application = defineApplication$1(config);
11895
12062
  for (const { namespace, migrationsDir } of namespacesWithMigrations) {
11896
12063
  logger.info(`Processing namespace: ${styles.bold(namespace)}`);
@@ -13096,5 +13263,5 @@ const updateCommand = defineCommand({
13096
13263
  });
13097
13264
 
13098
13265
  //#endregion
13099
- export { startWorkflow as $, generateCommand as A, trnPrefix as At, getMachineUserToken as B, fetchAll as Bt, resumeCommand as C, isValidMigrationNumber as Ct, truncate as D, formatMigrationDiff as Dt, listWorkflows as E, formatDiffSummary as Et, removeCommand$1 as F, fetchLatestToken as Ft, generateCommand$1 as G, PATScope as Gt, listCommand$5 as H, initOAuth2Client as Ht, listCommand$4 as I, loadAccessToken as It, getExecutorJob as J, deploymentArgs as Jt, triggerCommand as K, commonArgs as Kt, listOAuth2Clients as L, loadWorkspaceId as Lt, show as M, loadConfig as Mt, showCommand as N, apiCall as Nt, truncateCommand as O, hasChanges as Ot, remove as P, apiCommand as Pt, startCommand as Q, getCommand$1 as R, readPlatformConfig as Rt, healthCommand as S, getNextMigrationNumber as St, listCommand$3 as T, reconstructSnapshotFromMigrations as Tt, listMachineUsers as U, initOperatorClient as Ut, tokenCommand as V, fetchUserInfo as Vt, generate$1 as W, readPackageJson as Wt, listExecutorJobs as X, withCommonArgs as Xt, jobsCommand as Y, jsonArgs as Yt, watchExecutorJob as Z, workspaceArgs as Zt, createCommand as _, formatMigrationNumber as _t, listCommand as a, apply as at, listCommand$2 as b, getMigrationFilePath as bt, inviteUser as c, parseMigrationLabelNumber as ct, listCommand$1 as d, INITIAL_SCHEMA_NUMBER as dt, getCommand$2 as et, listWorkspaces as f, MIGRATE_FILE_NAME as ft, deleteWorkspace as g, createSnapshotFromLocalTypes as gt, deleteCommand as h, compareSnapshots as ht, removeUser as i, listWorkflowExecutions as it, logBetaWarning as j, generateUserTypes as jt, generate as k, getNamespacesWithMigrations as kt, restoreCommand as l, DB_TYPES_FILE_NAME as lt, getWorkspace as m, compareLocalTypesWithSnapshot as mt, updateUser as n, executionsCommand as nt, listUsers as o, applyCommand as ot, getCommand as p, SCHEMA_FILE_NAME as pt, triggerExecutor as q, confirmationArgs as qt, removeCommand as r, getWorkflowExecution as rt, inviteCommand as s, MIGRATION_LABEL_KEY as st, updateCommand as t, getWorkflow as tt, restoreWorkspace as u, DIFF_FILE_NAME as ut, createWorkspace as v, getLatestMigrationNumber as vt, resumeWorkflow as w, loadDiff as wt, getAppHealth as x, getMigrationFiles as xt, listApps as y, getMigrationDirPath as yt, getOAuth2Client as z, writePlatformConfig as zt };
13100
- //# sourceMappingURL=update-DZs1loy_.mjs.map
13266
+ export { startWorkflow as $, withCommonArgs as $t, generateCommand as A, hasChanges as At, getMachineUserToken as B, loadWorkspaceId as Bt, resumeCommand as C, getMigrationFiles as Ct, truncate as D, reconstructSnapshotFromMigrations as Dt, listWorkflows as E, loadDiff as Et, removeCommand$1 as F, getDistDir as Ft, generateCommand$1 as G, initOAuth2Client as Gt, listCommand$5 as H, writePlatformConfig as Ht, listCommand$4 as I, apiCall as It, getExecutorJob as J, PATScope as Jt, triggerCommand as K, initOperatorClient as Kt, listOAuth2Clients as L, apiCommand as Lt, show as M, trnPrefix as Mt, showCommand as N, generateUserTypes as Nt, truncateCommand as O, formatDiffSummary as Ot, remove as P, loadConfig as Pt, startCommand as Q, jsonArgs as Qt, getCommand$1 as R, fetchLatestToken as Rt, healthCommand as S, getMigrationFilePath as St, listCommand$3 as T, isValidMigrationNumber as Tt, listMachineUsers as U, fetchAll as Ut, tokenCommand as V, readPlatformConfig as Vt, generate$1 as W, fetchUserInfo as Wt, listExecutorJobs as X, confirmationArgs as Xt, jobsCommand as Y, commonArgs as Yt, watchExecutorJob as Z, deploymentArgs as Zt, createCommand as _, compareSnapshots as _t, listCommand as a, apply as at, listCommand$2 as b, getLatestMigrationNumber as bt, inviteUser as c, waitForExecution$1 as ct, listCommand$1 as d, DB_TYPES_FILE_NAME as dt, workspaceArgs as en, getCommand$2 as et, listWorkspaces as f, DIFF_FILE_NAME as ft, deleteWorkspace as g, compareLocalTypesWithSnapshot as gt, deleteCommand as h, SCHEMA_FILE_NAME as ht, removeUser as i, listWorkflowExecutions as it, logBetaWarning as j, getNamespacesWithMigrations as jt, generate as k, formatMigrationDiff as kt, restoreCommand as l, MIGRATION_LABEL_KEY as lt, getWorkspace as m, MIGRATE_FILE_NAME as mt, updateUser as n, executionsCommand as nt, listUsers as o, applyCommand as ot, getCommand as p, INITIAL_SCHEMA_NUMBER as pt, triggerExecutor as q, readPackageJson as qt, removeCommand as r, getWorkflowExecution as rt, inviteCommand as s, executeScript as st, updateCommand as t, getWorkflow as tt, restoreWorkspace as u, parseMigrationLabelNumber as ut, createWorkspace as v, createSnapshotFromLocalTypes as vt, resumeWorkflow as w, getNextMigrationNumber as wt, getAppHealth as x, getMigrationDirPath as xt, listApps as y, formatMigrationNumber as yt, getOAuth2Client as z, loadAccessToken as zt };
13267
+ //# sourceMappingURL=update-C877GWkA.mjs.map