@sanity/cli 8.25.0 → 8.27.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 (127) hide show
  1. package/README.md +3 -2
  2. package/dist/actions/build/shouldAutoUpdate.js +1 -26
  3. package/dist/actions/build/shouldAutoUpdate.js.map +1 -1
  4. package/dist/actions/context/mcpEndpoint.js +165 -0
  5. package/dist/actions/context/mcpEndpoint.js.map +1 -0
  6. package/dist/actions/context/resolveOrganizationId.js +8 -1
  7. package/dist/actions/context/resolveOrganizationId.js.map +1 -1
  8. package/dist/actions/deploy/deployApp.js +10 -3
  9. package/dist/actions/deploy/deployApp.js.map +1 -1
  10. package/dist/actions/deploy/deployStudio.js +11 -4
  11. package/dist/actions/deploy/deployStudio.js.map +1 -1
  12. package/dist/actions/init/initAction.js +3 -3
  13. package/dist/actions/init/initAction.js.map +1 -1
  14. package/dist/actions/init/plan/verifyCoupon.js +0 -1
  15. package/dist/actions/init/plan/verifyCoupon.js.map +1 -1
  16. package/dist/actions/init/scaffoldTemplate.js +1 -1
  17. package/dist/actions/init/scaffoldTemplate.js.map +1 -1
  18. package/dist/commands/api.js +10 -0
  19. package/dist/commands/api.js.map +1 -1
  20. package/dist/commands/backups/download.js +6 -0
  21. package/dist/commands/backups/download.js.map +1 -1
  22. package/dist/commands/context/create.js +8 -22
  23. package/dist/commands/context/create.js.map +1 -1
  24. package/dist/commands/context/delete.js +8 -1
  25. package/dist/commands/context/delete.js.map +1 -1
  26. package/dist/commands/context/issues/list.js +0 -5
  27. package/dist/commands/context/issues/list.js.map +1 -1
  28. package/dist/commands/context/list.js +6 -14
  29. package/dist/commands/context/list.js.map +1 -1
  30. package/dist/commands/context/mcp/create.js +152 -0
  31. package/dist/commands/context/mcp/create.js.map +1 -0
  32. package/dist/commands/context/mcp/delete.js +82 -0
  33. package/dist/commands/context/mcp/delete.js.map +1 -0
  34. package/dist/commands/context/mcp/get.js +42 -0
  35. package/dist/commands/context/mcp/get.js.map +1 -0
  36. package/dist/commands/context/mcp/list.js +87 -0
  37. package/dist/commands/context/mcp/list.js.map +1 -0
  38. package/dist/commands/context/mcp/status.js +98 -0
  39. package/dist/commands/context/mcp/status.js.map +1 -0
  40. package/dist/commands/context/mcp/update.js +225 -0
  41. package/dist/commands/context/mcp/update.js.map +1 -0
  42. package/dist/commands/context/query.js +6 -14
  43. package/dist/commands/context/query.js.map +1 -1
  44. package/dist/commands/context/update.js +12 -1
  45. package/dist/commands/context/update.js.map +1 -1
  46. package/dist/commands/datasets/create.js +6 -0
  47. package/dist/commands/datasets/create.js.map +1 -1
  48. package/dist/commands/datasets/embeddings/enable.js +6 -0
  49. package/dist/commands/datasets/embeddings/enable.js.map +1 -1
  50. package/dist/commands/datasets/import.js +6 -0
  51. package/dist/commands/datasets/import.js.map +1 -1
  52. package/dist/commands/deploy.js +7 -0
  53. package/dist/commands/deploy.js.map +1 -1
  54. package/dist/commands/documents/validate.js +6 -0
  55. package/dist/commands/documents/validate.js.map +1 -1
  56. package/dist/commands/exec.js +4 -2
  57. package/dist/commands/exec.js.map +1 -1
  58. package/dist/commands/init.js +13 -0
  59. package/dist/commands/init.js.map +1 -1
  60. package/dist/commands/manifest/extract.js +6 -0
  61. package/dist/commands/manifest/extract.js.map +1 -1
  62. package/dist/commands/media/create-aspect.js +7 -0
  63. package/dist/commands/media/create-aspect.js.map +1 -1
  64. package/dist/commands/migrations/run.js +6 -0
  65. package/dist/commands/migrations/run.js.map +1 -1
  66. package/dist/commands/organizations/create.js +6 -0
  67. package/dist/commands/organizations/create.js.map +1 -1
  68. package/dist/commands/organizations/update.js +6 -0
  69. package/dist/commands/organizations/update.js.map +1 -1
  70. package/dist/commands/schemas/delete.js +6 -0
  71. package/dist/commands/schemas/delete.js.map +1 -1
  72. package/dist/commands/schemas/deploy.js +6 -0
  73. package/dist/commands/schemas/deploy.js.map +1 -1
  74. package/dist/commands/schemas/extract.js +28 -3
  75. package/dist/commands/schemas/extract.js.map +1 -1
  76. package/dist/commands/schemas/list.js +6 -0
  77. package/dist/commands/schemas/list.js.map +1 -1
  78. package/dist/commands/schemas/validate.js +6 -0
  79. package/dist/commands/schemas/validate.js.map +1 -1
  80. package/dist/commands/tokens/rotate.js +6 -0
  81. package/dist/commands/tokens/rotate.js.map +1 -1
  82. package/dist/commands/typegen/generate.js +25 -1
  83. package/dist/commands/typegen/generate.js.map +1 -1
  84. package/dist/exports/invokeSanityCli/commandPolicies/mcpPolicy.js +6 -0
  85. package/dist/exports/invokeSanityCli/commandPolicies/mcpPolicy.js.map +1 -1
  86. package/dist/generated/apiRoutes.js +22 -0
  87. package/dist/generated/apiRoutes.js.map +1 -1
  88. package/dist/hooks/prerun/setupTelemetry.js +2 -3
  89. package/dist/hooks/prerun/setupTelemetry.js.map +1 -1
  90. package/dist/prompts/promptForText.js +12 -0
  91. package/dist/prompts/promptForText.js.map +1 -0
  92. package/dist/services/context.js +174 -1
  93. package/dist/services/context.js.map +1 -1
  94. package/dist/services/telemetry.js +4 -2
  95. package/dist/services/telemetry.js.map +1 -1
  96. package/dist/telemetry/cli.telemetry.js +1 -1
  97. package/dist/telemetry/cli.telemetry.js.map +1 -1
  98. package/dist/telemetry/init.telemetry.js +1 -1
  99. package/dist/telemetry/init.telemetry.js.map +1 -1
  100. package/dist/telemetry/typegen.telemetry.js +12 -0
  101. package/dist/telemetry/typegen.telemetry.js.map +1 -0
  102. package/dist/util/parseArguments.js +12 -40
  103. package/dist/util/parseArguments.js.map +1 -1
  104. package/dist/util/sharedFlags.js.map +1 -1
  105. package/dist/util/telemetry/cliCommandIdentity.js +222 -0
  106. package/dist/util/telemetry/cliCommandIdentity.js.map +1 -0
  107. package/dist/util/telemetry/cliTelemetryFlags.js +186 -0
  108. package/dist/util/telemetry/cliTelemetryFlags.js.map +1 -0
  109. package/dist/util/telemetry/commandTelemetry.js +56 -11
  110. package/dist/util/telemetry/commandTelemetry.js.map +1 -1
  111. package/dist/util/telemetry/createTelemetryStore.js +13 -5
  112. package/dist/util/telemetry/createTelemetryStore.js.map +1 -1
  113. package/dist/util/telemetry/createTraceId.js +3 -3
  114. package/dist/util/telemetry/createTraceId.js.map +1 -1
  115. package/dist/util/telemetry/flushTelemetryFiles.js +14 -4
  116. package/dist/util/telemetry/flushTelemetryFiles.js.map +1 -1
  117. package/dist/util/telemetry/logger.js +1 -1
  118. package/dist/util/telemetry/logger.js.map +1 -1
  119. package/dist/util/telemetry/readNDJSON.js +1 -1
  120. package/dist/util/telemetry/readNDJSON.js.map +1 -1
  121. package/dist/util/telemetry/sanitizeTelemetryEvent.js +304 -0
  122. package/dist/util/telemetry/sanitizeTelemetryEvent.js.map +1 -0
  123. package/dist/util/telemetry/trace.js +4 -7
  124. package/dist/util/telemetry/trace.js.map +1 -1
  125. package/oclif.config.js +1 -1
  126. package/oclif.manifest.json +2380 -1526
  127. package/package.json +8 -11
@@ -2,7 +2,7 @@ import { Args, Flags } from '@oclif/core';
2
2
  import { colorizeJson, exitCodes, SanityCommand, subdebug } from '@sanity/cli-core';
3
3
  import { getErrorMessage } from '@sanity/cli-core/errors';
4
4
  import { isRecord } from '@sanity/cli-core/util';
5
- import { MissingOrganizationError, resolveOrganizationId } from '../../actions/context/resolveOrganizationId.js';
5
+ import { resolveOrganizationId } from '../../actions/context/resolveOrganizationId.js';
6
6
  import { queryContext } from '../../services/context.js';
7
7
  import { getOrganizationFlag } from '../../util/sharedFlags.js';
8
8
  import { defineCommandTelemetry } from '../../util/telemetry/commandTelemetry.js';
@@ -57,19 +57,11 @@ export class QueryContextCommand extends SanityCommand {
57
57
  async run() {
58
58
  const { query } = this.args;
59
59
  const { json, organization, params } = this.flags;
60
- let organizationId;
61
- try {
62
- organizationId = await resolveOrganizationId({
63
- configuredOrganizationId: (await this.tryGetCliConfig()).app?.organizationId,
64
- flagOrganizationId: organization,
65
- unattended: this.isUnattended()
66
- });
67
- } catch (error) {
68
- queryContextDebug('Error resolving organization', error);
69
- this.error(getErrorMessage(error), {
70
- exit: error instanceof MissingOrganizationError ? exitCodes.USAGE_ERROR : exitCodes.RUNTIME_ERROR
71
- });
72
- }
60
+ const organizationId = await resolveOrganizationId({
61
+ configuredOrganizationId: (await this.tryGetCliConfig()).app?.organizationId,
62
+ flagOrganizationId: organization,
63
+ unattended: this.isUnattended()
64
+ });
73
65
  let result;
74
66
  try {
75
67
  result = await queryContext(organizationId, query, params);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/commands/context/query.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {type FlagInput} from '@oclif/core/interfaces'\nimport {colorizeJson, exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {isRecord} from '@sanity/cli-core/util'\n\nimport {\n MissingOrganizationError,\n resolveOrganizationId,\n} from '../../actions/context/resolveOrganizationId.js'\nimport {queryContext} from '../../services/context.js'\nimport {getOrganizationFlag} from '../../util/sharedFlags.js'\nimport {defineCommandTelemetry} from '../../util/telemetry/commandTelemetry.js'\n\nconst queryContextDebug = subdebug('context:query')\n\nconst flags = {\n ...getOrganizationFlag({\n description: 'Organization to query',\n semantics: 'override',\n }),\n params: Flags.custom<Record<string, unknown>>({\n description: 'Query parameters as a JSON object',\n helpValue: '<json>',\n parse: async (input: string) => {\n let parsed: unknown\n try {\n parsed = JSON.parse(input)\n } catch {\n throw new Error('`--params` must be valid JSON')\n }\n if (!isRecord(parsed)) {\n throw new Error('`--params` must be a JSON object, like \\'{\"type\": \"issue\"}\\'')\n }\n return parsed\n },\n })(),\n} satisfies FlagInput\n\nexport class QueryContextCommand extends SanityCommand<typeof QueryContextCommand> {\n static override args = {\n query: Args.string({\n description: \"GROQ query to run against the organization's Context documents\",\n required: true,\n }),\n }\n\n static override description = \"Query an organization's Context documents with GROQ\"\n\n static override enableJsonFlag = true\n\n static override examples = [\n {\n command:\n '<%= config.bin %> <%= command.id %> \\'*[_type == \"sanity.context.issue\" && status == \"open\"]{_id, knowledgeBaseId}\\'',\n description: 'List open issues across all knowledge bases',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> \\'*[_type == \"sanity.context.entry\" && knowledgeBaseId == $kb].path\\' --params \\'{\"kb\": \"kb-abc123\"}\\' --json',\n description: 'List the entry paths of one knowledge base as plain JSON',\n },\n ]\n\n static override flags = flags\n\n static telemetry = defineCommandTelemetry(flags, {redact: ['params']})\n\n public async run(): Promise<void> {\n const {query} = this.args\n const {json, organization, params} = this.flags\n\n let organizationId: string\n try {\n organizationId = await resolveOrganizationId({\n configuredOrganizationId: (await this.tryGetCliConfig()).app?.organizationId,\n flagOrganizationId: organization,\n unattended: this.isUnattended(),\n })\n } catch (error) {\n queryContextDebug('Error resolving organization', error)\n this.error(getErrorMessage(error), {\n exit:\n error instanceof MissingOrganizationError\n ? exitCodes.USAGE_ERROR\n : exitCodes.RUNTIME_ERROR,\n })\n }\n\n let result\n try {\n result = await queryContext(organizationId, query, params)\n } catch (error) {\n queryContextDebug('Error running query', error)\n this.error(`Failed to run query: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n // GROQ returns null for no match; guard undefined, which colorizeJson cannot tokenize\n const output = result ?? null\n if (json) {\n this.logJson(output)\n return\n }\n\n this.log(colorizeJson(output))\n }\n}\n"],"names":["Args","Flags","colorizeJson","exitCodes","SanityCommand","subdebug","getErrorMessage","isRecord","MissingOrganizationError","resolveOrganizationId","queryContext","getOrganizationFlag","defineCommandTelemetry","queryContextDebug","flags","description","semantics","params","custom","helpValue","parse","input","parsed","JSON","Error","QueryContextCommand","args","query","string","required","enableJsonFlag","examples","command","telemetry","redact","run","json","organization","organizationId","configuredOrganizationId","tryGetCliConfig","app","flagOrganizationId","unattended","isUnattended","error","exit","USAGE_ERROR","RUNTIME_ERROR","result","output","logJson","log"],"mappings":"AAAA,SAAQA,IAAI,EAAEC,KAAK,QAAO,cAAa;AAEvC,SAAQC,YAAY,EAAEC,SAAS,EAAEC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACjF,SAAQC,eAAe,QAAO,0BAAyB;AACvD,SAAQC,QAAQ,QAAO,wBAAuB;AAE9C,SACEC,wBAAwB,EACxBC,qBAAqB,QAChB,iDAAgD;AACvD,SAAQC,YAAY,QAAO,4BAA2B;AACtD,SAAQC,mBAAmB,QAAO,4BAA2B;AAC7D,SAAQC,sBAAsB,QAAO,2CAA0C;AAE/E,MAAMC,oBAAoBR,SAAS;AAEnC,MAAMS,QAAQ;IACZ,GAAGH,oBAAoB;QACrBI,aAAa;QACbC,WAAW;IACb,EAAE;IACFC,QAAQhB,MAAMiB,MAAM,CAA0B;QAC5CH,aAAa;QACbI,WAAW;QACXC,OAAO,OAAOC;YACZ,IAAIC;YACJ,IAAI;gBACFA,SAASC,KAAKH,KAAK,CAACC;YACtB,EAAE,OAAM;gBACN,MAAM,IAAIG,MAAM;YAClB;YACA,IAAI,CAACjB,SAASe,SAAS;gBACrB,MAAM,IAAIE,MAAM;YAClB;YACA,OAAOF;QACT;IACF;AACF;AAEA,OAAO,MAAMG,4BAA4BrB;IACvC,OAAgBsB,OAAO;QACrBC,OAAO3B,KAAK4B,MAAM,CAAC;YACjBb,aAAa;YACbc,UAAU;QACZ;IACF,EAAC;IAED,OAAgBd,cAAc,sDAAqD;IAEnF,OAAgBe,iBAAiB,KAAI;IAErC,OAAgBC,WAAW;QACzB;YACEC,SACE;YACFjB,aAAa;QACf;QACA;YACEiB,SACE;YACFjB,aAAa;QACf;KACD,CAAA;IAED,OAAgBD,QAAQA,MAAK;IAE7B,OAAOmB,YAAYrB,uBAAuBE,OAAO;QAACoB,QAAQ;YAAC;SAAS;IAAA,GAAE;IAEtE,MAAaC,MAAqB;QAChC,MAAM,EAACR,KAAK,EAAC,GAAG,IAAI,CAACD,IAAI;QACzB,MAAM,EAACU,IAAI,EAAEC,YAAY,EAAEpB,MAAM,EAAC,GAAG,IAAI,CAACH,KAAK;QAE/C,IAAIwB;QACJ,IAAI;YACFA,iBAAiB,MAAM7B,sBAAsB;gBAC3C8B,0BAA0B,AAAC,CAAA,MAAM,IAAI,CAACC,eAAe,EAAC,EAAGC,GAAG,EAAEH;gBAC9DI,oBAAoBL;gBACpBM,YAAY,IAAI,CAACC,YAAY;YAC/B;QACF,EAAE,OAAOC,OAAO;YACdhC,kBAAkB,gCAAgCgC;YAClD,IAAI,CAACA,KAAK,CAACvC,gBAAgBuC,QAAQ;gBACjCC,MACED,iBAAiBrC,2BACbL,UAAU4C,WAAW,GACrB5C,UAAU6C,aAAa;YAC/B;QACF;QAEA,IAAIC;QACJ,IAAI;YACFA,SAAS,MAAMvC,aAAa4B,gBAAgBX,OAAOV;QACrD,EAAE,OAAO4B,OAAO;YACdhC,kBAAkB,uBAAuBgC;YACzC,IAAI,CAACA,KAAK,CAAC,CAAC,qBAAqB,EAAEvC,gBAAgBuC,QAAQ,EAAE;gBAC3DC,MAAM3C,UAAU6C,aAAa;YAC/B;QACF;QAEA,sFAAsF;QACtF,MAAME,SAASD,UAAU;QACzB,IAAIb,MAAM;YACR,IAAI,CAACe,OAAO,CAACD;YACb;QACF;QAEA,IAAI,CAACE,GAAG,CAAClD,aAAagD;IACxB;AACF"}
1
+ {"version":3,"sources":["../../../src/commands/context/query.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {type FlagInput} from '@oclif/core/interfaces'\nimport {colorizeJson, exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {isRecord} from '@sanity/cli-core/util'\n\nimport {resolveOrganizationId} from '../../actions/context/resolveOrganizationId.js'\nimport {queryContext} from '../../services/context.js'\nimport {getOrganizationFlag} from '../../util/sharedFlags.js'\nimport {defineCommandTelemetry} from '../../util/telemetry/commandTelemetry.js'\n\nconst queryContextDebug = subdebug('context:query')\n\nconst flags = {\n ...getOrganizationFlag({\n description: 'Organization to query',\n semantics: 'override',\n }),\n params: Flags.custom<Record<string, unknown>>({\n description: 'Query parameters as a JSON object',\n helpValue: '<json>',\n parse: async (input: string) => {\n let parsed: unknown\n try {\n parsed = JSON.parse(input)\n } catch {\n throw new Error('`--params` must be valid JSON')\n }\n if (!isRecord(parsed)) {\n throw new Error('`--params` must be a JSON object, like \\'{\"type\": \"issue\"}\\'')\n }\n return parsed\n },\n })(),\n} satisfies FlagInput\n\nexport class QueryContextCommand extends SanityCommand<typeof QueryContextCommand> {\n static override args = {\n query: Args.string({\n description: \"GROQ query to run against the organization's Context documents\",\n required: true,\n }),\n }\n\n static override description = \"Query an organization's Context documents with GROQ\"\n\n static override enableJsonFlag = true\n\n static override examples = [\n {\n command:\n '<%= config.bin %> <%= command.id %> \\'*[_type == \"sanity.context.issue\" && status == \"open\"]{_id, knowledgeBaseId}\\'',\n description: 'List open issues across all knowledge bases',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> \\'*[_type == \"sanity.context.entry\" && knowledgeBaseId == $kb].path\\' --params \\'{\"kb\": \"kb-abc123\"}\\' --json',\n description: 'List the entry paths of one knowledge base as plain JSON',\n },\n ]\n\n static override flags = flags\n\n static telemetry = defineCommandTelemetry(flags, {redact: ['params']})\n\n public async run(): Promise<void> {\n const {query} = this.args\n const {json, organization, params} = this.flags\n\n const organizationId = await resolveOrganizationId({\n configuredOrganizationId: (await this.tryGetCliConfig()).app?.organizationId,\n flagOrganizationId: organization,\n unattended: this.isUnattended(),\n })\n\n let result\n try {\n result = await queryContext(organizationId, query, params)\n } catch (error) {\n queryContextDebug('Error running query', error)\n this.error(`Failed to run query: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n // GROQ returns null for no match; guard undefined, which colorizeJson cannot tokenize\n const output = result ?? null\n if (json) {\n this.logJson(output)\n return\n }\n\n this.log(colorizeJson(output))\n }\n}\n"],"names":["Args","Flags","colorizeJson","exitCodes","SanityCommand","subdebug","getErrorMessage","isRecord","resolveOrganizationId","queryContext","getOrganizationFlag","defineCommandTelemetry","queryContextDebug","flags","description","semantics","params","custom","helpValue","parse","input","parsed","JSON","Error","QueryContextCommand","args","query","string","required","enableJsonFlag","examples","command","telemetry","redact","run","json","organization","organizationId","configuredOrganizationId","tryGetCliConfig","app","flagOrganizationId","unattended","isUnattended","result","error","exit","RUNTIME_ERROR","output","logJson","log"],"mappings":"AAAA,SAAQA,IAAI,EAAEC,KAAK,QAAO,cAAa;AAEvC,SAAQC,YAAY,EAAEC,SAAS,EAAEC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACjF,SAAQC,eAAe,QAAO,0BAAyB;AACvD,SAAQC,QAAQ,QAAO,wBAAuB;AAE9C,SAAQC,qBAAqB,QAAO,iDAAgD;AACpF,SAAQC,YAAY,QAAO,4BAA2B;AACtD,SAAQC,mBAAmB,QAAO,4BAA2B;AAC7D,SAAQC,sBAAsB,QAAO,2CAA0C;AAE/E,MAAMC,oBAAoBP,SAAS;AAEnC,MAAMQ,QAAQ;IACZ,GAAGH,oBAAoB;QACrBI,aAAa;QACbC,WAAW;IACb,EAAE;IACFC,QAAQf,MAAMgB,MAAM,CAA0B;QAC5CH,aAAa;QACbI,WAAW;QACXC,OAAO,OAAOC;YACZ,IAAIC;YACJ,IAAI;gBACFA,SAASC,KAAKH,KAAK,CAACC;YACtB,EAAE,OAAM;gBACN,MAAM,IAAIG,MAAM;YAClB;YACA,IAAI,CAAChB,SAASc,SAAS;gBACrB,MAAM,IAAIE,MAAM;YAClB;YACA,OAAOF;QACT;IACF;AACF;AAEA,OAAO,MAAMG,4BAA4BpB;IACvC,OAAgBqB,OAAO;QACrBC,OAAO1B,KAAK2B,MAAM,CAAC;YACjBb,aAAa;YACbc,UAAU;QACZ;IACF,EAAC;IAED,OAAgBd,cAAc,sDAAqD;IAEnF,OAAgBe,iBAAiB,KAAI;IAErC,OAAgBC,WAAW;QACzB;YACEC,SACE;YACFjB,aAAa;QACf;QACA;YACEiB,SACE;YACFjB,aAAa;QACf;KACD,CAAA;IAED,OAAgBD,QAAQA,MAAK;IAE7B,OAAOmB,YAAYrB,uBAAuBE,OAAO;QAACoB,QAAQ;YAAC;SAAS;IAAA,GAAE;IAEtE,MAAaC,MAAqB;QAChC,MAAM,EAACR,KAAK,EAAC,GAAG,IAAI,CAACD,IAAI;QACzB,MAAM,EAACU,IAAI,EAAEC,YAAY,EAAEpB,MAAM,EAAC,GAAG,IAAI,CAACH,KAAK;QAE/C,MAAMwB,iBAAiB,MAAM7B,sBAAsB;YACjD8B,0BAA0B,AAAC,CAAA,MAAM,IAAI,CAACC,eAAe,EAAC,EAAGC,GAAG,EAAEH;YAC9DI,oBAAoBL;YACpBM,YAAY,IAAI,CAACC,YAAY;QAC/B;QAEA,IAAIC;QACJ,IAAI;YACFA,SAAS,MAAMnC,aAAa4B,gBAAgBX,OAAOV;QACrD,EAAE,OAAO6B,OAAO;YACdjC,kBAAkB,uBAAuBiC;YACzC,IAAI,CAACA,KAAK,CAAC,CAAC,qBAAqB,EAAEvC,gBAAgBuC,QAAQ,EAAE;gBAC3DC,MAAM3C,UAAU4C,aAAa;YAC/B;QACF;QAEA,sFAAsF;QACtF,MAAMC,SAASJ,UAAU;QACzB,IAAIT,MAAM;YACR,IAAI,CAACc,OAAO,CAACD;YACb;QACF;QAEA,IAAI,CAACE,GAAG,CAAChD,aAAa8C;IACxB;AACF"}
@@ -3,7 +3,7 @@ import { exitCodes, SanityCommand, subdebug } from '@sanity/cli-core';
3
3
  import { getErrorMessage } from '@sanity/cli-core/errors';
4
4
  import { spinner } from '@sanity/cli-core/ux';
5
5
  import { isHttpError } from '@sanity/client';
6
- import { updateKnowledgeBase } from '../../services/context.js';
6
+ import { describeBlueprintManager, getKnowledgeBaseBlueprintOwnership, updateKnowledgeBase } from '../../services/context.js';
7
7
  import { defineCommandTelemetry } from '../../util/telemetry/commandTelemetry.js';
8
8
  const updateContextDebug = subdebug('context:update');
9
9
  const UPDATE_FLAGS = [
@@ -104,6 +104,17 @@ export class UpdateKnowledgeBaseCommand extends SanityCommand {
104
104
  if (refreshFrequency !== undefined) {
105
105
  params.refreshFrequency = refreshFrequency;
106
106
  }
107
+ const changesBlueprintFields = params.title !== undefined || params.description !== undefined;
108
+ const ownership = changesBlueprintFields ? await getKnowledgeBaseBlueprintOwnership(knowledgeBaseId) : {
109
+ managed: false
110
+ };
111
+ if (ownership.managed) {
112
+ const manager = describeBlueprintManager(ownership.stackName);
113
+ const refreshHint = params.refreshEnabled === undefined && params.refreshFrequency === undefined ? '' : ' Refresh settings are not managed by the blueprint, so you can change them without `--title` and `--description`.';
114
+ this.error(`${manager} manages the title and description of knowledge base "${knowledgeBaseId}", so the next deploy would undo this change. Change them in the blueprint and run \`sanity blueprints deploy\` instead.${refreshHint}`, {
115
+ exit: exitCodes.USAGE_ERROR
116
+ });
117
+ }
107
118
  const spin = spinner('Updating knowledge base').start();
108
119
  try {
109
120
  await updateKnowledgeBase(knowledgeBaseId, params);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/commands/context/update.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {type FlagInput} from '@oclif/core/interfaces'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {type Context, isHttpError} from '@sanity/client'\n\nimport {updateKnowledgeBase} from '../../services/context.js'\nimport {defineCommandTelemetry} from '../../util/telemetry/commandTelemetry.js'\n\nconst updateContextDebug = subdebug('context:update')\n\nconst UPDATE_FLAGS = ['title', 'description', 'refresh-enabled', 'refresh-frequency'] as const\n\nconst flags = {\n description: Flags.string({\n atLeastOne: [...UPDATE_FLAGS],\n description: 'New knowledge base description',\n required: false,\n }),\n 'refresh-enabled': Flags.boolean({\n allowNo: true,\n atLeastOne: [...UPDATE_FLAGS],\n description: 'Enable scheduled refresh (--no-refresh-enabled to disable)',\n required: false,\n }),\n 'refresh-frequency': Flags.custom<'monthly' | 'weekly'>({\n atLeastOne: [...UPDATE_FLAGS],\n description: 'How often scheduled refresh runs',\n options: ['weekly', 'monthly'],\n required: false,\n })(),\n title: Flags.string({\n atLeastOne: [...UPDATE_FLAGS],\n description: 'New knowledge base title',\n required: false,\n }),\n} satisfies FlagInput\n\nexport class UpdateKnowledgeBaseCommand extends SanityCommand<typeof UpdateKnowledgeBaseCommand> {\n static override args = {\n knowledgeBaseId: Args.string({\n description: 'Knowledge base ID',\n required: true,\n }),\n }\n\n static override description = 'Update a knowledge base'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 --title \"New title\"',\n description: 'Rename a knowledge base',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> kb-abc123 --refresh-enabled --refresh-frequency weekly',\n description: 'Enable weekly scheduled refresh',\n },\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 --no-refresh-enabled',\n description: 'Disable scheduled refresh',\n },\n ]\n\n static override flags = flags\n\n static telemetry = defineCommandTelemetry(flags, {redact: ['title', 'description']})\n\n public async run(): Promise<void> {\n const {knowledgeBaseId} = this.args\n const {\n description,\n 'refresh-enabled': refreshEnabled,\n 'refresh-frequency': refreshFrequency,\n title,\n } = this.flags\n\n const params: Context.EditKnowledgeBaseParams = {}\n if (title !== undefined) {\n const trimmedTitle = title.trim()\n if (trimmedTitle === '') {\n this.error('Title cannot be empty', {exit: exitCodes.USAGE_ERROR})\n }\n params.title = trimmedTitle\n }\n if (description !== undefined) {\n const trimmedDescription = description.trim()\n if (trimmedDescription === '') {\n this.error('Description cannot be empty', {exit: exitCodes.USAGE_ERROR})\n }\n params.description = trimmedDescription\n }\n if (refreshEnabled !== undefined) {\n params.refreshEnabled = refreshEnabled\n }\n if (refreshFrequency !== undefined) {\n params.refreshFrequency = refreshFrequency\n }\n\n const spin = spinner('Updating knowledge base').start()\n try {\n await updateKnowledgeBase(knowledgeBaseId, params)\n spin.succeed()\n this.log('Knowledge base updated')\n } catch (error) {\n spin.fail()\n updateContextDebug('Error updating knowledge base', error)\n if (isHttpError(error) && error.statusCode === 404) {\n this.error(`Knowledge base \"${knowledgeBaseId}\" not found`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n this.error(`Failed to update knowledge base: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n }\n}\n"],"names":["Args","Flags","exitCodes","SanityCommand","subdebug","getErrorMessage","spinner","isHttpError","updateKnowledgeBase","defineCommandTelemetry","updateContextDebug","UPDATE_FLAGS","flags","description","string","atLeastOne","required","boolean","allowNo","custom","options","title","UpdateKnowledgeBaseCommand","args","knowledgeBaseId","examples","command","telemetry","redact","run","refreshEnabled","refreshFrequency","params","undefined","trimmedTitle","trim","error","exit","USAGE_ERROR","trimmedDescription","spin","start","succeed","log","fail","statusCode","RUNTIME_ERROR"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/commands/context/update.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {type FlagInput} from '@oclif/core/interfaces'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {type Context, isHttpError} from '@sanity/client'\n\nimport {\n type BlueprintOwnership,\n describeBlueprintManager,\n getKnowledgeBaseBlueprintOwnership,\n updateKnowledgeBase,\n} from '../../services/context.js'\nimport {defineCommandTelemetry} from '../../util/telemetry/commandTelemetry.js'\n\nconst updateContextDebug = subdebug('context:update')\n\nconst UPDATE_FLAGS = ['title', 'description', 'refresh-enabled', 'refresh-frequency'] as const\n\nconst flags = {\n description: Flags.string({\n atLeastOne: [...UPDATE_FLAGS],\n description: 'New knowledge base description',\n required: false,\n }),\n 'refresh-enabled': Flags.boolean({\n allowNo: true,\n atLeastOne: [...UPDATE_FLAGS],\n description: 'Enable scheduled refresh (--no-refresh-enabled to disable)',\n required: false,\n }),\n 'refresh-frequency': Flags.custom<'monthly' | 'weekly'>({\n atLeastOne: [...UPDATE_FLAGS],\n description: 'How often scheduled refresh runs',\n options: ['weekly', 'monthly'],\n required: false,\n })(),\n title: Flags.string({\n atLeastOne: [...UPDATE_FLAGS],\n description: 'New knowledge base title',\n required: false,\n }),\n} satisfies FlagInput\n\nexport class UpdateKnowledgeBaseCommand extends SanityCommand<typeof UpdateKnowledgeBaseCommand> {\n static override args = {\n knowledgeBaseId: Args.string({\n description: 'Knowledge base ID',\n required: true,\n }),\n }\n\n static override description = 'Update a knowledge base'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 --title \"New title\"',\n description: 'Rename a knowledge base',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> kb-abc123 --refresh-enabled --refresh-frequency weekly',\n description: 'Enable weekly scheduled refresh',\n },\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 --no-refresh-enabled',\n description: 'Disable scheduled refresh',\n },\n ]\n\n static override flags = flags\n\n static telemetry = defineCommandTelemetry(flags, {\n redact: ['title', 'description'],\n })\n\n public async run(): Promise<void> {\n const {knowledgeBaseId} = this.args\n const {\n description,\n 'refresh-enabled': refreshEnabled,\n 'refresh-frequency': refreshFrequency,\n title,\n } = this.flags\n\n const params: Context.EditKnowledgeBaseParams = {}\n if (title !== undefined) {\n const trimmedTitle = title.trim()\n if (trimmedTitle === '') {\n this.error('Title cannot be empty', {exit: exitCodes.USAGE_ERROR})\n }\n params.title = trimmedTitle\n }\n if (description !== undefined) {\n const trimmedDescription = description.trim()\n if (trimmedDescription === '') {\n this.error('Description cannot be empty', {\n exit: exitCodes.USAGE_ERROR,\n })\n }\n params.description = trimmedDescription\n }\n if (refreshEnabled !== undefined) {\n params.refreshEnabled = refreshEnabled\n }\n if (refreshFrequency !== undefined) {\n params.refreshFrequency = refreshFrequency\n }\n\n const changesBlueprintFields = params.title !== undefined || params.description !== undefined\n const ownership: BlueprintOwnership = changesBlueprintFields\n ? await getKnowledgeBaseBlueprintOwnership(knowledgeBaseId)\n : {managed: false}\n if (ownership.managed) {\n const manager = describeBlueprintManager(ownership.stackName)\n const refreshHint =\n params.refreshEnabled === undefined && params.refreshFrequency === undefined\n ? ''\n : ' Refresh settings are not managed by the blueprint, so you can change them without `--title` and `--description`.'\n this.error(\n `${manager} manages the title and description of knowledge base \"${knowledgeBaseId}\", so the next deploy would undo this change. Change them in the blueprint and run \\`sanity blueprints deploy\\` instead.${refreshHint}`,\n {exit: exitCodes.USAGE_ERROR},\n )\n }\n\n const spin = spinner('Updating knowledge base').start()\n try {\n await updateKnowledgeBase(knowledgeBaseId, params)\n spin.succeed()\n this.log('Knowledge base updated')\n } catch (error) {\n spin.fail()\n updateContextDebug('Error updating knowledge base', error)\n if (isHttpError(error) && error.statusCode === 404) {\n this.error(`Knowledge base \"${knowledgeBaseId}\" not found`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n this.error(`Failed to update knowledge base: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n }\n}\n"],"names":["Args","Flags","exitCodes","SanityCommand","subdebug","getErrorMessage","spinner","isHttpError","describeBlueprintManager","getKnowledgeBaseBlueprintOwnership","updateKnowledgeBase","defineCommandTelemetry","updateContextDebug","UPDATE_FLAGS","flags","description","string","atLeastOne","required","boolean","allowNo","custom","options","title","UpdateKnowledgeBaseCommand","args","knowledgeBaseId","examples","command","telemetry","redact","run","refreshEnabled","refreshFrequency","params","undefined","trimmedTitle","trim","error","exit","USAGE_ERROR","trimmedDescription","changesBlueprintFields","ownership","managed","manager","stackName","refreshHint","spin","start","succeed","log","fail","statusCode","RUNTIME_ERROR"],"mappings":"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"}
@@ -7,6 +7,7 @@ import { promptForProject } from '../../prompts/promptForProject.js';
7
7
  import { listDatasets } from '../../services/datasets.js';
8
8
  import { getProjectFeatures } from '../../services/getProjectFeatures.js';
9
9
  import { getProjectIdFlag } from '../../util/sharedFlags.js';
10
+ import { defineCommandTelemetry } from '../../util/telemetry/commandTelemetry.js';
10
11
  const createDatasetDebug = subdebug('dataset:create');
11
12
  const ALLOWED_ACL_MODES = [
12
13
  'custom',
@@ -59,6 +60,11 @@ export class CreateDatasetCommand extends SanityCommand {
59
60
  static hiddenAliases = [
60
61
  'dataset:create'
61
62
  ];
63
+ static telemetry = defineCommandTelemetry(this.flags, {
64
+ redact: [
65
+ 'embeddings-projection'
66
+ ]
67
+ });
62
68
  async run() {
63
69
  const { args, flags } = await this.parse(CreateDatasetCommand);
64
70
  const { visibility } = flags;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/commands/datasets/create.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\n\nimport {createDataset} from '../../actions/dataset/create.js'\nimport {validateDatasetName} from '../../actions/dataset/validateDatasetName.js'\nimport {promptForDatasetName} from '../../prompts/promptForDatasetName.js'\nimport {promptForProject} from '../../prompts/promptForProject.js'\nimport {listDatasets} from '../../services/datasets.js'\nimport {getProjectFeatures} from '../../services/getProjectFeatures.js'\nimport {getProjectIdFlag} from '../../util/sharedFlags.js'\n\nconst createDatasetDebug = subdebug('dataset:create')\n\nconst ALLOWED_ACL_MODES = ['custom', 'private', 'public']\n\nexport class CreateDatasetCommand extends SanityCommand<typeof CreateDatasetCommand> {\n static override args = {\n name: Args.string({\n description: 'Name of the dataset to create',\n required: false,\n }),\n }\n\n static override description = 'Create a new dataset for the project'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Interactively create a dataset',\n },\n {\n command: '<%= config.bin %> <%= command.id %> my-dataset',\n description: 'Create a dataset named \"my-dataset\"',\n },\n {\n command: '<%= config.bin %> <%= command.id %> my-dataset --visibility private',\n description: 'Create a private dataset named \"my-dataset\"',\n },\n ]\n\n static override flags = {\n ...getProjectIdFlag({\n description: 'Project ID to create dataset in',\n semantics: 'override',\n }),\n embeddings: Flags.boolean({\n default: false,\n description: 'Enable embeddings for this dataset',\n }),\n 'embeddings-projection': Flags.string({\n dependsOn: ['embeddings'],\n description: 'GROQ projection for embeddings indexing (e.g. \"{ title, body }\")',\n }),\n visibility: Flags.string({\n description: 'Set visibility for this dataset (custom/private/public)',\n options: ALLOWED_ACL_MODES,\n required: false,\n }),\n }\n\n static override hiddenAliases: string[] = ['dataset:create']\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(CreateDatasetCommand)\n const {visibility} = flags\n\n // Ensure we have project context\n const projectId = await this.getProjectId({\n fallback: () =>\n promptForProject({\n requiredPermissions: [\n {grant: 'read', permission: 'sanity.project.datasets'},\n {grant: 'create', permission: 'sanity.project.datasets'},\n ],\n }),\n })\n\n // Get dataset name from args or prompt\n let {name: datasetName} = args\n if (datasetName) {\n const nameError = validateDatasetName(datasetName)\n if (nameError) {\n this.error(nameError, {exit: exitCodes.USAGE_ERROR})\n }\n } else {\n if (this.isUnattended()) {\n this.error('Dataset name is required. Pass it as the `<name>` argument.', {\n exit: exitCodes.USAGE_ERROR,\n })\n }\n datasetName = await promptForDatasetName()\n }\n\n let datasets: string[]\n let projectFeatures: string[]\n\n try {\n const [datasetsResponse, featuresResponse] = await Promise.all([\n listDatasets(projectId),\n getProjectFeatures(projectId),\n ])\n datasets = datasetsResponse.map((ds) => ds.name)\n projectFeatures = featuresResponse\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n createDatasetDebug(`Failed to fetch project data: ${message}`, error)\n this.error(`Failed to fetch project data: ${message}`, {exit: exitCodes.RUNTIME_ERROR})\n }\n\n if (datasets.includes(datasetName)) {\n this.error(`Dataset \"${datasetName}\" already exists`, {exit: exitCodes.RUNTIME_ERROR})\n }\n\n const canCreatePrivate = projectFeatures.includes('privateDataset')\n createDatasetDebug('%s create private datasets', canCreatePrivate ? 'Can' : 'Cannot')\n\n try {\n await createDataset({\n datasetName,\n embeddings: flags.embeddings,\n embeddingsProjection: flags['embeddings-projection'],\n isUnattended: this.isUnattended(),\n output: this.output,\n projectFeatures,\n projectId,\n visibility,\n })\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n this.error(`Failed to create dataset: ${message}`, {exit: exitCodes.RUNTIME_ERROR})\n }\n }\n}\n"],"names":["Args","Flags","exitCodes","SanityCommand","subdebug","createDataset","validateDatasetName","promptForDatasetName","promptForProject","listDatasets","getProjectFeatures","getProjectIdFlag","createDatasetDebug","ALLOWED_ACL_MODES","CreateDatasetCommand","args","name","string","description","required","examples","command","flags","semantics","embeddings","boolean","default","dependsOn","visibility","options","hiddenAliases","run","parse","projectId","getProjectId","fallback","requiredPermissions","grant","permission","datasetName","nameError","error","exit","USAGE_ERROR","isUnattended","datasets","projectFeatures","datasetsResponse","featuresResponse","Promise","all","map","ds","message","Error","String","RUNTIME_ERROR","includes","canCreatePrivate","embeddingsProjection","output"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/commands/datasets/create.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\n\nimport {createDataset} from '../../actions/dataset/create.js'\nimport {validateDatasetName} from '../../actions/dataset/validateDatasetName.js'\nimport {promptForDatasetName} from '../../prompts/promptForDatasetName.js'\nimport {promptForProject} from '../../prompts/promptForProject.js'\nimport {listDatasets} from '../../services/datasets.js'\nimport {getProjectFeatures} from '../../services/getProjectFeatures.js'\nimport {getProjectIdFlag} from '../../util/sharedFlags.js'\nimport {defineCommandTelemetry} from '../../util/telemetry/commandTelemetry.js'\n\nconst createDatasetDebug = subdebug('dataset:create')\n\nconst ALLOWED_ACL_MODES = ['custom', 'private', 'public']\n\nexport class CreateDatasetCommand extends SanityCommand<typeof CreateDatasetCommand> {\n static override args = {\n name: Args.string({\n description: 'Name of the dataset to create',\n required: false,\n }),\n }\n\n static override description = 'Create a new dataset for the project'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Interactively create a dataset',\n },\n {\n command: '<%= config.bin %> <%= command.id %> my-dataset',\n description: 'Create a dataset named \"my-dataset\"',\n },\n {\n command: '<%= config.bin %> <%= command.id %> my-dataset --visibility private',\n description: 'Create a private dataset named \"my-dataset\"',\n },\n ]\n\n static override flags = {\n ...getProjectIdFlag({\n description: 'Project ID to create dataset in',\n semantics: 'override',\n }),\n embeddings: Flags.boolean({\n default: false,\n description: 'Enable embeddings for this dataset',\n }),\n 'embeddings-projection': Flags.string({\n dependsOn: ['embeddings'],\n description: 'GROQ projection for embeddings indexing (e.g. \"{ title, body }\")',\n }),\n visibility: Flags.string({\n description: 'Set visibility for this dataset (custom/private/public)',\n options: ALLOWED_ACL_MODES,\n required: false,\n }),\n }\n\n static override hiddenAliases: string[] = ['dataset:create']\n\n static telemetry = defineCommandTelemetry(this.flags, {redact: ['embeddings-projection']})\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(CreateDatasetCommand)\n const {visibility} = flags\n\n // Ensure we have project context\n const projectId = await this.getProjectId({\n fallback: () =>\n promptForProject({\n requiredPermissions: [\n {grant: 'read', permission: 'sanity.project.datasets'},\n {grant: 'create', permission: 'sanity.project.datasets'},\n ],\n }),\n })\n\n // Get dataset name from args or prompt\n let {name: datasetName} = args\n if (datasetName) {\n const nameError = validateDatasetName(datasetName)\n if (nameError) {\n this.error(nameError, {exit: exitCodes.USAGE_ERROR})\n }\n } else {\n if (this.isUnattended()) {\n this.error('Dataset name is required. Pass it as the `<name>` argument.', {\n exit: exitCodes.USAGE_ERROR,\n })\n }\n datasetName = await promptForDatasetName()\n }\n\n let datasets: string[]\n let projectFeatures: string[]\n\n try {\n const [datasetsResponse, featuresResponse] = await Promise.all([\n listDatasets(projectId),\n getProjectFeatures(projectId),\n ])\n datasets = datasetsResponse.map((ds) => ds.name)\n projectFeatures = featuresResponse\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n createDatasetDebug(`Failed to fetch project data: ${message}`, error)\n this.error(`Failed to fetch project data: ${message}`, {exit: exitCodes.RUNTIME_ERROR})\n }\n\n if (datasets.includes(datasetName)) {\n this.error(`Dataset \"${datasetName}\" already exists`, {exit: exitCodes.RUNTIME_ERROR})\n }\n\n const canCreatePrivate = projectFeatures.includes('privateDataset')\n createDatasetDebug('%s create private datasets', canCreatePrivate ? 'Can' : 'Cannot')\n\n try {\n await createDataset({\n datasetName,\n embeddings: flags.embeddings,\n embeddingsProjection: flags['embeddings-projection'],\n isUnattended: this.isUnattended(),\n output: this.output,\n projectFeatures,\n projectId,\n visibility,\n })\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n this.error(`Failed to create dataset: ${message}`, {exit: exitCodes.RUNTIME_ERROR})\n }\n }\n}\n"],"names":["Args","Flags","exitCodes","SanityCommand","subdebug","createDataset","validateDatasetName","promptForDatasetName","promptForProject","listDatasets","getProjectFeatures","getProjectIdFlag","defineCommandTelemetry","createDatasetDebug","ALLOWED_ACL_MODES","CreateDatasetCommand","args","name","string","description","required","examples","command","flags","semantics","embeddings","boolean","default","dependsOn","visibility","options","hiddenAliases","telemetry","redact","run","parse","projectId","getProjectId","fallback","requiredPermissions","grant","permission","datasetName","nameError","error","exit","USAGE_ERROR","isUnattended","datasets","projectFeatures","datasetsResponse","featuresResponse","Promise","all","map","ds","message","Error","String","RUNTIME_ERROR","includes","canCreatePrivate","embeddingsProjection","output"],"mappings":"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"}
@@ -7,6 +7,7 @@ import { resolveDataset } from '../../../actions/dataset/resolveDataset.js';
7
7
  import { promptForProject } from '../../../prompts/promptForProject.js';
8
8
  import { getEmbeddingsSettings, setEmbeddingsSettings } from '../../../services/embeddings.js';
9
9
  import { getProjectIdFlag } from '../../../util/sharedFlags.js';
10
+ import { defineCommandTelemetry } from '../../../util/telemetry/commandTelemetry.js';
10
11
  import { validateProjection } from '../../../util/validateProjection.js';
11
12
  const debug = subdebug('dataset:embeddings:enable');
12
13
  const INITIAL_POLL_INTERVAL_MS = 10_000;
@@ -51,6 +52,11 @@ export class DatasetEmbeddingsEnableCommand extends SanityCommand {
51
52
  static hiddenAliases = [
52
53
  'dataset:embeddings:enable'
53
54
  ];
55
+ static telemetry = defineCommandTelemetry(this.flags, {
56
+ redact: [
57
+ 'projection'
58
+ ]
59
+ });
54
60
  async run() {
55
61
  const { args, flags } = await this.parse(DatasetEmbeddingsEnableCommand);
56
62
  let { dataset } = args;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/commands/datasets/embeddings/enable.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {Args, Flags} from '@oclif/core'\nimport {CLIError} from '@oclif/core/errors'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {spinner} from '@sanity/cli-core/ux'\n\nimport {resolveDataset} from '../../../actions/dataset/resolveDataset.js'\nimport {promptForProject} from '../../../prompts/promptForProject.js'\nimport {getEmbeddingsSettings, setEmbeddingsSettings} from '../../../services/embeddings.js'\nimport {getProjectIdFlag} from '../../../util/sharedFlags.js'\nimport {validateProjection} from '../../../util/validateProjection.js'\n\nconst debug = subdebug('dataset:embeddings:enable')\n\nconst INITIAL_POLL_INTERVAL_MS = 10_000\nconst MAX_POLL_INTERVAL_MS = 10 * 60 * 1000\nconst POLL_TIMEOUT_MS = 24 * 60 * 60 * 1000\n\nexport class DatasetEmbeddingsEnableCommand extends SanityCommand<\n typeof DatasetEmbeddingsEnableCommand\n> {\n static override args = {\n dataset: Args.string({\n description: 'Dataset name to enable embeddings for',\n required: false,\n }),\n }\n\n static override description = 'Enable embeddings for a dataset'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> production',\n description: 'Enable embeddings for the production dataset',\n },\n {\n command: '<%= config.bin %> <%= command.id %> production --projection \"{ title, body }\"',\n description: 'Enable embeddings with a specific projection',\n },\n {\n command: '<%= config.bin %> <%= command.id %> production --wait',\n description: 'Enable embeddings and wait for processing to complete',\n },\n ]\n\n static override flags = {\n ...getProjectIdFlag({\n description: 'Project ID to enable embeddings for',\n semantics: 'override',\n }),\n projection: Flags.string({\n description: 'GROQ projection defining which fields to embed (e.g. \"{ title, body }\")',\n required: false,\n }),\n wait: Flags.boolean({\n default: false,\n description: 'Wait for embeddings processing to complete before returning',\n }),\n }\n\n static override hiddenAliases: string[] = ['dataset:embeddings:enable']\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(DatasetEmbeddingsEnableCommand)\n let {dataset} = args\n const {projection, wait} = flags\n\n const projectId = await this.getProjectId({\n fallback: () =>\n promptForProject({\n requiredPermissions: [\n {grant: 'read', permission: 'sanity.project.datasets'},\n {grant: 'update', permission: 'sanity.project.datasets'},\n ],\n }),\n })\n\n try {\n ;({dataset} = await resolveDataset({\n dataset,\n isUnattended: this.isUnattended(),\n output: this.output,\n projectId,\n }))\n } catch (error) {\n if (error instanceof CLIError) throw error\n const message = error instanceof Error ? error.message : String(error)\n debug(`Failed to resolve dataset: ${message}`, error)\n this.error(message, {exit: exitCodes.RUNTIME_ERROR})\n }\n\n if (projection) {\n try {\n validateProjection(projection)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n this.error(`Invalid projection: ${message}`, {exit: exitCodes.USAGE_ERROR})\n }\n }\n\n try {\n await setEmbeddingsSettings({dataset, enabled: true, projectId, projection})\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n debug(`Failed to enable embeddings: ${message}`, error)\n this.error(`Failed to enable embeddings: ${message}`, {exit: exitCodes.RUNTIME_ERROR})\n }\n\n this.log(styleText('green', `Embeddings enabled for dataset ${dataset}.`))\n if (projection) {\n this.log(`Projection: ${projection}`)\n }\n\n if (wait) {\n await this.waitForReady(projectId, dataset)\n } else {\n this.log('Processing documents in the background. Use --wait to wait for completion.')\n }\n }\n\n private async waitForReady(projectId: string, dataset: string): Promise<void> {\n const spin = spinner('Waiting for embeddings to be ready...').start()\n const deadline = Date.now() + POLL_TIMEOUT_MS\n let interval = INITIAL_POLL_INTERVAL_MS\n\n while (Date.now() < deadline) {\n await new Promise<void>((resolve) => setTimeout(resolve, interval))\n interval = Math.min(interval * 1.5, MAX_POLL_INTERVAL_MS)\n\n let settings\n try {\n settings = await getEmbeddingsSettings(projectId, dataset)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n spin.fail('Failed while waiting for embeddings.')\n this.error(`Failed while waiting for embeddings: ${message}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n debug(`Poll status: ${settings.status}, next interval: ${Math.round(interval)}ms`)\n\n if (settings.status === 'ready') {\n spin.succeed('Embeddings ready.')\n return\n }\n\n if (settings.status !== 'updating') {\n spin.fail(`Unexpected status: ${settings.status}`)\n this.error(`Embeddings entered unexpected status: ${settings.status}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n spin.text = 'Still processing...'\n }\n\n spin.fail('Timed out waiting for embeddings.')\n this.error('Timed out. Check status with: sanity dataset embeddings status', {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n}\n"],"names":["styleText","Args","Flags","CLIError","exitCodes","SanityCommand","subdebug","spinner","resolveDataset","promptForProject","getEmbeddingsSettings","setEmbeddingsSettings","getProjectIdFlag","validateProjection","debug","INITIAL_POLL_INTERVAL_MS","MAX_POLL_INTERVAL_MS","POLL_TIMEOUT_MS","DatasetEmbeddingsEnableCommand","args","dataset","string","description","required","examples","command","flags","semantics","projection","wait","boolean","default","hiddenAliases","run","parse","projectId","getProjectId","fallback","requiredPermissions","grant","permission","isUnattended","output","error","message","Error","String","exit","RUNTIME_ERROR","USAGE_ERROR","enabled","log","waitForReady","spin","start","deadline","Date","now","interval","Promise","resolve","setTimeout","Math","min","settings","fail","status","round","succeed","text"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/commands/datasets/embeddings/enable.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {Args, Flags} from '@oclif/core'\nimport {CLIError} from '@oclif/core/errors'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {spinner} from '@sanity/cli-core/ux'\n\nimport {resolveDataset} from '../../../actions/dataset/resolveDataset.js'\nimport {promptForProject} from '../../../prompts/promptForProject.js'\nimport {getEmbeddingsSettings, setEmbeddingsSettings} from '../../../services/embeddings.js'\nimport {getProjectIdFlag} from '../../../util/sharedFlags.js'\nimport {defineCommandTelemetry} from '../../../util/telemetry/commandTelemetry.js'\nimport {validateProjection} from '../../../util/validateProjection.js'\n\nconst debug = subdebug('dataset:embeddings:enable')\n\nconst INITIAL_POLL_INTERVAL_MS = 10_000\nconst MAX_POLL_INTERVAL_MS = 10 * 60 * 1000\nconst POLL_TIMEOUT_MS = 24 * 60 * 60 * 1000\n\nexport class DatasetEmbeddingsEnableCommand extends SanityCommand<\n typeof DatasetEmbeddingsEnableCommand\n> {\n static override args = {\n dataset: Args.string({\n description: 'Dataset name to enable embeddings for',\n required: false,\n }),\n }\n\n static override description = 'Enable embeddings for a dataset'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> production',\n description: 'Enable embeddings for the production dataset',\n },\n {\n command: '<%= config.bin %> <%= command.id %> production --projection \"{ title, body }\"',\n description: 'Enable embeddings with a specific projection',\n },\n {\n command: '<%= config.bin %> <%= command.id %> production --wait',\n description: 'Enable embeddings and wait for processing to complete',\n },\n ]\n\n static override flags = {\n ...getProjectIdFlag({\n description: 'Project ID to enable embeddings for',\n semantics: 'override',\n }),\n projection: Flags.string({\n description: 'GROQ projection defining which fields to embed (e.g. \"{ title, body }\")',\n required: false,\n }),\n wait: Flags.boolean({\n default: false,\n description: 'Wait for embeddings processing to complete before returning',\n }),\n }\n\n static override hiddenAliases: string[] = ['dataset:embeddings:enable']\n\n static telemetry = defineCommandTelemetry(this.flags, {redact: ['projection']})\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(DatasetEmbeddingsEnableCommand)\n let {dataset} = args\n const {projection, wait} = flags\n\n const projectId = await this.getProjectId({\n fallback: () =>\n promptForProject({\n requiredPermissions: [\n {grant: 'read', permission: 'sanity.project.datasets'},\n {grant: 'update', permission: 'sanity.project.datasets'},\n ],\n }),\n })\n\n try {\n ;({dataset} = await resolveDataset({\n dataset,\n isUnattended: this.isUnattended(),\n output: this.output,\n projectId,\n }))\n } catch (error) {\n if (error instanceof CLIError) throw error\n const message = error instanceof Error ? error.message : String(error)\n debug(`Failed to resolve dataset: ${message}`, error)\n this.error(message, {exit: exitCodes.RUNTIME_ERROR})\n }\n\n if (projection) {\n try {\n validateProjection(projection)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n this.error(`Invalid projection: ${message}`, {exit: exitCodes.USAGE_ERROR})\n }\n }\n\n try {\n await setEmbeddingsSettings({dataset, enabled: true, projectId, projection})\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n debug(`Failed to enable embeddings: ${message}`, error)\n this.error(`Failed to enable embeddings: ${message}`, {exit: exitCodes.RUNTIME_ERROR})\n }\n\n this.log(styleText('green', `Embeddings enabled for dataset ${dataset}.`))\n if (projection) {\n this.log(`Projection: ${projection}`)\n }\n\n if (wait) {\n await this.waitForReady(projectId, dataset)\n } else {\n this.log('Processing documents in the background. Use --wait to wait for completion.')\n }\n }\n\n private async waitForReady(projectId: string, dataset: string): Promise<void> {\n const spin = spinner('Waiting for embeddings to be ready...').start()\n const deadline = Date.now() + POLL_TIMEOUT_MS\n let interval = INITIAL_POLL_INTERVAL_MS\n\n while (Date.now() < deadline) {\n await new Promise<void>((resolve) => setTimeout(resolve, interval))\n interval = Math.min(interval * 1.5, MAX_POLL_INTERVAL_MS)\n\n let settings\n try {\n settings = await getEmbeddingsSettings(projectId, dataset)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n spin.fail('Failed while waiting for embeddings.')\n this.error(`Failed while waiting for embeddings: ${message}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n debug(`Poll status: ${settings.status}, next interval: ${Math.round(interval)}ms`)\n\n if (settings.status === 'ready') {\n spin.succeed('Embeddings ready.')\n return\n }\n\n if (settings.status !== 'updating') {\n spin.fail(`Unexpected status: ${settings.status}`)\n this.error(`Embeddings entered unexpected status: ${settings.status}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n spin.text = 'Still processing...'\n }\n\n spin.fail('Timed out waiting for embeddings.')\n this.error('Timed out. Check status with: sanity dataset embeddings status', {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n}\n"],"names":["styleText","Args","Flags","CLIError","exitCodes","SanityCommand","subdebug","spinner","resolveDataset","promptForProject","getEmbeddingsSettings","setEmbeddingsSettings","getProjectIdFlag","defineCommandTelemetry","validateProjection","debug","INITIAL_POLL_INTERVAL_MS","MAX_POLL_INTERVAL_MS","POLL_TIMEOUT_MS","DatasetEmbeddingsEnableCommand","args","dataset","string","description","required","examples","command","flags","semantics","projection","wait","boolean","default","hiddenAliases","telemetry","redact","run","parse","projectId","getProjectId","fallback","requiredPermissions","grant","permission","isUnattended","output","error","message","Error","String","exit","RUNTIME_ERROR","USAGE_ERROR","enabled","log","waitForReady","spin","start","deadline","Date","now","interval","Promise","resolve","setTimeout","Math","min","settings","fail","status","round","succeed","text"],"mappings":"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"}
@@ -11,6 +11,7 @@ import { promptForDatasetName } from '../../prompts/promptForDatasetName.js';
11
11
  import { promptForProject } from '../../prompts/promptForProject.js';
12
12
  import { createDataset, listDatasets } from '../../services/datasets.js';
13
13
  import { getDatasetFlag, getProjectIdFlag } from '../../util/sharedFlags.js';
14
+ import { defineCommandTelemetry } from '../../util/telemetry/commandTelemetry.js';
14
15
  const importDebug = subdebug('dataset:import');
15
16
  function getAssetsBase(source) {
16
17
  if (/^https?:\/\//i.test(source) || source === '-') {
@@ -138,6 +139,11 @@ export class ImportDatasetCommand extends SanityCommand {
138
139
  static hiddenAliases = [
139
140
  'dataset:import'
140
141
  ];
142
+ static telemetry = defineCommandTelemetry(this.flags, {
143
+ redact: [
144
+ 'token'
145
+ ]
146
+ });
141
147
  currentProgress;
142
148
  currentStep;
143
149
  spinInterval;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/commands/datasets/import.ts"],"sourcesContent":["import fs from 'node:fs'\nimport path from 'node:path'\n\nimport {Args, Flags} from '@oclif/core'\nimport {exitCodes, getProjectCliClient, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {createRequester, nodeReadableFromWeb} from '@sanity/cli-core/request'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {sanityImport} from '@sanity/import'\nimport prettyMs from 'pretty-ms'\n\nimport {NEW_DATASET_VALUE, promptForDataset} from '../../prompts/promptForDataset.js'\nimport {promptForDatasetName} from '../../prompts/promptForDatasetName.js'\nimport {promptForProject} from '../../prompts/promptForProject.js'\nimport {createDataset, listDatasets} from '../../services/datasets.js'\nimport {getDatasetFlag, getProjectIdFlag} from '../../util/sharedFlags.js'\n\nconst importDebug = subdebug('dataset:import')\n\ninterface ProgressEvent {\n step: string\n\n current?: number\n total?: number\n update?: string\n}\n\nfunction getAssetsBase(source: string): string | undefined {\n if (/^https?:\\/\\//i.test(source) || source === '-') {\n return undefined\n }\n\n try {\n const fileStats = fs.statSync(source)\n const sourceIsFolder = fileStats.isDirectory()\n return sourceIsFolder ? source : path.dirname(source)\n } catch {\n return undefined\n }\n}\n\nasync function getUriStream(uri: string): Promise<NodeJS.ReadableStream> {\n const request = createRequester()\n\n try {\n // No timeout: large dataset exports may stream for longer than get-it's\n // default request timeout, which would abort the body mid-transfer.\n const response = await request({as: 'stream', timeout: false, url: uri})\n return nodeReadableFromWeb(response.body)\n } catch (err) {\n throw new Error(`Error fetching source:\\n${(err as Error).message}`, {cause: err})\n }\n}\n\nfunction getPercentage(opts: ProgressEvent): string {\n if (!opts.total) {\n return ''\n }\n\n const percent = Math.floor(((opts.current || 0) / opts.total) * 100)\n return `[${percent}%] `\n}\n\nexport class ImportDatasetCommand extends SanityCommand<typeof ImportDatasetCommand> {\n static override args = {\n source: Args.string({\n description: 'Source file (use \"-\" for stdin)',\n required: true,\n }),\n targetDataset: Args.string({\n description: 'Target dataset (prefer --dataset flag instead)',\n required: false,\n }),\n }\n\n static override description = 'Import documents to a Sanity dataset'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> -d staging my-dataset.ndjson',\n description: 'Import \"./my-dataset.ndjson\" into dataset \"staging\"',\n },\n {\n command: 'cat my-dataset.ndjson | <%= config.bin %> <%= command.id %> -d test -',\n description: 'Import into dataset \"test\" from stdin',\n },\n {\n command: '<%= config.bin %> <%= command.id %> -p projectId -d staging my-dataset.ndjson',\n description: 'Import with explicit project ID (overrides CLI configuration)',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> -d staging -t someSecretToken my-dataset.ndjson',\n description: 'Import with an explicit token (e.g. for CI/CD)',\n },\n ]\n\n static override flags = {\n 'allow-assets-in-different-dataset': Flags.boolean({\n default: false,\n description: 'Allow asset documents to reference different project/dataset',\n }),\n 'allow-failing-assets': Flags.boolean({\n default: false,\n description: 'Skip assets that cannot be fetched/uploaded',\n }),\n 'allow-replacement-characters': Flags.boolean({\n default: false,\n description: 'Allow unicode replacement characters in imported documents',\n }),\n 'allow-system-documents': Flags.boolean({\n default: false,\n description: 'Imports system documents',\n }),\n 'asset-concurrency': Flags.integer({\n description: 'Number of parallel asset imports',\n }),\n ...getDatasetFlag({\n description: 'Dataset to import to',\n semantics: 'specify',\n }),\n missing: Flags.boolean({\n default: false,\n description: 'Skip documents that already exist',\n exclusive: ['replace'],\n }),\n ...getProjectIdFlag({\n description: 'Project ID to import to',\n semantics: 'override',\n }),\n replace: Flags.boolean({\n default: false,\n description: 'Replace documents with the same IDs',\n exclusive: ['missing'],\n }),\n 'replace-assets': Flags.boolean({\n default: false,\n description: 'Skip reuse of existing assets',\n }),\n 'skip-cross-dataset-references': Flags.boolean({\n default: false,\n description: 'Skips references to other datasets',\n }),\n token: Flags.string({\n char: 't',\n description: 'Token to authenticate with',\n env: 'SANITY_IMPORT_TOKEN',\n required: false,\n }),\n }\n\n static override hiddenAliases: string[] = ['dataset:import']\n\n private currentProgress?: ReturnType<typeof spinner>\n private currentStep?: string\n private spinInterval?: NodeJS.Timeout | null\n private stepStart?: number\n\n private static async getStream(source: string): Promise<NodeJS.ReadableStream> {\n if (/^https?:\\/\\//i.test(source)) {\n return getUriStream(source)\n }\n\n return source === '-' ? process.stdin : fs.createReadStream(source)\n }\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(ImportDatasetCommand)\n\n const {\n 'allow-assets-in-different-dataset': allowAssetsInDifferentDataset,\n 'allow-failing-assets': allowFailingAssets,\n 'allow-replacement-characters': allowReplacementCharacters,\n 'allow-system-documents': allowSystemDocuments,\n 'asset-concurrency': assetConcurrency,\n dataset: datasetFlag,\n missing,\n replace,\n 'replace-assets': replaceAssets,\n 'skip-cross-dataset-references': skipCrossDatasetReferences,\n token,\n } = flags\n\n const projectId = await this.getProjectId({\n fallback: () => promptForProject({}),\n })\n\n const {source, targetDataset: targetDatasetArg} = args\n\n if (targetDatasetArg && !datasetFlag) {\n this.output.warn(\n 'Positional dataset argument is deprecated. Use the --dataset flag instead: --dataset <name>',\n )\n }\n\n let dataset = datasetFlag ?? targetDatasetArg\n if (!dataset) {\n if (this.isUnattended()) {\n return this.output.error('Dataset is required. Pass it with `--dataset <name>`.', {\n exit: exitCodes.USAGE_ERROR,\n })\n }\n\n const datasets = await listDatasets(projectId)\n dataset = await promptForDataset({allowCreation: true, datasets})\n\n if (dataset === NEW_DATASET_VALUE) {\n const newDatasetName = await promptForDatasetName()\n\n try {\n await createDataset({datasetName: newDatasetName, projectId})\n dataset = newDatasetName\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n importDebug(`Failed to create dataset ${newDatasetName}: ${message}`, error)\n return this.output.error(`Failed to create dataset ${newDatasetName}: ${message}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n }\n }\n\n let operation: 'create' | 'createIfNotExists' | 'createOrReplace' = 'create'\n let releasesOperation: 'fail' | 'ignore' | 'replace' = 'fail'\n\n if (replace || missing) {\n operation = replace ? 'createOrReplace' : 'createIfNotExists'\n releasesOperation = replace ? 'replace' : 'ignore'\n }\n\n const client = await getProjectCliClient({\n apiVersion: 'v2025-02-19',\n dataset,\n projectId,\n requireUser: true,\n ...(token ? {token} : {}),\n })\n\n try {\n const stream = await ImportDatasetCommand.getStream(source)\n const assetsBase = getAssetsBase(source)\n\n const importOptions = {\n allowAssetsInDifferentDataset,\n allowFailingAssets,\n allowReplacementCharacters,\n allowSystemDocuments,\n client,\n onProgress: this.onProgress.bind(this),\n operation,\n releasesOperation,\n replaceAssets,\n skipCrossDatasetReferences,\n tag: 'sanity.import',\n targetDataset: dataset,\n targetProjectId: projectId,\n ...(assetsBase ? {assetsBase} : {}),\n ...(assetConcurrency === undefined ? {} : {assetConcurrency}),\n }\n\n const {numDocs, warnings} = await sanityImport(stream, importOptions)\n\n if (this.stepStart) {\n const timeSpent = prettyMs(Date.now() - this.stepStart, {secondsDecimalDigits: 2})\n if (this.currentProgress) {\n if (this.spinInterval) {\n clearInterval(this.spinInterval)\n this.spinInterval = null\n }\n this.currentProgress.text = `[100%] ${this.currentStep} (${timeSpent})`\n this.currentProgress.succeed()\n }\n }\n\n this.output.log('Done! Imported %d documents to dataset \"%s\"\\n', numDocs, dataset)\n this.printWarnings(warnings)\n } catch (err) {\n if (this.spinInterval) {\n clearInterval(this.spinInterval)\n this.spinInterval = null\n }\n\n if (this.currentProgress) {\n this.currentProgress.fail()\n }\n\n return (err as Error).name === 'ReplacementCharError'\n ? this.output.error(\n `Import failed due to unicode replacement characters in the data.\\n${(err as Error).message}\\n\\nIf you are certain you want to proceed with the import despite potentially corrupt data, re-run the import with the \\`--allow-replacement-characters\\` flag set.`,\n {exit: exitCodes.RUNTIME_ERROR},\n )\n : this.output.error((err as Error).stack || (err as Error).message, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n }\n\n private onProgress(opts: ProgressEvent): void {\n const lengthComputable = opts.total\n const sameStep = opts.step === this.currentStep\n const percent = getPercentage(opts)\n\n if (lengthComputable && opts.total === opts.current && this.spinInterval) {\n clearInterval(this.spinInterval)\n this.spinInterval = null\n }\n\n if (sameStep && !lengthComputable) {\n return\n }\n\n if (sameStep) {\n if (this.stepStart) {\n const timeSpent = prettyMs(Date.now() - this.stepStart, {secondsDecimalDigits: 2})\n if (this.currentProgress) {\n this.currentProgress.text = `${percent}${opts.step} (${timeSpent})`\n this.currentProgress.render()\n }\n }\n return\n }\n\n // Moved to a new step\n const prevStep = this.currentStep\n const prevStepStart = this.stepStart\n this.stepStart = Date.now()\n this.currentStep = opts.step\n\n if (this.spinInterval) {\n clearInterval(this.spinInterval)\n this.spinInterval = null\n }\n\n if (this.currentProgress && this.currentProgress.succeed && prevStepStart) {\n const timeSpent = prettyMs(Date.now() - prevStepStart, {\n secondsDecimalDigits: 2,\n })\n this.currentProgress.text = `[100%] ${prevStep} (${timeSpent})`\n this.currentProgress.succeed()\n }\n\n this.currentProgress = spinner(`[0%] ${opts.step} (0.00s)`).start()\n\n if (!lengthComputable) {\n this.spinInterval = setInterval(() => {\n if (this.stepStart && this.currentProgress) {\n const timeSpent = prettyMs(Date.now() - this.stepStart, {\n secondsDecimalDigits: 2,\n })\n this.currentProgress.text = `${percent}${opts.step} (${timeSpent})`\n this.currentProgress.render()\n }\n }, 60)\n }\n }\n\n private printWarnings(warnings: Array<{message: string; type?: string; url?: string}>): void {\n const assetFails = warnings.filter((warn) => warn.type === 'asset')\n\n if (assetFails.length === 0) {\n return\n }\n\n this.output.warn(\n `Failed to import the following ${assetFails.length > 1 ? 'assets' : 'asset'}:`,\n )\n\n for (const warning of assetFails) {\n if (warning.url) {\n this.output.warn(` ${warning.url}`)\n }\n }\n }\n}\n"],"names":["fs","path","Args","Flags","exitCodes","getProjectCliClient","SanityCommand","subdebug","createRequester","nodeReadableFromWeb","spinner","sanityImport","prettyMs","NEW_DATASET_VALUE","promptForDataset","promptForDatasetName","promptForProject","createDataset","listDatasets","getDatasetFlag","getProjectIdFlag","importDebug","getAssetsBase","source","test","undefined","fileStats","statSync","sourceIsFolder","isDirectory","dirname","getUriStream","uri","request","response","as","timeout","url","body","err","Error","message","cause","getPercentage","opts","total","percent","Math","floor","current","ImportDatasetCommand","args","string","description","required","targetDataset","examples","command","flags","boolean","default","integer","semantics","missing","exclusive","replace","token","char","env","hiddenAliases","currentProgress","currentStep","spinInterval","stepStart","getStream","process","stdin","createReadStream","run","parse","allowAssetsInDifferentDataset","allowFailingAssets","allowReplacementCharacters","allowSystemDocuments","assetConcurrency","dataset","datasetFlag","replaceAssets","skipCrossDatasetReferences","projectId","getProjectId","fallback","targetDatasetArg","output","warn","isUnattended","error","exit","USAGE_ERROR","datasets","allowCreation","newDatasetName","datasetName","String","RUNTIME_ERROR","operation","releasesOperation","client","apiVersion","requireUser","stream","assetsBase","importOptions","onProgress","bind","tag","targetProjectId","numDocs","warnings","timeSpent","Date","now","secondsDecimalDigits","clearInterval","text","succeed","log","printWarnings","fail","name","stack","lengthComputable","sameStep","step","render","prevStep","prevStepStart","start","setInterval","assetFails","filter","type","length","warning"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/commands/datasets/import.ts"],"sourcesContent":["import fs from 'node:fs'\nimport path from 'node:path'\n\nimport {Args, Flags} from '@oclif/core'\nimport {exitCodes, getProjectCliClient, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {createRequester, nodeReadableFromWeb} from '@sanity/cli-core/request'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {sanityImport} from '@sanity/import'\nimport prettyMs from 'pretty-ms'\n\nimport {NEW_DATASET_VALUE, promptForDataset} from '../../prompts/promptForDataset.js'\nimport {promptForDatasetName} from '../../prompts/promptForDatasetName.js'\nimport {promptForProject} from '../../prompts/promptForProject.js'\nimport {createDataset, listDatasets} from '../../services/datasets.js'\nimport {getDatasetFlag, getProjectIdFlag} from '../../util/sharedFlags.js'\nimport {defineCommandTelemetry} from '../../util/telemetry/commandTelemetry.js'\n\nconst importDebug = subdebug('dataset:import')\n\ninterface ProgressEvent {\n step: string\n\n current?: number\n total?: number\n update?: string\n}\n\nfunction getAssetsBase(source: string): string | undefined {\n if (/^https?:\\/\\//i.test(source) || source === '-') {\n return undefined\n }\n\n try {\n const fileStats = fs.statSync(source)\n const sourceIsFolder = fileStats.isDirectory()\n return sourceIsFolder ? source : path.dirname(source)\n } catch {\n return undefined\n }\n}\n\nasync function getUriStream(uri: string): Promise<NodeJS.ReadableStream> {\n const request = createRequester()\n\n try {\n // No timeout: large dataset exports may stream for longer than get-it's\n // default request timeout, which would abort the body mid-transfer.\n const response = await request({as: 'stream', timeout: false, url: uri})\n return nodeReadableFromWeb(response.body)\n } catch (err) {\n throw new Error(`Error fetching source:\\n${(err as Error).message}`, {cause: err})\n }\n}\n\nfunction getPercentage(opts: ProgressEvent): string {\n if (!opts.total) {\n return ''\n }\n\n const percent = Math.floor(((opts.current || 0) / opts.total) * 100)\n return `[${percent}%] `\n}\n\nexport class ImportDatasetCommand extends SanityCommand<typeof ImportDatasetCommand> {\n static override args = {\n source: Args.string({\n description: 'Source file (use \"-\" for stdin)',\n required: true,\n }),\n targetDataset: Args.string({\n description: 'Target dataset (prefer --dataset flag instead)',\n required: false,\n }),\n }\n\n static override description = 'Import documents to a Sanity dataset'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> -d staging my-dataset.ndjson',\n description: 'Import \"./my-dataset.ndjson\" into dataset \"staging\"',\n },\n {\n command: 'cat my-dataset.ndjson | <%= config.bin %> <%= command.id %> -d test -',\n description: 'Import into dataset \"test\" from stdin',\n },\n {\n command: '<%= config.bin %> <%= command.id %> -p projectId -d staging my-dataset.ndjson',\n description: 'Import with explicit project ID (overrides CLI configuration)',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> -d staging -t someSecretToken my-dataset.ndjson',\n description: 'Import with an explicit token (e.g. for CI/CD)',\n },\n ]\n\n static override flags = {\n 'allow-assets-in-different-dataset': Flags.boolean({\n default: false,\n description: 'Allow asset documents to reference different project/dataset',\n }),\n 'allow-failing-assets': Flags.boolean({\n default: false,\n description: 'Skip assets that cannot be fetched/uploaded',\n }),\n 'allow-replacement-characters': Flags.boolean({\n default: false,\n description: 'Allow unicode replacement characters in imported documents',\n }),\n 'allow-system-documents': Flags.boolean({\n default: false,\n description: 'Imports system documents',\n }),\n 'asset-concurrency': Flags.integer({\n description: 'Number of parallel asset imports',\n }),\n ...getDatasetFlag({\n description: 'Dataset to import to',\n semantics: 'specify',\n }),\n missing: Flags.boolean({\n default: false,\n description: 'Skip documents that already exist',\n exclusive: ['replace'],\n }),\n ...getProjectIdFlag({\n description: 'Project ID to import to',\n semantics: 'override',\n }),\n replace: Flags.boolean({\n default: false,\n description: 'Replace documents with the same IDs',\n exclusive: ['missing'],\n }),\n 'replace-assets': Flags.boolean({\n default: false,\n description: 'Skip reuse of existing assets',\n }),\n 'skip-cross-dataset-references': Flags.boolean({\n default: false,\n description: 'Skips references to other datasets',\n }),\n token: Flags.string({\n char: 't',\n description: 'Token to authenticate with',\n env: 'SANITY_IMPORT_TOKEN',\n required: false,\n }),\n }\n\n static override hiddenAliases: string[] = ['dataset:import']\n\n static telemetry = defineCommandTelemetry(this.flags, {redact: ['token']})\n\n private currentProgress?: ReturnType<typeof spinner>\n private currentStep?: string\n private spinInterval?: NodeJS.Timeout | null\n private stepStart?: number\n\n private static async getStream(source: string): Promise<NodeJS.ReadableStream> {\n if (/^https?:\\/\\//i.test(source)) {\n return getUriStream(source)\n }\n\n return source === '-' ? process.stdin : fs.createReadStream(source)\n }\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(ImportDatasetCommand)\n\n const {\n 'allow-assets-in-different-dataset': allowAssetsInDifferentDataset,\n 'allow-failing-assets': allowFailingAssets,\n 'allow-replacement-characters': allowReplacementCharacters,\n 'allow-system-documents': allowSystemDocuments,\n 'asset-concurrency': assetConcurrency,\n dataset: datasetFlag,\n missing,\n replace,\n 'replace-assets': replaceAssets,\n 'skip-cross-dataset-references': skipCrossDatasetReferences,\n token,\n } = flags\n\n const projectId = await this.getProjectId({\n fallback: () => promptForProject({}),\n })\n\n const {source, targetDataset: targetDatasetArg} = args\n\n if (targetDatasetArg && !datasetFlag) {\n this.output.warn(\n 'Positional dataset argument is deprecated. Use the --dataset flag instead: --dataset <name>',\n )\n }\n\n let dataset = datasetFlag ?? targetDatasetArg\n if (!dataset) {\n if (this.isUnattended()) {\n return this.output.error('Dataset is required. Pass it with `--dataset <name>`.', {\n exit: exitCodes.USAGE_ERROR,\n })\n }\n\n const datasets = await listDatasets(projectId)\n dataset = await promptForDataset({allowCreation: true, datasets})\n\n if (dataset === NEW_DATASET_VALUE) {\n const newDatasetName = await promptForDatasetName()\n\n try {\n await createDataset({datasetName: newDatasetName, projectId})\n dataset = newDatasetName\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n importDebug(`Failed to create dataset ${newDatasetName}: ${message}`, error)\n return this.output.error(`Failed to create dataset ${newDatasetName}: ${message}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n }\n }\n\n let operation: 'create' | 'createIfNotExists' | 'createOrReplace' = 'create'\n let releasesOperation: 'fail' | 'ignore' | 'replace' = 'fail'\n\n if (replace || missing) {\n operation = replace ? 'createOrReplace' : 'createIfNotExists'\n releasesOperation = replace ? 'replace' : 'ignore'\n }\n\n const client = await getProjectCliClient({\n apiVersion: 'v2025-02-19',\n dataset,\n projectId,\n requireUser: true,\n ...(token ? {token} : {}),\n })\n\n try {\n const stream = await ImportDatasetCommand.getStream(source)\n const assetsBase = getAssetsBase(source)\n\n const importOptions = {\n allowAssetsInDifferentDataset,\n allowFailingAssets,\n allowReplacementCharacters,\n allowSystemDocuments,\n client,\n onProgress: this.onProgress.bind(this),\n operation,\n releasesOperation,\n replaceAssets,\n skipCrossDatasetReferences,\n tag: 'sanity.import',\n targetDataset: dataset,\n targetProjectId: projectId,\n ...(assetsBase ? {assetsBase} : {}),\n ...(assetConcurrency === undefined ? {} : {assetConcurrency}),\n }\n\n const {numDocs, warnings} = await sanityImport(stream, importOptions)\n\n if (this.stepStart) {\n const timeSpent = prettyMs(Date.now() - this.stepStart, {secondsDecimalDigits: 2})\n if (this.currentProgress) {\n if (this.spinInterval) {\n clearInterval(this.spinInterval)\n this.spinInterval = null\n }\n this.currentProgress.text = `[100%] ${this.currentStep} (${timeSpent})`\n this.currentProgress.succeed()\n }\n }\n\n this.output.log('Done! Imported %d documents to dataset \"%s\"\\n', numDocs, dataset)\n this.printWarnings(warnings)\n } catch (err) {\n if (this.spinInterval) {\n clearInterval(this.spinInterval)\n this.spinInterval = null\n }\n\n if (this.currentProgress) {\n this.currentProgress.fail()\n }\n\n return (err as Error).name === 'ReplacementCharError'\n ? this.output.error(\n `Import failed due to unicode replacement characters in the data.\\n${(err as Error).message}\\n\\nIf you are certain you want to proceed with the import despite potentially corrupt data, re-run the import with the \\`--allow-replacement-characters\\` flag set.`,\n {exit: exitCodes.RUNTIME_ERROR},\n )\n : this.output.error((err as Error).stack || (err as Error).message, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n }\n\n private onProgress(opts: ProgressEvent): void {\n const lengthComputable = opts.total\n const sameStep = opts.step === this.currentStep\n const percent = getPercentage(opts)\n\n if (lengthComputable && opts.total === opts.current && this.spinInterval) {\n clearInterval(this.spinInterval)\n this.spinInterval = null\n }\n\n if (sameStep && !lengthComputable) {\n return\n }\n\n if (sameStep) {\n if (this.stepStart) {\n const timeSpent = prettyMs(Date.now() - this.stepStart, {secondsDecimalDigits: 2})\n if (this.currentProgress) {\n this.currentProgress.text = `${percent}${opts.step} (${timeSpent})`\n this.currentProgress.render()\n }\n }\n return\n }\n\n // Moved to a new step\n const prevStep = this.currentStep\n const prevStepStart = this.stepStart\n this.stepStart = Date.now()\n this.currentStep = opts.step\n\n if (this.spinInterval) {\n clearInterval(this.spinInterval)\n this.spinInterval = null\n }\n\n if (this.currentProgress && this.currentProgress.succeed && prevStepStart) {\n const timeSpent = prettyMs(Date.now() - prevStepStart, {\n secondsDecimalDigits: 2,\n })\n this.currentProgress.text = `[100%] ${prevStep} (${timeSpent})`\n this.currentProgress.succeed()\n }\n\n this.currentProgress = spinner(`[0%] ${opts.step} (0.00s)`).start()\n\n if (!lengthComputable) {\n this.spinInterval = setInterval(() => {\n if (this.stepStart && this.currentProgress) {\n const timeSpent = prettyMs(Date.now() - this.stepStart, {\n secondsDecimalDigits: 2,\n })\n this.currentProgress.text = `${percent}${opts.step} (${timeSpent})`\n this.currentProgress.render()\n }\n }, 60)\n }\n }\n\n private printWarnings(warnings: Array<{message: string; type?: string; url?: string}>): void {\n const assetFails = warnings.filter((warn) => warn.type === 'asset')\n\n if (assetFails.length === 0) {\n return\n }\n\n this.output.warn(\n `Failed to import the following ${assetFails.length > 1 ? 'assets' : 'asset'}:`,\n )\n\n for (const warning of assetFails) {\n if (warning.url) {\n this.output.warn(` ${warning.url}`)\n }\n }\n }\n}\n"],"names":["fs","path","Args","Flags","exitCodes","getProjectCliClient","SanityCommand","subdebug","createRequester","nodeReadableFromWeb","spinner","sanityImport","prettyMs","NEW_DATASET_VALUE","promptForDataset","promptForDatasetName","promptForProject","createDataset","listDatasets","getDatasetFlag","getProjectIdFlag","defineCommandTelemetry","importDebug","getAssetsBase","source","test","undefined","fileStats","statSync","sourceIsFolder","isDirectory","dirname","getUriStream","uri","request","response","as","timeout","url","body","err","Error","message","cause","getPercentage","opts","total","percent","Math","floor","current","ImportDatasetCommand","args","string","description","required","targetDataset","examples","command","flags","boolean","default","integer","semantics","missing","exclusive","replace","token","char","env","hiddenAliases","telemetry","redact","currentProgress","currentStep","spinInterval","stepStart","getStream","process","stdin","createReadStream","run","parse","allowAssetsInDifferentDataset","allowFailingAssets","allowReplacementCharacters","allowSystemDocuments","assetConcurrency","dataset","datasetFlag","replaceAssets","skipCrossDatasetReferences","projectId","getProjectId","fallback","targetDatasetArg","output","warn","isUnattended","error","exit","USAGE_ERROR","datasets","allowCreation","newDatasetName","datasetName","String","RUNTIME_ERROR","operation","releasesOperation","client","apiVersion","requireUser","stream","assetsBase","importOptions","onProgress","bind","tag","targetProjectId","numDocs","warnings","timeSpent","Date","now","secondsDecimalDigits","clearInterval","text","succeed","log","printWarnings","fail","name","stack","lengthComputable","sameStep","step","render","prevStep","prevStepStart","start","setInterval","assetFails","filter","type","length","warning"],"mappings":"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"}
@@ -9,6 +9,7 @@ import { deployStudio } from '../actions/deploy/deployStudio.js';
9
9
  import { getAppId } from '../util/appId.js';
10
10
  import { determineIsApp } from '../util/determineIsApp.js';
11
11
  import { dirIsEmptyOrNonExistent } from '../util/dirIsEmptyOrNonExistent.js';
12
+ import { defineCommandTelemetry } from '../util/telemetry/commandTelemetry.js';
12
13
  export class DeployCommand extends SanityCommand {
13
14
  static args = {
14
15
  sourceDir: Args.directory({
@@ -121,6 +122,12 @@ export class DeployCommand extends SanityCommand {
121
122
  description: 'Unattended mode, answers "yes" to any "yes/no" prompt and otherwise uses defaults'
122
123
  })
123
124
  };
125
+ static telemetry = defineCommandTelemetry(this.flags, {
126
+ redact: [
127
+ 'title',
128
+ 'url'
129
+ ]
130
+ });
124
131
  async run() {
125
132
  const { flags } = await this.parse(DeployCommand);
126
133
  const cliConfig = await this.getCliConfig();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/deploy.ts"],"sourcesContent":["import path from 'node:path'\n\nimport {Args, Flags} from '@oclif/core'\nimport {exitCodes, SanityCommand} from '@sanity/cli-core'\nimport {confirm} from '@sanity/cli-core/ux'\nimport {getWorkbench, resolveWorkbenchConfig} from '@sanity/workbench-cli/deploy'\n\nimport {deployApp} from '../actions/deploy/deployApp.js'\nimport {deployDebug} from '../actions/deploy/deployDebug.js'\nimport {deployStudio} from '../actions/deploy/deployStudio.js'\nimport {getAppId} from '../util/appId.js'\nimport {determineIsApp} from '../util/determineIsApp.js'\nimport {dirIsEmptyOrNonExistent} from '../util/dirIsEmptyOrNonExistent.js'\n\nexport class DeployCommand extends SanityCommand<typeof DeployCommand> {\n static override args = {\n sourceDir: Args.directory({\n description: 'Source directory',\n }),\n }\n\n static override description = 'Builds and deploys Sanity Studio or application to Sanity hosting'\n\n static override enableJsonFlag = true\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Build and deploy the studio to Sanity hosting',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --no-minify --source-maps',\n description: 'Deploys non-minified build with source maps',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --schema-required',\n description:\n 'Fail fast on schema store fails - for when other services rely on the stored schema',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --external',\n description: 'Register an externally hosted studio (studioHost contains full URL)',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --external --url https://apps.example.com',\n description: 'Register an externally hosted studio, served from the provided origin',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --create --title \"My App\" --yes --json',\n description:\n 'Create and deploy an App SDK app without prompts. Save application.id as deployment.appId, then omit --create on later deploys',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --create --title \"My App\" --dry-run --json',\n description: 'Preview a new App SDK deployment without creating or uploading anything',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --url my-studio --yes',\n description: 'Deploy a studio without prompts using its hostname',\n },\n ]\n\n static override flags = {\n 'auto-updates': Flags.boolean({\n allowNo: true,\n deprecated: true,\n description: 'Automatically update the studio to the latest version',\n }),\n build: Flags.boolean({\n allowNo: true,\n default: true,\n description:\n 'Build the studio before deploying (use --no-build to deploy existing `dist/` output)',\n }),\n create: Flags.boolean({\n description: 'Create a new App SDK app, even if the organization has other apps',\n exclusive: ['external', 'url'],\n }),\n 'dry-run': Flags.boolean({\n default: false,\n description: 'Report what would be deployed without uploading or creating anything',\n }),\n external: Flags.boolean({\n default: false,\n description: 'Register an externally hosted studio',\n exclusive: ['source-maps', 'minify'],\n }),\n json: Flags.boolean({\n char: 'j',\n default: false,\n description: 'Output the result as JSON',\n }),\n 'media-library-id': Flags.string({\n description:\n 'For a Media Library config deploy: the media library to sync the aspect definitions to. Defaults to the single active library of the configured organization; required when the organization has several',\n // Part of the beta config-app flow, like the hidden media commands it\n // pairs with. A help-listed flag is hard to take back — unhide at GA.\n hidden: true,\n }),\n minify: Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Minify built JavaScript (use --no-minify to skip for faster builds)',\n }),\n 'schema-required': Flags.boolean({\n default: false,\n description: 'Fail if schema deployment fails',\n }),\n 'source-maps': Flags.boolean({\n default: false,\n description: 'Enable source maps for built bundles (increases size of bundle)',\n }),\n title: Flags.string({\n description:\n 'Title for a newly created application or studio. For apps, use --create to select creation when the organization already has apps',\n }),\n url: Flags.string({\n description:\n 'Studio URL for deployment. For external deploys, the full URL. For hosted studios, the hostname (e.g. \"my-studio\" or \"my-studio.sanity.studio\")',\n }),\n verbose: Flags.boolean({\n default: false,\n description: 'Enable verbose logging',\n }),\n yes: Flags.boolean({\n char: 'y',\n default: false,\n description:\n 'Unattended mode, answers \"yes\" to any \"yes/no\" prompt and otherwise uses defaults',\n }),\n }\n\n public async run(): Promise<void> {\n const {flags} = await this.parse(DeployCommand)\n\n const cliConfig = await this.getCliConfig()\n const projectRoot = await this.getProjectRoot()\n\n const isApp = determineIsApp(cliConfig)\n\n // `--media-library-id` only steers the aspect-document sync of a Media\n // Library config deploy (see deployApp); studio and app deploys never read\n // it. Warned rather than silently dropped (same courtesy init gives\n // --dashboard on the media template).\n if (flags['media-library-id'] && !resolveWorkbenchConfig(cliConfig)) {\n this.output.warn(\n '--media-library-id is ignored — it only applies when deploying a Media Library config',\n )\n }\n\n if (flags.create) {\n if (!isApp) {\n return this.output.error(\n '--create is only supported for App SDK apps. For a studio, use --url <hostname>.',\n )\n }\n if (getAppId(cliConfig)) {\n return this.output.error(\n '--create cannot be used with a configured app ID. Omit --create to deploy to that app, or remove deployment.appId and app.id to create a new one.',\n )\n }\n if (getWorkbench(cliConfig) || resolveWorkbenchConfig(cliConfig)) {\n return this.output.error(\n '--create is not supported for this app configuration. Omit --create and run sanity deploy.',\n )\n }\n }\n\n const defaultOutputDir = path.resolve(path.join(projectRoot.directory, 'dist'))\n const sourceDir = path.resolve(process.cwd(), this.args.sourceDir || defaultOutputDir)\n\n // Skip the directory check if the studio is externally hosted\n if (this.args.sourceDir && this.args.sourceDir !== 'dist' && !flags.external) {\n let relativeOutput = path.relative(process.cwd(), sourceDir)\n if (relativeOutput[0] !== '.') {\n relativeOutput = `./${relativeOutput}`\n }\n\n if (!this.isUnattended() && !flags['dry-run']) {\n const isEmpty = await dirIsEmptyOrNonExistent(sourceDir)\n const shouldProceed =\n isEmpty ||\n (await confirm({\n default: false,\n message: `\"${relativeOutput}\" is not empty, do you want to proceed?`,\n }))\n\n if (!shouldProceed) {\n this.output.error('Cancelled.', {exit: exitCodes.RUNTIME_ERROR})\n }\n }\n\n // Keep --json's stdout clean for the payload\n if (!flags.json) this.output.log(`Building to ${relativeOutput}\\n`)\n }\n\n // Force yes downstream: build/app resolution otherwise prompts for prerelease/version choices\n const deployFlags = this.isUnattended() || flags['dry-run'] ? {...flags, yes: true} : flags\n\n if (isApp) {\n deployDebug('Deploying app')\n await deployApp({\n cliConfig,\n flags: deployFlags,\n output: this.output,\n projectRoot,\n sourceDir,\n })\n } else {\n deployDebug('Deploying studio')\n await deployStudio({\n cliConfig,\n flags: deployFlags,\n output: this.output,\n projectRoot,\n sourceDir,\n })\n }\n }\n}\n"],"names":["path","Args","Flags","exitCodes","SanityCommand","confirm","getWorkbench","resolveWorkbenchConfig","deployApp","deployDebug","deployStudio","getAppId","determineIsApp","dirIsEmptyOrNonExistent","DeployCommand","args","sourceDir","directory","description","enableJsonFlag","examples","command","flags","boolean","allowNo","deprecated","build","default","create","exclusive","external","json","char","string","hidden","minify","title","url","verbose","yes","run","parse","cliConfig","getCliConfig","projectRoot","getProjectRoot","isApp","output","warn","error","defaultOutputDir","resolve","join","process","cwd","relativeOutput","relative","isUnattended","isEmpty","shouldProceed","message","exit","RUNTIME_ERROR","log","deployFlags"],"mappings":"AAAA,OAAOA,UAAU,YAAW;AAE5B,SAAQC,IAAI,EAAEC,KAAK,QAAO,cAAa;AACvC,SAAQC,SAAS,EAAEC,aAAa,QAAO,mBAAkB;AACzD,SAAQC,OAAO,QAAO,sBAAqB;AAC3C,SAAQC,YAAY,EAAEC,sBAAsB,QAAO,+BAA8B;AAEjF,SAAQC,SAAS,QAAO,iCAAgC;AACxD,SAAQC,WAAW,QAAO,mCAAkC;AAC5D,SAAQC,YAAY,QAAO,oCAAmC;AAC9D,SAAQC,QAAQ,QAAO,mBAAkB;AACzC,SAAQC,cAAc,QAAO,4BAA2B;AACxD,SAAQC,uBAAuB,QAAO,qCAAoC;AAE1E,OAAO,MAAMC,sBAAsBV;IACjC,OAAgBW,OAAO;QACrBC,WAAWf,KAAKgB,SAAS,CAAC;YACxBC,aAAa;QACf;IACF,EAAC;IAED,OAAgBA,cAAc,oEAAmE;IAEjG,OAAgBC,iBAAiB,KAAI;IAErC,OAAgBC,WAAW;QACzB;YACEC,SAAS;YACTH,aAAa;QACf;QACA;YACEG,SAAS;YACTH,aAAa;QACf;QACA;YACEG,SAAS;YACTH,aACE;QACJ;QACA;YACEG,SAAS;YACTH,aAAa;QACf;QACA;YACEG,SAAS;YACTH,aAAa;QACf;QACA;YACEG,SAAS;YACTH,aACE;QACJ;QACA;YACEG,SAAS;YACTH,aAAa;QACf;QACA;YACEG,SAAS;YACTH,aAAa;QACf;KACD,CAAA;IAED,OAAgBI,QAAQ;QACtB,gBAAgBpB,MAAMqB,OAAO,CAAC;YAC5BC,SAAS;YACTC,YAAY;YACZP,aAAa;QACf;QACAQ,OAAOxB,MAAMqB,OAAO,CAAC;YACnBC,SAAS;YACTG,SAAS;YACTT,aACE;QACJ;QACAU,QAAQ1B,MAAMqB,OAAO,CAAC;YACpBL,aAAa;YACbW,WAAW;gBAAC;gBAAY;aAAM;QAChC;QACA,WAAW3B,MAAMqB,OAAO,CAAC;YACvBI,SAAS;YACTT,aAAa;QACf;QACAY,UAAU5B,MAAMqB,OAAO,CAAC;YACtBI,SAAS;YACTT,aAAa;YACbW,WAAW;gBAAC;gBAAe;aAAS;QACtC;QACAE,MAAM7B,MAAMqB,OAAO,CAAC;YAClBS,MAAM;YACNL,SAAS;YACTT,aAAa;QACf;QACA,oBAAoBhB,MAAM+B,MAAM,CAAC;YAC/Bf,aACE;YACF,sEAAsE;YACtE,sEAAsE;YACtEgB,QAAQ;QACV;QACAC,QAAQjC,MAAMqB,OAAO,CAAC;YACpBC,SAAS;YACTG,SAAS;YACTT,aAAa;QACf;QACA,mBAAmBhB,MAAMqB,OAAO,CAAC;YAC/BI,SAAS;YACTT,aAAa;QACf;QACA,eAAehB,MAAMqB,OAAO,CAAC;YAC3BI,SAAS;YACTT,aAAa;QACf;QACAkB,OAAOlC,MAAM+B,MAAM,CAAC;YAClBf,aACE;QACJ;QACAmB,KAAKnC,MAAM+B,MAAM,CAAC;YAChBf,aACE;QACJ;QACAoB,SAASpC,MAAMqB,OAAO,CAAC;YACrBI,SAAS;YACTT,aAAa;QACf;QACAqB,KAAKrC,MAAMqB,OAAO,CAAC;YACjBS,MAAM;YACNL,SAAS;YACTT,aACE;QACJ;IACF,EAAC;IAED,MAAasB,MAAqB;QAChC,MAAM,EAAClB,KAAK,EAAC,GAAG,MAAM,IAAI,CAACmB,KAAK,CAAC3B;QAEjC,MAAM4B,YAAY,MAAM,IAAI,CAACC,YAAY;QACzC,MAAMC,cAAc,MAAM,IAAI,CAACC,cAAc;QAE7C,MAAMC,QAAQlC,eAAe8B;QAE7B,uEAAuE;QACvE,2EAA2E;QAC3E,oEAAoE;QACpE,sCAAsC;QACtC,IAAIpB,KAAK,CAAC,mBAAmB,IAAI,CAACf,uBAAuBmC,YAAY;YACnE,IAAI,CAACK,MAAM,CAACC,IAAI,CACd;QAEJ;QAEA,IAAI1B,MAAMM,MAAM,EAAE;YAChB,IAAI,CAACkB,OAAO;gBACV,OAAO,IAAI,CAACC,MAAM,CAACE,KAAK,CACtB;YAEJ;YACA,IAAItC,SAAS+B,YAAY;gBACvB,OAAO,IAAI,CAACK,MAAM,CAACE,KAAK,CACtB;YAEJ;YACA,IAAI3C,aAAaoC,cAAcnC,uBAAuBmC,YAAY;gBAChE,OAAO,IAAI,CAACK,MAAM,CAACE,KAAK,CACtB;YAEJ;QACF;QAEA,MAAMC,mBAAmBlD,KAAKmD,OAAO,CAACnD,KAAKoD,IAAI,CAACR,YAAY3B,SAAS,EAAE;QACvE,MAAMD,YAAYhB,KAAKmD,OAAO,CAACE,QAAQC,GAAG,IAAI,IAAI,CAACvC,IAAI,CAACC,SAAS,IAAIkC;QAErE,8DAA8D;QAC9D,IAAI,IAAI,CAACnC,IAAI,CAACC,SAAS,IAAI,IAAI,CAACD,IAAI,CAACC,SAAS,KAAK,UAAU,CAACM,MAAMQ,QAAQ,EAAE;YAC5E,IAAIyB,iBAAiBvD,KAAKwD,QAAQ,CAACH,QAAQC,GAAG,IAAItC;YAClD,IAAIuC,cAAc,CAAC,EAAE,KAAK,KAAK;gBAC7BA,iBAAiB,CAAC,EAAE,EAAEA,gBAAgB;YACxC;YAEA,IAAI,CAAC,IAAI,CAACE,YAAY,MAAM,CAACnC,KAAK,CAAC,UAAU,EAAE;gBAC7C,MAAMoC,UAAU,MAAM7C,wBAAwBG;gBAC9C,MAAM2C,gBACJD,WACC,MAAMrD,QAAQ;oBACbsB,SAAS;oBACTiC,SAAS,CAAC,CAAC,EAAEL,eAAe,uCAAuC,CAAC;gBACtE;gBAEF,IAAI,CAACI,eAAe;oBAClB,IAAI,CAACZ,MAAM,CAACE,KAAK,CAAC,cAAc;wBAACY,MAAM1D,UAAU2D,aAAa;oBAAA;gBAChE;YACF;YAEA,6CAA6C;YAC7C,IAAI,CAACxC,MAAMS,IAAI,EAAE,IAAI,CAACgB,MAAM,CAACgB,GAAG,CAAC,CAAC,YAAY,EAAER,eAAe,EAAE,CAAC;QACpE;QAEA,8FAA8F;QAC9F,MAAMS,cAAc,IAAI,CAACP,YAAY,MAAMnC,KAAK,CAAC,UAAU,GAAG;YAAC,GAAGA,KAAK;YAAEiB,KAAK;QAAI,IAAIjB;QAEtF,IAAIwB,OAAO;YACTrC,YAAY;YACZ,MAAMD,UAAU;gBACdkC;gBACApB,OAAO0C;gBACPjB,QAAQ,IAAI,CAACA,MAAM;gBACnBH;gBACA5B;YACF;QACF,OAAO;YACLP,YAAY;YACZ,MAAMC,aAAa;gBACjBgC;gBACApB,OAAO0C;gBACPjB,QAAQ,IAAI,CAACA,MAAM;gBACnBH;gBACA5B;YACF;QACF;IACF;AACF"}
1
+ {"version":3,"sources":["../../src/commands/deploy.ts"],"sourcesContent":["import path from 'node:path'\n\nimport {Args, Flags} from '@oclif/core'\nimport {exitCodes, SanityCommand} from '@sanity/cli-core'\nimport {confirm} from '@sanity/cli-core/ux'\nimport {getWorkbench, resolveWorkbenchConfig} from '@sanity/workbench-cli/deploy'\n\nimport {deployApp} from '../actions/deploy/deployApp.js'\nimport {deployDebug} from '../actions/deploy/deployDebug.js'\nimport {deployStudio} from '../actions/deploy/deployStudio.js'\nimport {getAppId} from '../util/appId.js'\nimport {determineIsApp} from '../util/determineIsApp.js'\nimport {dirIsEmptyOrNonExistent} from '../util/dirIsEmptyOrNonExistent.js'\nimport {defineCommandTelemetry} from '../util/telemetry/commandTelemetry.js'\n\nexport class DeployCommand extends SanityCommand<typeof DeployCommand> {\n static override args = {\n sourceDir: Args.directory({\n description: 'Source directory',\n }),\n }\n\n static override description = 'Builds and deploys Sanity Studio or application to Sanity hosting'\n\n static override enableJsonFlag = true\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Build and deploy the studio to Sanity hosting',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --no-minify --source-maps',\n description: 'Deploys non-minified build with source maps',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --schema-required',\n description:\n 'Fail fast on schema store fails - for when other services rely on the stored schema',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --external',\n description: 'Register an externally hosted studio (studioHost contains full URL)',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --external --url https://apps.example.com',\n description: 'Register an externally hosted studio, served from the provided origin',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --create --title \"My App\" --yes --json',\n description:\n 'Create and deploy an App SDK app without prompts. Save application.id as deployment.appId, then omit --create on later deploys',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --create --title \"My App\" --dry-run --json',\n description: 'Preview a new App SDK deployment without creating or uploading anything',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --url my-studio --yes',\n description: 'Deploy a studio without prompts using its hostname',\n },\n ]\n\n static override flags = {\n 'auto-updates': Flags.boolean({\n allowNo: true,\n deprecated: true,\n description: 'Automatically update the studio to the latest version',\n }),\n build: Flags.boolean({\n allowNo: true,\n default: true,\n description:\n 'Build the studio before deploying (use --no-build to deploy existing `dist/` output)',\n }),\n create: Flags.boolean({\n description: 'Create a new App SDK app, even if the organization has other apps',\n exclusive: ['external', 'url'],\n }),\n 'dry-run': Flags.boolean({\n default: false,\n description: 'Report what would be deployed without uploading or creating anything',\n }),\n external: Flags.boolean({\n default: false,\n description: 'Register an externally hosted studio',\n exclusive: ['source-maps', 'minify'],\n }),\n json: Flags.boolean({\n char: 'j',\n default: false,\n description: 'Output the result as JSON',\n }),\n 'media-library-id': Flags.string({\n description:\n 'For a Media Library config deploy: the media library to sync the aspect definitions to. Defaults to the single active library of the configured organization; required when the organization has several',\n // Part of the beta config-app flow, like the hidden media commands it\n // pairs with. A help-listed flag is hard to take back — unhide at GA.\n hidden: true,\n }),\n minify: Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Minify built JavaScript (use --no-minify to skip for faster builds)',\n }),\n 'schema-required': Flags.boolean({\n default: false,\n description: 'Fail if schema deployment fails',\n }),\n 'source-maps': Flags.boolean({\n default: false,\n description: 'Enable source maps for built bundles (increases size of bundle)',\n }),\n title: Flags.string({\n description:\n 'Title for a newly created application or studio. For apps, use --create to select creation when the organization already has apps',\n }),\n url: Flags.string({\n description:\n 'Studio URL for deployment. For external deploys, the full URL. For hosted studios, the hostname (e.g. \"my-studio\" or \"my-studio.sanity.studio\")',\n }),\n verbose: Flags.boolean({\n default: false,\n description: 'Enable verbose logging',\n }),\n yes: Flags.boolean({\n char: 'y',\n default: false,\n description:\n 'Unattended mode, answers \"yes\" to any \"yes/no\" prompt and otherwise uses defaults',\n }),\n }\n\n static telemetry = defineCommandTelemetry(this.flags, {redact: ['title', 'url']})\n\n public async run(): Promise<void> {\n const {flags} = await this.parse(DeployCommand)\n\n const cliConfig = await this.getCliConfig()\n const projectRoot = await this.getProjectRoot()\n\n const isApp = determineIsApp(cliConfig)\n\n // `--media-library-id` only steers the aspect-document sync of a Media\n // Library config deploy (see deployApp); studio and app deploys never read\n // it. Warned rather than silently dropped (same courtesy init gives\n // --dashboard on the media template).\n if (flags['media-library-id'] && !resolveWorkbenchConfig(cliConfig)) {\n this.output.warn(\n '--media-library-id is ignored — it only applies when deploying a Media Library config',\n )\n }\n\n if (flags.create) {\n if (!isApp) {\n return this.output.error(\n '--create is only supported for App SDK apps. For a studio, use --url <hostname>.',\n )\n }\n if (getAppId(cliConfig)) {\n return this.output.error(\n '--create cannot be used with a configured app ID. Omit --create to deploy to that app, or remove deployment.appId and app.id to create a new one.',\n )\n }\n if (getWorkbench(cliConfig) || resolveWorkbenchConfig(cliConfig)) {\n return this.output.error(\n '--create is not supported for this app configuration. Omit --create and run sanity deploy.',\n )\n }\n }\n\n const defaultOutputDir = path.resolve(path.join(projectRoot.directory, 'dist'))\n const sourceDir = path.resolve(process.cwd(), this.args.sourceDir || defaultOutputDir)\n\n // Skip the directory check if the studio is externally hosted\n if (this.args.sourceDir && this.args.sourceDir !== 'dist' && !flags.external) {\n let relativeOutput = path.relative(process.cwd(), sourceDir)\n if (relativeOutput[0] !== '.') {\n relativeOutput = `./${relativeOutput}`\n }\n\n if (!this.isUnattended() && !flags['dry-run']) {\n const isEmpty = await dirIsEmptyOrNonExistent(sourceDir)\n const shouldProceed =\n isEmpty ||\n (await confirm({\n default: false,\n message: `\"${relativeOutput}\" is not empty, do you want to proceed?`,\n }))\n\n if (!shouldProceed) {\n this.output.error('Cancelled.', {exit: exitCodes.RUNTIME_ERROR})\n }\n }\n\n // Keep --json's stdout clean for the payload\n if (!flags.json) this.output.log(`Building to ${relativeOutput}\\n`)\n }\n\n // Force yes downstream: build/app resolution otherwise prompts for prerelease/version choices\n const deployFlags = this.isUnattended() || flags['dry-run'] ? {...flags, yes: true} : flags\n\n if (isApp) {\n deployDebug('Deploying app')\n await deployApp({\n cliConfig,\n flags: deployFlags,\n output: this.output,\n projectRoot,\n sourceDir,\n })\n } else {\n deployDebug('Deploying studio')\n await deployStudio({\n cliConfig,\n flags: deployFlags,\n output: this.output,\n projectRoot,\n sourceDir,\n })\n }\n }\n}\n"],"names":["path","Args","Flags","exitCodes","SanityCommand","confirm","getWorkbench","resolveWorkbenchConfig","deployApp","deployDebug","deployStudio","getAppId","determineIsApp","dirIsEmptyOrNonExistent","defineCommandTelemetry","DeployCommand","args","sourceDir","directory","description","enableJsonFlag","examples","command","flags","boolean","allowNo","deprecated","build","default","create","exclusive","external","json","char","string","hidden","minify","title","url","verbose","yes","telemetry","redact","run","parse","cliConfig","getCliConfig","projectRoot","getProjectRoot","isApp","output","warn","error","defaultOutputDir","resolve","join","process","cwd","relativeOutput","relative","isUnattended","isEmpty","shouldProceed","message","exit","RUNTIME_ERROR","log","deployFlags"],"mappings":"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"}
@@ -9,6 +9,7 @@ import { confirm, logSymbols } from '@sanity/cli-core/ux';
9
9
  import { validateDocuments } from '../../actions/documents/validate.js';
10
10
  import { reporters } from '../../actions/documents/validation/reporters/index.js';
11
11
  import { getDatasetFlag, getProjectIdFlag } from '../../util/sharedFlags.js';
12
+ import { defineCommandTelemetry } from '../../util/telemetry/commandTelemetry.js';
12
13
  export class ValidateDocumentsCommand extends SanityCommand {
13
14
  static description = 'Validate documents in a dataset against the studio schema';
14
15
  static examples = [
@@ -82,6 +83,11 @@ export class ValidateDocumentsCommand extends SanityCommand {
82
83
  static hiddenAliases = [
83
84
  'document:validate'
84
85
  ];
86
+ static telemetry = defineCommandTelemetry(this.flags, {
87
+ redact: [
88
+ 'file'
89
+ ]
90
+ });
85
91
  async run() {
86
92
  const { flags } = await this.parse(ValidateDocumentsCommand);
87
93
  const { dataset, file, format, level, 'max-custom-validation-concurrency': maxCustomValidationConcurrency, 'max-fetch-concurrency': maxFetchConcurrency, project: projectId, workspace } = flags;