@tailor-platform/sdk 2.2.0 → 2.4.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.
Files changed (117) hide show
  1. package/CHANGELOG.md +183 -0
  2. package/README.md +1 -1
  3. package/dist/{application-BpLeawBg.mjs → application-C8a0UJ-z.mjs} +312 -166
  4. package/dist/application-C8a0UJ-z.mjs.map +1 -0
  5. package/dist/application-D4zOiLLa.mjs +3 -0
  6. package/dist/cli/commands/tailordb/migrate/diff-calculator.d.mts +47 -24
  7. package/dist/cli/commands/tailordb/migrate/generate.d.mts +6 -0
  8. package/dist/cli/commands/tailordb/migrate/rename-detection.d.mts +22 -0
  9. package/dist/cli/commands/tailordb/migrate/snapshot-types.d.mts +1 -1
  10. package/dist/cli/commands/tailordb/migrate/snapshot.d.mts +30 -11
  11. package/dist/cli/commands/tailordb/truncate.d.mts +2 -2
  12. package/dist/cli/lib.mjs +2 -2
  13. package/dist/cli/lib.mjs.map +1 -1
  14. package/dist/cli/main.mjs +366 -137
  15. package/dist/cli/main.mjs.map +1 -1
  16. package/dist/cli/ts-hook.mjs +55 -8
  17. package/dist/completion/zsh-worker.zsh +38 -10
  18. package/dist/configure/config/index.d.mts +1 -1
  19. package/dist/configure/index.d.mts +3 -2
  20. package/dist/configure/index.mjs +92 -25
  21. package/dist/configure/index.mjs.map +1 -1
  22. package/dist/configure/services/aigateway/index.d.mts +5 -4
  23. package/dist/configure/services/aigateway/types.d.mts +6 -1
  24. package/dist/configure/services/auth/types.d.mts +2 -2
  25. package/dist/configure/services/index.d.mts +2 -2
  26. package/dist/configure/services/tailordb/permission.d.mts +1 -1
  27. package/dist/configure/services/tailordb/schema.d.mts +1 -1
  28. package/dist/configure/services/tailordb/types.d.mts +7 -4
  29. package/dist/configure/services/workflow/index.d.mts +2 -2
  30. package/dist/configure/services/workflow/wait-point.d.mts +72 -13
  31. package/dist/configure/types/auth-namespace-name.d.mts +18 -0
  32. package/dist/{crashreport-CINZ5dVN.mjs → crashreport-Cd4TqfZq.mjs} +1 -1
  33. package/dist/{crashreport-CIIfLnoO.mjs → crashreport-Q0pDAlrj.mjs} +8 -4
  34. package/dist/{crashreport-CIIfLnoO.mjs.map → crashreport-Q0pDAlrj.mjs.map} +1 -1
  35. package/dist/{errors-CWj21238.mjs → errors-Bxut5_Sy.mjs} +17 -3
  36. package/dist/{errors-CWj21238.mjs.map → errors-Bxut5_Sy.mjs.map} +1 -1
  37. package/dist/file-BUcmVIH2.mjs.map +1 -1
  38. package/dist/kysely/index.d.mts +2 -1
  39. package/dist/kysely/index.mjs +2 -1
  40. package/dist/kysely/index.mjs.map +1 -1
  41. package/dist/{logger-DSdExfor.mjs → logger-D0bEznPv.mjs} +9 -5
  42. package/dist/{logger-DSdExfor.mjs.map → logger-D0bEznPv.mjs.map} +1 -1
  43. package/dist/package-json-8b0O9TlX.mjs.map +1 -1
  44. package/dist/plugin/builtin/enum-constants/index.d.mts +1 -1
  45. package/dist/plugin/builtin/enum-constants/index.mjs +5 -5
  46. package/dist/plugin/builtin/enum-constants/index.mjs.map +1 -1
  47. package/dist/plugin/builtin/file-utils/index.d.mts +1 -1
  48. package/dist/plugin/builtin/file-utils/index.mjs +14 -11
  49. package/dist/plugin/builtin/file-utils/index.mjs.map +1 -1
  50. package/dist/plugin/builtin/kysely-type/index.d.mts +1 -1
  51. package/dist/plugin/builtin/kysely-type/index.mjs +9 -9
  52. package/dist/plugin/builtin/kysely-type/index.mjs.map +1 -1
  53. package/dist/plugin/builtin/seed/index.mjs +1 -1
  54. package/dist/plugin/builtin/seed/seed-type-processor.d.mts +4 -4
  55. package/dist/plugin/get-generated-type.d.mts +4 -4
  56. package/dist/plugin/index.mjs +13 -13
  57. package/dist/plugin/index.mjs.map +1 -1
  58. package/dist/plugin/types.d.mts +2 -2
  59. package/dist/plugin/with-context.d.mts +1 -1
  60. package/dist/{register-ts-hook-CTth1eqj.mjs → register-ts-hook-Vqjza10T.mjs} +2516 -857
  61. package/dist/register-ts-hook-Vqjza10T.mjs.map +1 -0
  62. package/dist/{repl-editor-BCozyiNq.mjs → repl-editor-F9LotMNx.mjs} +3 -2
  63. package/dist/{repl-editor-BCozyiNq.mjs.map → repl-editor-F9LotMNx.mjs.map} +1 -1
  64. package/dist/runtime/file.d.mts +14 -14
  65. package/dist/{schema--xYWRGfe.mjs → schema-D4TC4BC3.mjs} +4 -3
  66. package/dist/schema-D4TC4BC3.mjs.map +1 -0
  67. package/dist/seed/index.d.mts +4 -4
  68. package/dist/seed/index.mjs +3 -3
  69. package/dist/seed/index.mjs.map +1 -1
  70. package/dist/{seed-xqM9WIHP.mjs → seed-Cibjmtry.mjs} +46 -40
  71. package/dist/seed-Cibjmtry.mjs.map +1 -0
  72. package/dist/{service-goqlJJgA.mjs → service-2grcAOCJ.mjs} +61 -27
  73. package/dist/service-2grcAOCJ.mjs.map +1 -0
  74. package/dist/service-CaBPNDIZ.mjs +3 -0
  75. package/dist/{service-CCwl3Avt.mjs → service-LTfp03ZZ.mjs} +7 -5
  76. package/dist/{service-CCwl3Avt.mjs.map → service-LTfp03ZZ.mjs.map} +1 -1
  77. package/dist/types/aigateway.generated.d.mts +2 -2
  78. package/dist/types/auth.generated.d.mts +3 -3
  79. package/dist/types/executor.generated.d.mts +1 -1
  80. package/dist/types/tailordb.generated.d.mts +12 -12
  81. package/dist/utils/test/index.d.mts +4 -4
  82. package/dist/utils/test/index.mjs +4 -4
  83. package/dist/utils/test/index.mjs.map +1 -1
  84. package/dist/vitest/index.mjs +95 -7
  85. package/dist/vitest/index.mjs.map +1 -1
  86. package/dist/vitest/mocks/workflow.d.mts +13 -1
  87. package/dist/wait-point-invoker-__oE88_P.mjs +148 -0
  88. package/dist/wait-point-invoker-__oE88_P.mjs.map +1 -0
  89. package/dist/wait-point-registry-TL99zotw.mjs +47 -0
  90. package/dist/wait-point-registry-TL99zotw.mjs.map +1 -0
  91. package/docs/cli/application.md +3 -1
  92. package/docs/cli/function.md +17 -13
  93. package/docs/cli/setup.md +14 -1
  94. package/docs/cli/tailordb.md +30 -27
  95. package/docs/cli/workspace.md +2 -2
  96. package/docs/cli-reference.md +23 -22
  97. package/docs/configuration.md +2 -2
  98. package/docs/github-actions.md +73 -28
  99. package/docs/migration/v2.md +58 -4
  100. package/docs/migration/v3.md +41 -0
  101. package/docs/quickstart.md +1 -1
  102. package/docs/services/aigateway.md +33 -9
  103. package/docs/services/executor.md +5 -1
  104. package/docs/services/tailordb-migration.md +146 -44
  105. package/docs/services/tailordb.md +7 -7
  106. package/docs/services/workflow.md +52 -2
  107. package/docs/testing.md +13 -1
  108. package/package.json +8 -8
  109. package/dist/application-BpLeawBg.mjs.map +0 -1
  110. package/dist/application-BxLLiLsr.mjs +0 -3
  111. package/dist/register-ts-hook-CTth1eqj.mjs.map +0 -1
  112. package/dist/schema--xYWRGfe.mjs.map +0 -1
  113. package/dist/seed-xqM9WIHP.mjs.map +0 -1
  114. package/dist/service-_XmjSEGr.mjs +0 -3
  115. package/dist/service-goqlJJgA.mjs.map +0 -1
  116. package/dist/test-env-key-D7UkZp99.mjs +0 -75
  117. package/dist/test-env-key-D7UkZp99.mjs.map +0 -1
@@ -153,23 +153,7 @@ function generateIdpTruncateScriptCode(idpNamespace) {
153
153
  */
154
154
  function generateIdpUserSchemaFile(options) {
155
155
  const { usernameField, userTypeName, includeUserProfileFK = true } = options;
156
- return multiline`
157
- import { t } from "@tailor-platform/sdk";
158
- import { defineSchema } from "@tailor-platform/sdk/seed";
159
- import { createStandardSchema } from "@tailor-platform/sdk/test";
160
-
161
- const schemaType = t.object({
162
- name: t.string(),
163
- password: t.string(),
164
- });
165
-
166
- // Simple identity hook for _User (no TailorDB backing type)
167
- export const hook = <T>(data: unknown) => data as T;
168
-
169
- export const schema = defineSchema(
170
- createStandardSchema(schemaType, hook),
171
- {
172
- ${includeUserProfileFK ? multiline`
156
+ const schemaBody = includeUserProfileFK ? multiline`
173
157
  primaryKey: "name",
174
158
  indexes: [
175
159
  { name: "_user_name_unique_idx", columns: ["name"], unique: true },
@@ -188,7 +172,24 @@ function generateIdpUserSchemaFile(options) {
188
172
  indexes: [
189
173
  { name: "_user_name_unique_idx", columns: ["name"], unique: true },
190
174
  ],
191
- `}
175
+ `;
176
+ return multiline`
177
+ import { t } from "@tailor-platform/sdk";
178
+ import { defineSchema } from "@tailor-platform/sdk/seed";
179
+ import { createStandardSchema } from "@tailor-platform/sdk/test";
180
+
181
+ const schemaType = t.object({
182
+ name: t.string(),
183
+ password: t.string(),
184
+ });
185
+
186
+ // Simple identity hook for _User (no TailorDB backing table)
187
+ export const hook = <T>(data: unknown) => data as T;
188
+
189
+ export const schema = defineSchema(
190
+ createStandardSchema(schemaType, hook),
191
+ {
192
+ ${schemaBody}
192
193
  }
193
194
  );
194
195
 
@@ -198,15 +199,15 @@ function generateIdpUserSchemaFile(options) {
198
199
  //#endregion
199
200
  //#region src/plugin/builtin/seed/lines-db-processor.ts
200
201
  /**
201
- * Processes TailorDB types to generate lines-db metadata
202
- * @param type - Parsed TailorDB type
202
+ * Processes TailorDB tables to generate lines-db metadata
203
+ * @param type - Parsed TailorDB table
203
204
  * @param source - Source file info
204
205
  * @returns Generated lines-db metadata
205
206
  */
206
207
  function processLinesDb(type, source) {
207
208
  if (isPluginGeneratedType(source)) return processLinesDbForPluginType(type, source);
208
- if (!source.filePath) throw new Error(`Missing source info for type ${type.name}`);
209
- if (!source.exportName) throw new Error(`Missing export name for type ${type.name}`);
209
+ if (!source.filePath) throw new Error(`Missing source info for table ${type.name}`);
210
+ if (!source.exportName) throw new Error(`Missing export name for table ${type.name}`);
210
211
  const { optionalFields, omitFields, indexes, foreignKeys } = extractFieldMetadata(type);
211
212
  return {
212
213
  typeName: type.name,
@@ -220,8 +221,8 @@ function processLinesDb(type, source) {
220
221
  }
221
222
  /**
222
223
  * Process lines-db metadata for plugin-generated types
223
- * @param type - Parsed TailorDB type
224
- * @param source - Plugin-generated type source info
224
+ * @param type - Parsed TailorDB table
225
+ * @param source - Plugin-generated table source info
225
226
  * @returns Generated lines-db metadata with plugin source
226
227
  */
227
228
  function processLinesDbForPluginType(type, source) {
@@ -238,8 +239,8 @@ function processLinesDbForPluginType(type, source) {
238
239
  };
239
240
  }
240
241
  /**
241
- * Extract field metadata from TailorDB type
242
- * @param type - Parsed TailorDB type
242
+ * Extract field metadata from TailorDB table
243
+ * @param type - Parsed TailorDB table
243
244
  * @returns Field metadata including optional fields, omit fields, indexes, and foreign keys
244
245
  */
245
246
  function extractFieldMetadata(type) {
@@ -304,30 +305,32 @@ function generateSchemaOptions(foreignKeys, indexes) {
304
305
  ].join("\n") : "";
305
306
  }
306
307
  /**
307
- * Generates the schema file content for lines-db (for user-defined types with import)
308
+ * Generates the schema file content for lines-db (for user-defined tables with import)
308
309
  * @param metadata - lines-db metadata
309
- * @param importPath - Import path for the TailorDB type
310
+ * @param importPath - Import path for the TailorDB table
310
311
  * @returns Schema file contents
311
312
  */
312
313
  function generateLinesDbSchemaFile(metadata, importPath) {
313
314
  const { exportName, optionalFields, omitFields, foreignKeys, indexes } = metadata;
315
+ const schemaTypeCode = multiline`
316
+ const schemaType = t.object({
317
+ ...${exportName}.pickFields(${JSON.stringify(optionalFields)}, { optional: true }),
318
+ ...${exportName}.omitFields(${JSON.stringify([...optionalFields, ...omitFields])}),
319
+ });
320
+ `;
321
+ const schemaOptionsCode = generateSchemaOptions(foreignKeys, indexes);
314
322
  return multiline`
315
323
  import { t } from "@tailor-platform/sdk";
316
324
  import { defineSchema } from "@tailor-platform/sdk/seed";
317
325
  import { createTailorDBHook, createStandardSchema } from "@tailor-platform/sdk/test";
318
326
  import { ${exportName} } from "${importPath}";
319
327
 
320
- ${multiline`
321
- const schemaType = t.object({
322
- ...${exportName}.pickFields(${JSON.stringify(optionalFields)}, { optional: true }),
323
- ...${exportName}.omitFields(${JSON.stringify([...optionalFields, ...omitFields])}),
324
- });
325
- `}
328
+ ${schemaTypeCode}
326
329
 
327
330
  export const hook = createTailorDBHook(${exportName});
328
331
 
329
332
  export const schema = defineSchema(
330
- createStandardSchema(schemaType, hook, ${exportName}),${generateSchemaOptions(foreignKeys, indexes)}
333
+ createStandardSchema(schemaType, hook, ${exportName}),${schemaOptionsCode}
331
334
  );
332
335
 
333
336
  `;
@@ -421,7 +424,8 @@ function seedPlugin(options) {
421
424
  const idpUser = ctx.auth ? processIdpUser(ctx.auth) ?? null : null;
422
425
  const idpUserSyncFKs = resolveIdpUserSyncFKs(ctx.pluginConfig.disableIdpUserSync);
423
426
  for (const ns of ctx.tailordb) for (const [typeName, type] of Object.entries(ns.types)) {
424
- const linesDb = processLinesDb(type, assertDefined(ns.sourceInfo.get(typeName), `source info missing for type: ${typeName}`));
427
+ const source = assertDefined(ns.sourceInfo.get(typeName), `source info missing for type: ${typeName}`);
428
+ const linesDb = processLinesDb(type, source);
425
429
  if (idpUserSyncFKs.emitUserToIdpFK && idpUser && typeName === idpUser.schema.userTypeName) linesDb.foreignKeys.push({
426
430
  column: idpUser.schema.usernameField,
427
431
  references: {
@@ -441,17 +445,19 @@ function seedPlugin(options) {
441
445
  const relativePath = path.relative(path.dirname(schemaOutputPath), linesDb.pluginSource.originalFilePath);
442
446
  originalImportPath = relativePath.replace(/\.ts$/, "").startsWith(".") ? relativePath.replace(/\.ts$/, "") : `./${relativePath.replace(/\.ts$/, "")}`;
443
447
  }
444
- const schemaContent = generateLinesDbSchemaFileWithPluginAPI(linesDb, {
448
+ const params = {
445
449
  configImportPath: path.relative(path.dirname(schemaOutputPath), ctx.configPath),
446
450
  originalImportPath
447
- });
451
+ };
452
+ const schemaContent = generateLinesDbSchemaFileWithPluginAPI(linesDb, params);
448
453
  files.push({
449
454
  path: schemaOutputPath,
450
455
  content: schemaContent
451
456
  });
452
457
  } else {
453
458
  const relativePath = path.relative(path.dirname(schemaOutputPath), linesDb.importPath);
454
- const schemaContent = generateLinesDbSchemaFile(linesDb, relativePath.replace(/\.ts$/, "").startsWith(".") ? relativePath.replace(/\.ts$/, "") : `./${relativePath.replace(/\.ts$/, "")}`);
459
+ const typeImportPath = relativePath.replace(/\.ts$/, "").startsWith(".") ? relativePath.replace(/\.ts$/, "") : `./${relativePath.replace(/\.ts$/, "")}`;
460
+ const schemaContent = generateLinesDbSchemaFile(linesDb, typeImportPath);
455
461
  files.push({
456
462
  path: schemaOutputPath,
457
463
  content: schemaContent
@@ -480,4 +486,4 @@ function seedPlugin(options) {
480
486
 
481
487
  //#endregion
482
488
  export { generateIdpTruncateScriptCode as a, generateIdpSeedScriptCode as i, seedPlugin as n, processIdpUser as o, processLinesDb as r, SeedGeneratorID as t };
483
- //# sourceMappingURL=seed-xqM9WIHP.mjs.map
489
+ //# sourceMappingURL=seed-Cibjmtry.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seed-Cibjmtry.mjs","names":[],"sources":["../src/plugin/builtin/seed/idp-user-processor.ts","../src/plugin/builtin/seed/lines-db-processor.ts","../src/plugin/builtin/seed/index.ts"],"sourcesContent":["import ml from \"#/utils/multiline\";\nimport type { GeneratorAuthInput } from \"#/plugin/types\";\n\nexport interface IdpUserMetadata {\n name: \"_User\";\n dependencies: string[];\n dataFile: string;\n idpNamespace: string;\n schema: {\n usernameField: string;\n userTypeName: string;\n };\n}\n\n/**\n * Processes auth configuration to generate IdP user seed metadata\n * @param auth - Auth configuration from generator\n * @returns IdP user metadata or undefined if not applicable\n */\nexport function processIdpUser(auth: GeneratorAuthInput): IdpUserMetadata | undefined {\n // Only process if idProvider is BuiltInIdP and userProfile is defined\n if (auth.idProvider?.kind !== \"BuiltInIdP\" || !auth.userProfile) {\n return undefined;\n }\n\n const { typeName, usernameField } = auth.userProfile;\n\n return {\n name: \"_User\",\n dependencies: [typeName],\n dataFile: \"data/_User.jsonl\",\n idpNamespace: auth.idProvider.namespace,\n schema: {\n usernameField,\n userTypeName: typeName,\n },\n };\n}\n\n/**\n * Generates the server-side IDP seed script code for testExecScript execution.\n * Uses the global tailor.idp.Client - no bundling required.\n * @param idpNamespace - The IDP namespace name\n * @returns Script code string\n */\nexport function generateIdpSeedScriptCode(idpNamespace: string): string {\n return ml /* ts */ `\n export async function main(input) {\n const client = new tailor.idp.Client({ namespace: \"${idpNamespace}\" });\n const errors = [];\n let processed = 0;\n let created = 0;\n let updated = 0;\n let skipped = 0;\n const upsert = input.upsert === true;\n\n for (let i = 0; i < input.users.length; i++) {\n try {\n if (upsert) {\n let existing;\n let lookupError;\n try {\n existing = await client.userByName(input.users[i].name);\n } catch (error) {\n existing = undefined;\n lookupError = error instanceof Error ? error.message : String(error);\n }\n\n if (existing) {\n const { name, ...attributes } = input.users[i];\n if (Object.keys(attributes).length === 0) {\n skipped++;\n } else {\n await client.updateUser({ id: existing.id, ...attributes });\n updated++;\n }\n } else {\n try {\n await client.createUser(input.users[i]);\n created++;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(\n lookupError ? \\`create failed (\\${message}); lookup failed (\\${lookupError})\\` : message,\n );\n }\n }\n } else {\n await client.createUser(input.users[i]);\n created++;\n }\n processed++;\n console.log(\\`[_User] \\${i + 1}/\\${input.users.length}: \\${input.users[i].name}\\`);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n errors.push(\\`Row \\${i} (\\${input.users[i].name}): \\${message}\\`);\n console.error(\\`[_User] Row \\${i} failed: \\${message}\\`);\n }\n }\n\n return {\n success: errors.length === 0,\n processed,\n created,\n updated,\n skipped,\n errors,\n };\n }\n `;\n}\n\n/**\n * Generates the server-side IDP truncation script code for testExecScript execution.\n * Lists all users with pagination and deletes each one.\n * @param idpNamespace - The IDP namespace name\n * @returns Script code string\n */\nexport function generateIdpTruncateScriptCode(idpNamespace: string): string {\n return ml /* ts */ `\n export async function main() {\n const client = new tailor.idp.Client({ namespace: \"${idpNamespace}\" });\n const errors = [];\n let deleted = 0;\n\n // List all users with pagination\n let after = undefined;\n const allUsers = [];\n do {\n const response = await client.users(after ? { after } : undefined);\n allUsers.push(...(response.users || []));\n after = response.nextPageToken;\n } while (after);\n\n console.log(\\`Found \\${allUsers.length} IDP users to delete\\`);\n\n for (const user of allUsers) {\n try {\n await client.deleteUser(user.id);\n deleted++;\n console.log(\\`[_User] Deleted \\${deleted}/\\${allUsers.length}: \\${user.name}\\`);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n errors.push(\\`User \\${user.id} (\\${user.name}): \\${message}\\`);\n console.error(\\`[_User] Delete failed for \\${user.name}: \\${message}\\`);\n }\n }\n\n return {\n success: errors.length === 0,\n deleted,\n total: allUsers.length,\n errors,\n };\n }\n `;\n}\n\ntype GenerateIdpUserSchemaFileOptions = {\n usernameField: string;\n userTypeName: string;\n /**\n * When `true` (default), emit a foreign key from `_User.name` to the\n * userProfile type's username field so that seed validation rejects `_User`\n * rows without a matching userProfile row. Set to `false` to seed `_User`\n * rows that do not yet have a corresponding userProfile row.\n */\n includeUserProfileFK?: boolean;\n};\n\n/**\n * Generates the schema file content for IdP users. Emits the\n * `_User.name -> <userProfile>.<usernameField>` foreign key by default; pass\n * `includeUserProfileFK: false` to omit it (e.g. when seeding `_User` rows\n * that do not yet have a corresponding userProfile row).\n * @param options - Schema generation options\n * @param options.usernameField - Username field name\n * @param options.userTypeName - TailorDB user type name\n * @param options.includeUserProfileFK - Whether to emit the `_User -> userProfile` foreign key (default `true`)\n * @returns Schema file contents\n */\nexport function generateIdpUserSchemaFile(options: GenerateIdpUserSchemaFileOptions): string {\n const { usernameField, userTypeName, includeUserProfileFK = true } = options;\n const schemaBody = includeUserProfileFK\n ? ml`\n primaryKey: \"name\",\n indexes: [\n { name: \"_user_name_unique_idx\", columns: [\"name\"], unique: true },\n ],\n foreignKeys: [\n {\n column: \"name\",\n references: {\n table: \"${userTypeName}\",\n column: \"${usernameField}\",\n },\n },\n ],\n `\n : ml`\n primaryKey: \"name\",\n indexes: [\n { name: \"_user_name_unique_idx\", columns: [\"name\"], unique: true },\n ],\n `;\n\n return ml /* ts */ `\n import { t } from \"@tailor-platform/sdk\";\n import { defineSchema } from \"@tailor-platform/sdk/seed\";\n import { createStandardSchema } from \"@tailor-platform/sdk/test\";\n\n const schemaType = t.object({\n name: t.string(),\n password: t.string(),\n });\n\n // Simple identity hook for _User (no TailorDB backing table)\n export const hook = <T>(data: unknown) => data as T;\n\n export const schema = defineSchema(\n createStandardSchema(schemaType, hook),\n {\n ${schemaBody}\n }\n );\n\n `;\n}\n","import { isPluginGeneratedType } from \"#/parser/service/tailordb/type-source\";\nimport ml from \"#/utils/multiline\";\nimport type {\n PluginGeneratedTypeSource,\n TailorDBType,\n TypeSourceInfoEntry,\n} from \"#/parser/service/tailordb/types\";\nimport type { LinesDbMetadata } from \"./types\";\nimport type { ForeignKeyDefinition, IndexDefinition } from \"@toiroakr/lines-db\";\n\n/**\n * Processes TailorDB tables to generate lines-db metadata\n * @param type - Parsed TailorDB table\n * @param source - Source file info\n * @returns Generated lines-db metadata\n */\nexport function processLinesDb(type: TailorDBType, source: TypeSourceInfoEntry): LinesDbMetadata {\n if (isPluginGeneratedType(source)) {\n // Plugin-generated table\n return processLinesDbForPluginType(type, source);\n }\n\n // User-defined table\n if (!source.filePath) {\n throw new Error(`Missing source info for table ${type.name}`);\n }\n if (!source.exportName) {\n throw new Error(`Missing export name for table ${type.name}`);\n }\n\n const { optionalFields, omitFields, indexes, foreignKeys } = extractFieldMetadata(type);\n\n return {\n typeName: type.name,\n exportName: source.exportName,\n importPath: source.filePath,\n optionalFields,\n omitFields,\n foreignKeys,\n indexes,\n };\n}\n\n/**\n * Process lines-db metadata for plugin-generated types\n * @param type - Parsed TailorDB table\n * @param source - Plugin-generated table source info\n * @returns Generated lines-db metadata with plugin source\n */\nfunction processLinesDbForPluginType(\n type: TailorDBType,\n source: PluginGeneratedTypeSource,\n): LinesDbMetadata {\n const { optionalFields, omitFields, indexes, foreignKeys } = extractFieldMetadata(type);\n\n return {\n typeName: type.name,\n exportName: source.exportName,\n importPath: \"\",\n optionalFields,\n omitFields,\n foreignKeys,\n indexes,\n pluginSource: source,\n };\n}\n\n/**\n * Extract field metadata from TailorDB table\n * @param type - Parsed TailorDB table\n * @returns Field metadata including optional fields, omit fields, indexes, and foreign keys\n */\nfunction extractFieldMetadata(type: TailorDBType): {\n optionalFields: string[];\n omitFields: string[];\n indexes: IndexDefinition[];\n foreignKeys: ForeignKeyDefinition[];\n} {\n const optionalFields = [\"id\"]; // id is always optional\n const omitFields: string[] = [];\n const indexes: IndexDefinition[] = [];\n const foreignKeys: ForeignKeyDefinition[] = [];\n\n // Find fields with hooks.create or serial\n for (const [fieldName, field] of Object.entries(type.fields)) {\n if (field.config.hooks?.create) {\n optionalFields.push(fieldName);\n }\n // Serial fields are auto-generated, so they should be optional in seed data\n if (field.config.serial) {\n omitFields.push(fieldName);\n }\n if (field.config.unique) {\n indexes.push({\n name: `${type.name.toLowerCase()}_${fieldName}_unique_idx`,\n columns: [fieldName],\n unique: true,\n });\n }\n }\n\n // Extract indexes\n if (type.indexes) {\n for (const [indexName, indexDef] of Object.entries(type.indexes)) {\n indexes.push({\n name: indexName,\n columns: indexDef.fields,\n unique: indexDef.unique,\n });\n }\n }\n\n // Extract foreign keys from relations\n for (const [fieldName, field] of Object.entries(type.fields)) {\n if (field.relation) {\n foreignKeys.push({\n column: fieldName,\n references: {\n table: field.relation.targetType,\n column: field.relation.key,\n },\n });\n }\n }\n\n return { optionalFields, omitFields, indexes, foreignKeys };\n}\n\n/**\n * Generate schema options code for lines-db\n * @param foreignKeys - Foreign key definitions\n * @param indexes - Index definitions\n * @returns Schema options code string\n */\nfunction generateSchemaOptions(\n foreignKeys: ForeignKeyDefinition[],\n indexes: IndexDefinition[],\n): string {\n const schemaOptions: string[] = [];\n\n if (foreignKeys.length > 0) {\n schemaOptions.push(`foreignKeys: [`);\n foreignKeys.forEach((fk) => {\n schemaOptions.push(` ${JSON.stringify(fk)},`);\n });\n schemaOptions.push(`],`);\n }\n\n if (indexes.length > 0) {\n schemaOptions.push(`indexes: [`);\n indexes.forEach((index) => {\n schemaOptions.push(` ${JSON.stringify(index)},`);\n });\n schemaOptions.push(\"],\");\n }\n\n return schemaOptions.length > 0\n ? [\"\\n {\", ...schemaOptions.map((option) => ` ${option}`), \" }\"].join(\"\\n\")\n : \"\";\n}\n\n/**\n * Generates the schema file content for lines-db (for user-defined tables with import)\n * @param metadata - lines-db metadata\n * @param importPath - Import path for the TailorDB table\n * @returns Schema file contents\n */\nexport function generateLinesDbSchemaFile(metadata: LinesDbMetadata, importPath: string): string {\n const { exportName, optionalFields, omitFields, foreignKeys, indexes } = metadata;\n\n const schemaTypeCode = ml /* ts */ `\n const schemaType = t.object({\n ...${exportName}.pickFields(${JSON.stringify(optionalFields)}, { optional: true }),\n ...${exportName}.omitFields(${JSON.stringify([...optionalFields, ...omitFields])}),\n });\n `;\n\n const schemaOptionsCode = generateSchemaOptions(foreignKeys, indexes);\n\n return ml /* ts */ `\n import { t } from \"@tailor-platform/sdk\";\n import { defineSchema } from \"@tailor-platform/sdk/seed\";\n import { createTailorDBHook, createStandardSchema } from \"@tailor-platform/sdk/test\";\n import { ${exportName} } from \"${importPath}\";\n\n ${schemaTypeCode}\n\n export const hook = createTailorDBHook(${exportName});\n\n export const schema = defineSchema(\n createStandardSchema(schemaType, hook, ${exportName}),${schemaOptionsCode}\n );\n\n `;\n}\n\n/**\n * Parameters for generating plugin-type schema file\n */\nexport interface PluginSchemaParams {\n /** Relative path from schema output to tailor.config.ts */\n configImportPath: string;\n /** Relative import path to the original table file (for type-attached plugins) */\n originalImportPath?: string;\n}\n\n/**\n * Generates the schema file content using getGeneratedType API\n * (for plugin-generated types)\n * @param metadata - lines-db metadata (must have pluginSource)\n * @param params - Plugin import paths\n * @returns Schema file contents\n */\nexport function generateLinesDbSchemaFileWithPluginAPI(\n metadata: LinesDbMetadata,\n params: PluginSchemaParams,\n): string {\n const { typeName, exportName, optionalFields, omitFields, foreignKeys, indexes, pluginSource } =\n metadata;\n\n if (!pluginSource) {\n throw new Error(`pluginSource is required for plugin-generated type \"${typeName}\"`);\n }\n\n const { configImportPath, originalImportPath } = params;\n\n const schemaTypeCode = ml /* ts */ `\n const schemaType = t.object({\n ...${exportName}.pickFields(${JSON.stringify(optionalFields)}, { optional: true }),\n ...${exportName}.omitFields(${JSON.stringify([...optionalFields, ...omitFields])}),\n });\n `;\n\n const schemaOptionsCode = generateSchemaOptions(foreignKeys, indexes);\n\n // Type-attached plugin (e.g., changeset): import the original table and use getGeneratedType(configPath, pluginId, type, kind)\n if (pluginSource.originalExportName && originalImportPath && pluginSource.generatedTypeKind) {\n return ml /* ts */ `\n import { join } from \"node:path\";\n import { t } from \"@tailor-platform/sdk\";\n import { getGeneratedType } from \"@tailor-platform/sdk/plugin\";\n import { defineSchema } from \"@tailor-platform/sdk/seed\";\n import { createTailorDBHook, createStandardSchema } from \"@tailor-platform/sdk/test\";\n import { ${pluginSource.originalExportName} } from \"${originalImportPath}\";\n\n const configPath = join(import.meta.dirname, \"${configImportPath}\");\n const ${exportName} = await getGeneratedType(configPath, \"${pluginSource.pluginId}\", ${pluginSource.originalExportName}, \"${pluginSource.generatedTypeKind}\");\n\n ${schemaTypeCode}\n\n export const hook = createTailorDBHook(${exportName});\n\n export const schema = defineSchema(\n createStandardSchema(schemaType, hook, ${exportName}),${schemaOptionsCode}\n );\n\n `;\n }\n\n // Namespace plugin (e.g., audit-log): use getGeneratedType(configPath, pluginId, null, kind)\n // For namespace plugins, generatedTypeKind is required\n if (!pluginSource.generatedTypeKind) {\n throw new Error(\n `Namespace plugin \"${pluginSource.pluginId}\" must provide generatedTypeKind for type \"${typeName}\"`,\n );\n }\n\n return ml /* ts */ `\n import { join } from \"node:path\";\n import { t } from \"@tailor-platform/sdk\";\n import { getGeneratedType } from \"@tailor-platform/sdk/plugin\";\n import { defineSchema } from \"@tailor-platform/sdk/seed\";\n import { createTailorDBHook, createStandardSchema } from \"@tailor-platform/sdk/test\";\n\n const configPath = join(import.meta.dirname, \"${configImportPath}\");\n const ${exportName} = await getGeneratedType(configPath, \"${pluginSource.pluginId}\", null, \"${pluginSource.generatedTypeKind}\");\n\n ${schemaTypeCode}\n\n export const hook = createTailorDBHook(${exportName});\n\n export const schema = defineSchema(\n createStandardSchema(schemaType, hook, ${exportName}),${schemaOptionsCode}\n );\n\n `;\n}\n","import * as path from \"pathe\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { processIdpUser, generateIdpUserSchemaFile } from \"./idp-user-processor\";\nimport {\n processLinesDb,\n generateLinesDbSchemaFile,\n generateLinesDbSchemaFileWithPluginAPI,\n type PluginSchemaParams,\n} from \"./lines-db-processor\";\nimport type { Plugin, GeneratorResult, TailorDBReadyContext } from \"#/plugin/types\";\n\n/** Unique identifier for the seed generator plugin. */\nexport const SeedGeneratorID = \"@tailor-platform/seed\";\n\ntype DisableIdpUserSyncDirections = {\n /**\n * Skip emitting the foreign key from `<userProfile>.<usernameField>` to\n * `_User.name`. Defaults to `false` (FK emitted).\n *\n * Set to `true` to seed pre-registration states such as\n * invited-but-not-registered users.\n */\n userToIdp?: boolean;\n /**\n * Skip emitting the foreign key from `_User.name` to\n * `<userProfile>.<usernameField>`. Defaults to `false` (FK emitted).\n *\n * Set to `true` to seed `_User` rows that do not yet have a corresponding\n * userProfile row.\n */\n idpToUser?: boolean;\n};\n\nexport type SeedPluginOptions = {\n distPath: string;\n machineUserName?: string;\n /**\n * Disable individual `_User <-> userProfile` foreign keys emitted into\n * the generated seed schema. Both directions are emitted by default.\n *\n * Set a direction to `true` to relax it — for example to seed invited\n * users that do not yet have an IdP credential.\n */\n disableIdpUserSync?: DisableIdpUserSyncDirections;\n};\n\nfunction resolveIdpUserSyncFKs(option: SeedPluginOptions[\"disableIdpUserSync\"]): {\n emitUserToIdpFK: boolean;\n emitIdpToUserFK: boolean;\n} {\n return {\n emitUserToIdpFK: !(option?.userToIdp ?? false),\n emitIdpToUserFK: !(option?.idpToUser ?? false),\n };\n}\n/**\n * Plugin that generates seed data and schema files consumed by the\n * `tailor seed` commands (@tailor-platform/sdk-plugin-seed).\n * @param options - Plugin options\n * @param options.distPath - Output directory path for generated seed files\n * @param options.machineUserName - Default machine user name for authentication\n * @param options.disableIdpUserSync - Skip emitting individual `_User <-> userProfile` foreign keys. Both directions are emitted by default; set a direction to `true` to relax that side.\n * @returns Plugin instance with onTailorDBReady hook\n */\nexport function seedPlugin(options: SeedPluginOptions): Plugin<unknown, SeedPluginOptions> {\n return {\n id: SeedGeneratorID,\n description: \"Generates seed data and schema files for the tailor seed CLI plugin\",\n pluginConfig: options,\n\n async onTailorDBReady(ctx: TailorDBReadyContext<SeedPluginOptions>): Promise<GeneratorResult> {\n const files: GeneratorResult[\"files\"] = [];\n\n // Process IdP user early so we can add reverse FK to the user profile type\n const idpUser = ctx.auth ? (processIdpUser(ctx.auth) ?? null) : null;\n const idpUserSyncFKs = resolveIdpUserSyncFKs(ctx.pluginConfig.disableIdpUserSync);\n\n for (const ns of ctx.tailordb) {\n for (const [typeName, type] of Object.entries(ns.types)) {\n const source = assertDefined(\n ns.sourceInfo.get(typeName),\n `source info missing for type: ${typeName}`,\n );\n const linesDb = processLinesDb(type, source);\n\n // Add reverse FK from userProfile type to _User (opt-out via disableIdpUserSync.userToIdp: true)\n if (\n idpUserSyncFKs.emitUserToIdpFK &&\n idpUser &&\n typeName === idpUser.schema.userTypeName\n ) {\n linesDb.foreignKeys.push({\n column: idpUser.schema.usernameField,\n references: {\n table: \"_User\",\n column: \"name\",\n },\n });\n }\n\n // Generate empty JSONL data file\n files.push({\n path: path.join(ctx.pluginConfig.distPath, \"data\", `${linesDb.typeName}.jsonl`),\n content: \"\",\n skipIfExists: true,\n });\n\n const schemaOutputPath = path.join(\n ctx.pluginConfig.distPath,\n \"data\",\n `${linesDb.typeName}.schema.ts`,\n );\n\n // Plugin-generated type: use getGeneratedType API\n if (linesDb.pluginSource && linesDb.pluginSource.pluginImportPath) {\n // Build original type import path\n let originalImportPath: string | undefined;\n if (linesDb.pluginSource.originalFilePath && linesDb.pluginSource.originalExportName) {\n const relativePath = path.relative(\n path.dirname(schemaOutputPath),\n linesDb.pluginSource.originalFilePath,\n );\n originalImportPath = relativePath.replace(/\\.ts$/, \"\").startsWith(\".\")\n ? relativePath.replace(/\\.ts$/, \"\")\n : `./${relativePath.replace(/\\.ts$/, \"\")}`;\n }\n\n // Compute relative path from schema output to config file\n const configImportPath = path.relative(path.dirname(schemaOutputPath), ctx.configPath);\n\n const params: PluginSchemaParams = {\n configImportPath,\n originalImportPath,\n };\n\n const schemaContent = generateLinesDbSchemaFileWithPluginAPI(linesDb, params);\n\n files.push({\n path: schemaOutputPath,\n content: schemaContent,\n });\n } else {\n // User-defined type: import from source file\n const relativePath = path.relative(path.dirname(schemaOutputPath), linesDb.importPath);\n const typeImportPath = relativePath.replace(/\\.ts$/, \"\").startsWith(\".\")\n ? relativePath.replace(/\\.ts$/, \"\")\n : `./${relativePath.replace(/\\.ts$/, \"\")}`;\n const schemaContent = generateLinesDbSchemaFile(linesDb, typeImportPath);\n\n files.push({\n path: schemaOutputPath,\n content: schemaContent,\n });\n }\n }\n }\n\n if (idpUser) {\n // Generate empty JSONL data file\n files.push({\n path: path.join(ctx.pluginConfig.distPath, idpUser.dataFile),\n content: \"\",\n skipIfExists: true,\n });\n\n // Generate schema file with foreign key (opt-out via disableIdpUserSync.idpToUser: true)\n files.push({\n path: path.join(ctx.pluginConfig.distPath, \"data\", `${idpUser.name}.schema.ts`),\n content: generateIdpUserSchemaFile({\n usernameField: idpUser.schema.usernameField,\n userTypeName: idpUser.schema.userTypeName,\n includeUserProfileFK: idpUserSyncFKs.emitIdpToUserFK,\n }),\n });\n }\n\n return { files };\n },\n };\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { n as isSdkBranded } from "./brand-Eo4pLXPJ.mjs";
2
- import { n as logger, r as styles } from "./logger-DSdExfor.mjs";
2
+ import { n as logger, r as styles } from "./logger-D0bEznPv.mjs";
3
3
  import * as path from "pathe";
4
4
  import { z } from "zod";
5
5
  import * as fs from "node:fs";
@@ -8,6 +8,40 @@ import { pathToFileURL } from "node:url";
8
8
  //#region src/parser/service/common.ts
9
9
  const functionSchema = z.custom((val) => typeof val === "function");
10
10
 
11
+ //#endregion
12
+ //#region src/cli/shared/user-modules.ts
13
+ const IMPORT_NONCE_PARAM = "tailorImportNonce";
14
+ let runCounter = 0;
15
+ /**
16
+ * Start a fresh user-module run. Modules imported through
17
+ * {@link importUserModule} after this call bypass the ESM cache entries of
18
+ * earlier runs, so a repeated in-process run re-evaluates user code instead
19
+ * of reusing stale modules.
20
+ */
21
+ function beginUserModuleRun() {
22
+ runCounter += 1;
23
+ }
24
+ /**
25
+ * Read the cache-busting nonce of the current user-module run.
26
+ * @returns The nonce, or undefined when no run was started
27
+ */
28
+ function currentImportNonce() {
29
+ return runCounter === 0 ? void 0 : String(runCounter);
30
+ }
31
+ /**
32
+ * Import a user module (config, workflow, resolver, executor, ...) with the
33
+ * current run's cache-busting nonce applied. Outside a run this is a plain
34
+ * import.
35
+ * @param filePath - Absolute path of the user module
36
+ * @returns The imported module namespace
37
+ */
38
+ function importUserModule(filePath) {
39
+ const url = pathToFileURL(filePath);
40
+ const nonce = currentImportNonce();
41
+ if (nonce) url.searchParams.set(IMPORT_NONCE_PARAM, nonce);
42
+ return import(url.href);
43
+ }
44
+
11
45
  //#endregion
12
46
  //#region src/cli/services/file-loader.ts
13
47
  const DEFAULT_IGNORE_PATTERNS = ["**/*.test.ts", "**/*.spec.ts"];
@@ -67,17 +101,17 @@ const relationTypes = {
67
101
  };
68
102
  const relationTypesKeys = Object.keys(relationTypes);
69
103
  function fieldRef(context) {
70
- return `Field "${context.fieldName}" on type "${context.typeName}"`;
104
+ return `Field "${context.fieldName}" on table "${context.typeName}"`;
71
105
  }
72
106
  /**
73
107
  * Validate relation configuration.
74
- * @param rawRelation - Raw relation configuration from TailorDB type definition
75
- * @param context - Context information for the relation (type name, field name, all type names)
108
+ * @param rawRelation - Raw relation configuration from TailorDB table definition
109
+ * @param context - Context information for the relation (table name, field name, all type names)
76
110
  */
77
111
  function validateRelationConfig(rawRelation, context) {
78
112
  if (!rawRelation.type) throw new Error(`${fieldRef(context)} has a relation but is missing the required 'type' property. Valid values: ${relationTypesKeys.join(", ")}.`);
79
113
  if (!(rawRelation.type in relationTypes)) throw new Error(`${fieldRef(context)} has invalid relation type '${rawRelation.type}'. Valid values: ${relationTypesKeys.join(", ")}.`);
80
- if (rawRelation.toward.type !== "self" && !context.allTypeNames.has(rawRelation.toward.type)) throw new Error(`${fieldRef(context)} references unknown type "${rawRelation.toward.type}".`);
114
+ if (rawRelation.toward.type !== "self" && !context.allTypeNames.has(rawRelation.toward.type)) throw new Error(`${fieldRef(context)} references unknown table "${rawRelation.toward.type}".`);
81
115
  }
82
116
  /**
83
117
  * Process raw relation config and compute derived metadata values.
@@ -166,7 +200,7 @@ const GqlOperationsSchema = z.union([z.literal("query"), z.strictObject({
166
200
  update: z.boolean().optional().describe("Enable update mutation (default: true)"),
167
201
  delete: z.boolean().optional().describe("Enable delete mutation (default: true)"),
168
202
  read: z.boolean().optional().describe("Enable read queries - get, list, aggregation (default: true)")
169
- })]).describe("Configuration for GraphQL operations on a TailorDB type.\nAll operations are enabled by default (undefined or true = enabled, false = disabled).").transform((val) => normalizeGqlOperations(val));
203
+ })]).describe("Configuration for GraphQL operations on a TailorDB table.\nAll operations are enabled by default (undefined or true = enabled, false = disabled).").transform((val) => normalizeGqlOperations(val));
170
204
  const TailorFieldTypeSchema$1 = z.enum([
171
205
  "uuid",
172
206
  "string",
@@ -194,7 +228,7 @@ const DBFieldMetadataSchema = z.strictObject({
194
228
  unique: z.boolean().optional().describe("Whether the field value must be unique"),
195
229
  vector: z.boolean().optional().describe("Whether the field is a vector field for similarity search"),
196
230
  foreignKey: z.boolean().optional().describe("Whether the field is a foreign key"),
197
- foreignKeyType: z.string().optional().describe("Target type name for foreign key relations"),
231
+ foreignKeyType: z.string().optional().describe("Target table name for foreign key relations"),
198
232
  foreignKeyField: z.string().optional().describe("Target field name for foreign key relations"),
199
233
  hooks: z.strictObject({
200
234
  create: functionSchema.optional().describe("Hook function called on record creation"),
@@ -213,11 +247,11 @@ const RelationTypeSchema = z.enum(relationTypesKeys);
213
247
  const RawRelationConfigSchema = z.strictObject({
214
248
  type: RelationTypeSchema.describe("Relation cardinality type"),
215
249
  toward: z.strictObject({
216
- type: z.string().describe("Target type name, or 'self' for self-relations"),
250
+ type: z.string().describe("Target table name, or 'self' for self-relations"),
217
251
  as: z.string().optional().describe("Custom forward relation name"),
218
252
  key: z.string().optional().describe("Target field to join on (default: 'id')")
219
253
  }),
220
- backward: z.string().optional().describe("Backward relation name on the target type")
254
+ backward: z.string().optional().describe("Backward relation name on the target table")
221
255
  });
222
256
  const TailorDBFieldSchema = z.lazy(() => z.object({
223
257
  type: TailorFieldTypeSchema$1,
@@ -226,15 +260,15 @@ const TailorDBFieldSchema = z.lazy(() => z.object({
226
260
  rawRelation: RawRelationConfigSchema.optional()
227
261
  }));
228
262
  /**
229
- * Schema for TailorDB type settings.
263
+ * Schema for TailorDB table settings.
230
264
  * Normalizes gqlOperations from alias ("query") to object format.
231
265
  */
232
266
  const TailorDBTypeSettingsSchema = z.strictObject({
233
- pluralForm: z.string().optional().describe("Custom plural form of the type name for GraphQL"),
234
- aggregation: z.boolean().optional().describe("Enable aggregation queries for this type"),
235
- bulkUpsert: z.boolean().optional().describe("Enable bulk upsert mutation for this type"),
236
- gqlOperations: GqlOperationsSchema.optional().describe("Configure GraphQL operations for this type. Use \"query\" for read-only mode, or an object for granular control."),
237
- publishEvents: z.boolean().optional().describe("Enable publishing events for this type.\nWhen enabled, record creation/update/deletion events are published.\nIf not specified, this is automatically set to true when an executor uses this type\nwith recordCreated/recordUpdated/recordDeleted triggers. If explicitly set to false\nwhile an executor uses this type, an error will be thrown during apply.")
267
+ pluralForm: z.string().optional().describe("Custom plural form of the table name for GraphQL"),
268
+ aggregation: z.boolean().optional().describe("Enable aggregation queries for this table"),
269
+ bulkUpsert: z.boolean().optional().describe("Enable bulk upsert mutation for this table"),
270
+ gqlOperations: GqlOperationsSchema.optional().describe("Configure GraphQL operations for this table. Use \"query\" for read-only mode, or an object for granular control."),
271
+ publishEvents: z.boolean().optional().describe("Enable publishing events for this table.\nWhen enabled, record creation/update/deletion events are published.\nIf not specified, this is automatically set to true when an executor uses this table\nwith recordCreated/recordUpdated/recordDeleted triggers. If explicitly set to false\nwhile an executor uses this table, an error will be thrown during apply.")
238
272
  });
239
273
  const GQL_PERMISSION_INVALID_OPERAND_MESSAGE = "operand is not supported in gqlPermission. Use permission() for record-level conditions.";
240
274
  const GqlPermissionOperandSchema = z.union([
@@ -349,10 +383,10 @@ const TailorDBMigrationConfigSchema = z.strictObject({
349
383
  * Normalizes gqlOperations from alias ("query") to object format.
350
384
  */
351
385
  const TailorDBServiceConfigSchema = z.strictObject({
352
- files: z.array(z.string()).describe("Glob patterns for TailorDB type definition files"),
353
- ignores: z.array(z.string()).optional().describe("Glob patterns to exclude from type discovery"),
386
+ files: z.array(z.string()).describe("Glob patterns for TailorDB table definition files"),
387
+ ignores: z.array(z.string()).optional().describe("Glob patterns to exclude from table discovery"),
354
388
  migration: TailorDBMigrationConfigSchema.optional().describe("Migration configuration"),
355
- gqlOperations: GqlOperationsSchema.optional().describe("Default GraphQL operations for all types in this service")
389
+ gqlOperations: GqlOperationsSchema.optional().describe("Default GraphQL operations for all tables in this service")
356
390
  });
357
391
 
358
392
  //#endregion
@@ -543,7 +577,7 @@ const SCIMAttributeMappingSchema = z.strictObject({
543
577
  const SCIMResourceSchema = z.strictObject({
544
578
  name: z.string().describe("SCIM resource name"),
545
579
  tailorDBNamespace: z.string().describe("TailorDB namespace for the resource"),
546
- tailorDBType: z.string().describe("TailorDB type name for the resource"),
580
+ tailorDBType: z.string().describe("TailorDB table name for the resource"),
547
581
  coreSchema: SCIMSchemaSchema.describe("Core SCIM schema definition"),
548
582
  attributeMapping: z.array(SCIMAttributeMappingSchema).describe("Attribute mapping configuration")
549
583
  });
@@ -553,12 +587,12 @@ const SCIMSchema = z.strictObject({
553
587
  resources: z.array(SCIMResourceSchema).describe("SCIM resource definitions")
554
588
  });
555
589
  const TenantProviderSchema = z.strictObject({
556
- namespace: z.string().describe("TailorDB namespace for the tenant type"),
557
- type: z.string().describe("TailorDB type name for tenants"),
590
+ namespace: z.string().describe("TailorDB namespace for the tenant table"),
591
+ type: z.string().describe("TailorDB table name for tenants"),
558
592
  signatureField: z.string().describe("Field used as the tenant signature")
559
593
  });
560
594
  const UserProfileSchema = z.strictObject({
561
- namespace: z.string().optional().describe("TailorDB namespace where the user type is defined"),
595
+ namespace: z.string().optional().describe("TailorDB namespace where the user table is defined"),
562
596
  type: z.custom().transform(stripTailorDBTypeBuilderHelpers).pipe(TailorDBTypeSchema),
563
597
  usernameField: z.string(),
564
598
  attributes: z.record(z.string(), z.literal(true)).optional(),
@@ -610,7 +644,7 @@ const TailorDBTriggerSchema = z.strictObject({
610
644
  "tailordb.type_record.updated",
611
645
  "tailordb.type_record.deleted"
612
646
  ])).min(1).transform((arr) => [...new Set(arr)]).describe("TailorDB event types to trigger on"),
613
- typeName: z.string().describe("TailorDB type name to watch for events"),
647
+ typeName: z.string().describe("TailorDB table name to watch for events"),
614
648
  condition: functionSchema.optional().describe("Condition function to filter events")
615
649
  });
616
650
  const ResolverExecutedTriggerSchema = z.strictObject({
@@ -771,7 +805,7 @@ function stripExecutorTriggerArgs(executor) {
771
805
  * @returns Parsed executor or null if invalid
772
806
  */
773
807
  async function loadExecutor(executorFilePath) {
774
- const executor = (await import(pathToFileURL(executorFilePath).href)).default;
808
+ const executor = (await importUserModule(executorFilePath)).default;
775
809
  const parseResult = ExecutorSchema.safeParse(stripExecutorTriggerArgs(executor));
776
810
  if (!parseResult.success) return null;
777
811
  return parseResult.data;
@@ -791,7 +825,7 @@ function createExecutorService(params) {
791
825
  let loadPromise;
792
826
  const loadExecutorForFile = async (executorFile) => {
793
827
  try {
794
- const executorModule = await import(pathToFileURL(executorFile).href);
828
+ const executorModule = await importUserModule(executorFile);
795
829
  const result = ExecutorSchema.safeParse(stripExecutorTriggerArgs(executorModule.default));
796
830
  if (result.success) {
797
831
  const relativePath = path.relative(process.cwd(), executorFile);
@@ -860,5 +894,5 @@ function assertUniqueExecutorNames(executors) {
860
894
  }
861
895
 
862
896
  //#endregion
863
- export { AuthConfigSchema as a, stripTailorDBTypeBuilderHelpers as c, applyRelationMetadataToFieldConfig as d, buildRelationInfo as f, functionSchema as g, loadFilesWithIgnores as h, ExecutorSchema as i, TailorDBServiceConfigSchema as l, validateRelationConfig as m, loadExecutor as n, AuthInvokerSchema as o, processRelationMetadata as p, stripExecutorTriggerArgs as r, TailorFieldSchema as s, createExecutorService as t, TailorDBTypeSchema as u };
864
- //# sourceMappingURL=service-goqlJJgA.mjs.map
897
+ export { beginUserModuleRun as _, AuthConfigSchema as a, functionSchema as b, stripTailorDBTypeBuilderHelpers as c, applyRelationMetadataToFieldConfig as d, buildRelationInfo as f, IMPORT_NONCE_PARAM as g, loadFilesWithIgnores as h, ExecutorSchema as i, TailorDBServiceConfigSchema as l, validateRelationConfig as m, loadExecutor as n, AuthInvokerSchema as o, processRelationMetadata as p, stripExecutorTriggerArgs as r, TailorFieldSchema as s, createExecutorService as t, TailorDBTypeSchema as u, currentImportNonce as v, importUserModule as y };
898
+ //# sourceMappingURL=service-2grcAOCJ.mjs.map