@sanity/cli 6.0.0-alpha.9 → 6.1.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.
- package/README.md +602 -291
- package/bin/run.js +2 -0
- package/dist/SanityHelp.js +51 -23
- package/dist/SanityHelp.js.map +1 -1
- package/dist/actions/auth/authServer.js +28 -22
- package/dist/actions/auth/authServer.js.map +1 -1
- package/dist/actions/auth/login/getProvider.js +49 -38
- package/dist/actions/auth/login/getProvider.js.map +1 -1
- package/dist/actions/auth/login/getSSOProvider.js +25 -19
- package/dist/actions/auth/login/getSSOProvider.js.map +1 -1
- package/dist/actions/auth/login/login.js +12 -33
- package/dist/actions/auth/login/login.js.map +1 -1
- package/dist/actions/auth/types.js.map +1 -1
- package/dist/actions/backup/downloadAsset.js +9 -9
- package/dist/actions/backup/downloadAsset.js.map +1 -1
- package/dist/actions/backup/downloadDocument.js +8 -8
- package/dist/actions/backup/downloadDocument.js.map +1 -1
- package/dist/actions/build/buildApp.js +55 -18
- package/dist/actions/build/buildApp.js.map +1 -1
- package/dist/actions/build/buildStaticFiles.js +3 -2
- package/dist/actions/build/buildStaticFiles.js.map +1 -1
- package/dist/actions/build/buildStudio.js +72 -44
- package/dist/actions/build/buildStudio.js.map +1 -1
- package/dist/actions/build/buildVendorDependencies.js +18 -52
- package/dist/actions/build/buildVendorDependencies.js.map +1 -1
- package/dist/actions/build/checkRequiredDependencies.js +13 -8
- package/dist/actions/build/checkRequiredDependencies.js.map +1 -1
- package/dist/actions/build/checkStudioDependencyVersions.js +19 -17
- package/dist/actions/build/checkStudioDependencyVersions.js.map +1 -1
- package/dist/actions/build/createExternalFromImportMap.js +1 -1
- package/dist/actions/build/createExternalFromImportMap.js.map +1 -1
- package/dist/actions/build/determineBasePath.js +5 -2
- package/dist/actions/build/determineBasePath.js.map +1 -1
- package/dist/actions/build/getViteConfig.js +47 -4
- package/dist/actions/build/getViteConfig.js.map +1 -1
- package/dist/actions/build/handlePrereleaseVersions.js +44 -0
- package/dist/actions/build/handlePrereleaseVersions.js.map +1 -0
- package/dist/actions/build/renderDocument.js +6 -10
- package/dist/actions/build/renderDocument.js.map +1 -1
- package/dist/actions/build/renderDocumentWorker/components/BasicDocument.js +4 -4
- package/dist/actions/build/renderDocumentWorker/components/BasicDocument.js.map +1 -1
- package/dist/actions/build/renderDocumentWorker/components/DefaultDocument.js +3 -3
- package/dist/actions/build/renderDocumentWorker/components/DefaultDocument.js.map +1 -1
- package/dist/actions/build/renderDocumentWorker/components/GlobalErrorHandler.js +1 -0
- package/dist/actions/build/renderDocumentWorker/components/GlobalErrorHandler.js.map +1 -1
- package/dist/actions/build/renderDocumentWorker/getDocumentComponent.js +2 -2
- package/dist/actions/build/renderDocumentWorker/getDocumentComponent.js.map +1 -1
- package/dist/actions/build/renderDocumentWorker/renderDocumentWorker.js +1 -1
- package/dist/actions/build/renderDocumentWorker/renderDocumentWorker.js.map +1 -1
- package/dist/actions/build/shouldAutoUpdate.js +2 -0
- package/dist/actions/build/shouldAutoUpdate.js.map +1 -1
- package/dist/actions/build/types.js.map +1 -1
- package/dist/actions/build/writeFavicons.js +3 -5
- package/dist/actions/build/writeFavicons.js.map +1 -1
- package/dist/actions/build/writeSanityRuntime.js +4 -3
- package/dist/actions/build/writeSanityRuntime.js.map +1 -1
- package/dist/actions/codemods/reactIconsV3.js +2 -2
- package/dist/actions/codemods/reactIconsV3.js.map +1 -1
- package/dist/actions/dataset/create.js +7 -1
- package/dist/actions/dataset/create.js.map +1 -1
- package/dist/actions/dataset/determineDatasetAclMode.js.map +1 -1
- package/dist/actions/dataset/resolveDataset.js +26 -0
- package/dist/actions/dataset/resolveDataset.js.map +1 -0
- package/dist/actions/debug/formatters.js +22 -0
- package/dist/actions/debug/formatters.js.map +1 -0
- package/dist/actions/deploy/createStudioUserApplication.js +17 -4
- package/dist/actions/deploy/createStudioUserApplication.js.map +1 -1
- package/dist/actions/deploy/deployApp.js +41 -15
- package/dist/actions/deploy/deployApp.js.map +1 -1
- package/dist/actions/deploy/deployStudio.js +92 -44
- package/dist/actions/deploy/deployStudio.js.map +1 -1
- package/dist/actions/deploy/deployStudioSchemasAndManifests.js +55 -0
- package/dist/actions/deploy/deployStudioSchemasAndManifests.js.map +1 -0
- package/dist/actions/deploy/deployStudioSchemasAndManifests.worker.js +120 -0
- package/dist/actions/deploy/deployStudioSchemasAndManifests.worker.js.map +1 -0
- package/dist/actions/deploy/findUserApplicationForStudio.js +35 -12
- package/dist/actions/deploy/findUserApplicationForStudio.js.map +1 -1
- package/dist/actions/deploy/types.js +10 -1
- package/dist/actions/deploy/types.js.map +1 -1
- package/dist/actions/deploy/urlUtils.js +21 -0
- package/dist/actions/deploy/urlUtils.js.map +1 -0
- package/dist/actions/dev/getDashboardAppUrl.js +48 -0
- package/dist/actions/dev/getDashboardAppUrl.js.map +1 -0
- package/dist/actions/dev/getDevServerConfig.js +7 -3
- package/dist/actions/dev/getDevServerConfig.js.map +1 -1
- package/dist/actions/dev/startAppDevServer.js +3 -3
- package/dist/actions/dev/startAppDevServer.js.map +1 -1
- package/dist/actions/dev/startStudioDevServer.js +14 -14
- package/dist/actions/dev/startStudioDevServer.js.map +1 -1
- package/dist/actions/doctor/checks/cliInstallation.js +56 -0
- package/dist/actions/doctor/checks/cliInstallation.js.map +1 -0
- package/dist/actions/doctor/checks/index.js +16 -0
- package/dist/actions/doctor/checks/index.js.map +1 -0
- package/dist/actions/doctor/runDoctorChecks.js +56 -0
- package/dist/actions/doctor/runDoctorChecks.js.map +1 -0
- package/dist/actions/doctor/types.js +3 -0
- package/dist/actions/doctor/types.js.map +1 -0
- package/dist/actions/documents/types.js.map +1 -1
- package/dist/actions/documents/validate.js +11 -2
- package/dist/actions/documents/validate.js.map +1 -1
- package/dist/actions/documents/validateDocuments.worker.js +4 -4
- package/dist/actions/documents/validateDocuments.worker.js.map +1 -1
- package/dist/actions/documents/validation/reporters/jsonReporter.js +1 -1
- package/dist/actions/documents/validation/reporters/jsonReporter.js.map +1 -1
- package/dist/actions/documents/validation/reporters/ndjsonReporter.js +1 -1
- package/dist/actions/documents/validation/reporters/ndjsonReporter.js.map +1 -1
- package/dist/actions/documents/validation/reporters/prettyReporter/formatDocumentValidation.js +1 -1
- package/dist/actions/documents/validation/reporters/prettyReporter/formatDocumentValidation.js.map +1 -1
- package/dist/actions/documents/validation/reporters/prettyReporter/tree.js +108 -0
- package/dist/actions/documents/validation/reporters/prettyReporter/tree.js.map +1 -0
- package/dist/actions/graphql/SchemaError.js +4 -26
- package/dist/actions/graphql/SchemaError.js.map +1 -1
- package/dist/actions/graphql/__tests__/fixtures/many-self-refs.js +540 -0
- package/dist/actions/graphql/__tests__/fixtures/many-self-refs.js.map +1 -0
- package/dist/actions/graphql/__tests__/fixtures/test-studio.js +1143 -0
- package/dist/actions/graphql/__tests__/fixtures/test-studio.js.map +1 -0
- package/dist/actions/graphql/__tests__/fixtures/union-refs.js +591 -0
- package/dist/actions/graphql/__tests__/fixtures/union-refs.js.map +1 -0
- package/dist/actions/graphql/__tests__/helpers.js +23 -0
- package/dist/actions/graphql/__tests__/helpers.js.map +1 -0
- package/dist/actions/graphql/extractFromSanitySchema.js +5 -5
- package/dist/actions/graphql/extractFromSanitySchema.js.map +1 -1
- package/dist/actions/graphql/extractGraphQLAPIs.js +150 -0
- package/dist/actions/graphql/extractGraphQLAPIs.js.map +1 -0
- package/dist/actions/graphql/extractGraphQLAPIs.worker.js +12 -0
- package/dist/actions/graphql/extractGraphQLAPIs.worker.js.map +1 -0
- package/dist/actions/graphql/gen1/generateTypeFilters.js +1 -1
- package/dist/actions/graphql/gen1/generateTypeFilters.js.map +1 -1
- package/dist/actions/graphql/gen1/generateTypeQueries.js +2 -1
- package/dist/actions/graphql/gen1/generateTypeQueries.js.map +1 -1
- package/dist/actions/graphql/gen1/index.js +5 -5
- package/dist/actions/graphql/gen1/index.js.map +1 -1
- package/dist/actions/graphql/gen2/generateTypeQueries.js +1 -1
- package/dist/actions/graphql/gen2/generateTypeQueries.js.map +1 -1
- package/dist/actions/graphql/gen2/index.js +6 -6
- package/dist/actions/graphql/gen2/index.js.map +1 -1
- package/dist/actions/graphql/gen3/generateTypeQueries.js +3 -4
- package/dist/actions/graphql/gen3/generateTypeQueries.js.map +1 -1
- package/dist/actions/graphql/gen3/index.js +6 -7
- package/dist/actions/graphql/gen3/index.js.map +1 -1
- package/dist/actions/graphql/getGraphQLAPIs.js +15 -57
- package/dist/actions/graphql/getGraphQLAPIs.js.map +1 -1
- package/dist/actions/graphql/getGraphQLAPIs.worker.js +75 -106
- package/dist/actions/graphql/getGraphQLAPIs.worker.js.map +1 -1
- package/dist/actions/graphql/helpers.js +13 -0
- package/dist/actions/graphql/helpers.js.map +1 -1
- package/dist/actions/graphql/resolveGraphQLApisFromWorkspaces.js +187 -0
- package/dist/actions/graphql/resolveGraphQLApisFromWorkspaces.js.map +1 -0
- package/dist/actions/graphql/types.js +1 -1
- package/dist/actions/graphql/types.js.map +1 -1
- package/dist/actions/init/bootstrapLocalTemplate.js +10 -8
- package/dist/actions/init/bootstrapLocalTemplate.js.map +1 -1
- package/dist/actions/init/bootstrapRemoteTemplate.js +6 -5
- package/dist/actions/init/bootstrapRemoteTemplate.js.map +1 -1
- package/dist/actions/init/bootstrapTemplate.js.map +1 -1
- package/dist/actions/init/checkNextJsReactCompatibility.js +1 -1
- package/dist/actions/init/checkNextJsReactCompatibility.js.map +1 -1
- package/dist/actions/init/createAppCliConfig.js.map +1 -1
- package/dist/actions/init/createCliConfig.js.map +1 -1
- package/dist/actions/init/createPackageManifest.js +21 -9
- package/dist/actions/init/createPackageManifest.js.map +1 -1
- package/dist/actions/init/remoteTemplate.js +1 -2
- package/dist/actions/init/remoteTemplate.js.map +1 -1
- package/dist/actions/init/sdkAppDependencies.js +19 -0
- package/dist/actions/init/sdkAppDependencies.js.map +1 -0
- package/dist/actions/init/studioDependencies.js.map +1 -0
- package/dist/actions/init/templates/appQuickstart.js +1 -22
- package/dist/actions/init/templates/appQuickstart.js.map +1 -1
- package/dist/actions/init/templates/appSanityUi.js +3 -22
- package/dist/actions/init/templates/appSanityUi.js.map +1 -1
- package/dist/actions/init/types.js.map +1 -1
- package/dist/actions/manifest/SchemaIcon.js +6 -4
- package/dist/actions/manifest/SchemaIcon.js.map +1 -1
- package/dist/actions/manifest/blockTypeTransformer.js +67 -0
- package/dist/actions/manifest/blockTypeTransformer.js.map +1 -0
- package/dist/actions/manifest/debug.js +4 -0
- package/dist/actions/manifest/debug.js.map +1 -0
- package/dist/actions/manifest/extractAppManifest.js +39 -22
- package/dist/actions/manifest/extractAppManifest.js.map +1 -1
- package/dist/actions/manifest/extractManifest.js +27 -78
- package/dist/actions/manifest/extractManifest.js.map +1 -1
- package/dist/actions/manifest/extractManifest.worker.js +30 -0
- package/dist/actions/manifest/extractManifest.worker.js.map +1 -0
- package/dist/actions/manifest/extractWorkspaceManifest.js +31 -372
- package/dist/actions/manifest/extractWorkspaceManifest.js.map +1 -1
- package/dist/actions/manifest/iconResolver.js +30 -0
- package/dist/actions/manifest/iconResolver.js.map +1 -0
- package/dist/actions/manifest/referenceTransformer.js +51 -0
- package/dist/actions/manifest/referenceTransformer.js.map +1 -0
- package/dist/actions/manifest/schemaTypeHelpers.js +2 -2
- package/dist/actions/manifest/schemaTypeHelpers.js.map +1 -1
- package/dist/actions/manifest/schemaTypeTransformer.js +168 -0
- package/dist/actions/manifest/schemaTypeTransformer.js.map +1 -0
- package/dist/actions/manifest/transformerUtils.js +40 -0
- package/dist/actions/manifest/transformerUtils.js.map +1 -0
- package/dist/actions/manifest/types.js +5 -0
- package/dist/actions/manifest/types.js.map +1 -1
- package/dist/actions/manifest/validationTransformer.js +84 -0
- package/dist/actions/manifest/validationTransformer.js.map +1 -0
- package/dist/actions/manifest/writeManifestFile.js +30 -0
- package/dist/actions/manifest/writeManifestFile.js.map +1 -0
- package/dist/actions/manifest/writeWorkspaceFiles.js +30 -0
- package/dist/actions/manifest/writeWorkspaceFiles.js.map +1 -0
- package/dist/actions/mcp/detectAvailableEditors.js +34 -13
- package/dist/actions/mcp/detectAvailableEditors.js.map +1 -1
- package/dist/actions/mcp/editorConfigs.js +231 -109
- package/dist/actions/mcp/editorConfigs.js.map +1 -1
- package/dist/actions/mcp/promptForMCPSetup.js +16 -7
- package/dist/actions/mcp/promptForMCPSetup.js.map +1 -1
- package/dist/actions/mcp/setupMCP.js +62 -23
- package/dist/actions/mcp/setupMCP.js.map +1 -1
- package/dist/actions/mcp/types.js.map +1 -1
- package/dist/actions/mcp/validateEditorTokens.js +56 -0
- package/dist/actions/mcp/validateEditorTokens.js.map +1 -0
- package/dist/actions/mcp/writeMCPConfig.js +27 -15
- package/dist/actions/mcp/writeMCPConfig.js.map +1 -1
- package/dist/actions/media/buildNdjsonIndex.js +32 -0
- package/dist/actions/media/buildNdjsonIndex.js.map +1 -0
- package/dist/actions/media/importAspects.js +2 -11
- package/dist/actions/media/importAspects.js.map +1 -1
- package/dist/actions/media/importMedia.js +22 -18
- package/dist/actions/media/importMedia.js.map +1 -1
- package/dist/actions/organizations/findOrganizationByUserName.js +5 -0
- package/dist/actions/organizations/findOrganizationByUserName.js.map +1 -0
- package/dist/actions/organizations/getOrganization.js +3 -2
- package/dist/actions/organizations/getOrganization.js.map +1 -1
- package/dist/actions/organizations/getOrganizationChoices.js +27 -19
- package/dist/actions/organizations/getOrganizationChoices.js.map +1 -1
- package/dist/actions/organizations/types.js +3 -0
- package/dist/actions/organizations/types.js.map +1 -0
- package/dist/actions/projects/getManageUrl.js +1 -2
- package/dist/actions/projects/getManageUrl.js.map +1 -1
- package/dist/actions/schema/deleteSchemaAction.js +14 -30
- package/dist/actions/schema/deleteSchemaAction.js.map +1 -1
- package/dist/actions/schema/deploySchemas.js +22 -91
- package/dist/actions/schema/deploySchemas.js.map +1 -1
- package/dist/actions/schema/extractSanitySchema.worker.js +0 -5
- package/dist/actions/schema/extractSanitySchema.worker.js.map +1 -1
- package/dist/actions/schema/extractSanityWorkspace.worker.js +24 -0
- package/dist/actions/schema/extractSanityWorkspace.worker.js.map +1 -0
- package/dist/actions/schema/extractSchema.js +8 -40
- package/dist/actions/schema/extractSchema.js.map +1 -1
- package/dist/actions/schema/extractSchemaWatcher.js +128 -0
- package/dist/actions/schema/extractSchemaWatcher.js.map +1 -0
- package/dist/actions/schema/formatSchemaValidation.js +5 -1
- package/dist/actions/schema/formatSchemaValidation.js.map +1 -1
- package/dist/actions/schema/getExtractOptions.js +16 -0
- package/dist/actions/schema/getExtractOptions.js.map +1 -0
- package/dist/actions/schema/listSchemas.js +53 -56
- package/dist/actions/schema/listSchemas.js.map +1 -1
- package/dist/actions/schema/matchSchemaPattern.js +22 -0
- package/dist/actions/schema/matchSchemaPattern.js.map +1 -0
- package/dist/actions/schema/runSchemaExtraction.js +39 -0
- package/dist/actions/schema/runSchemaExtraction.js.map +1 -0
- package/dist/actions/schema/types.js +8 -0
- package/dist/actions/schema/types.js.map +1 -1
- package/dist/actions/schema/uniqueWorkspaces.worker.js +24 -0
- package/dist/actions/schema/uniqueWorkspaces.worker.js.map +1 -0
- package/dist/actions/schema/updateWorkspaceSchema.js +63 -0
- package/dist/actions/schema/updateWorkspaceSchema.js.map +1 -0
- package/dist/actions/schema/uploadSchemaToLexicon.js +87 -0
- package/dist/actions/schema/uploadSchemaToLexicon.js.map +1 -0
- package/dist/actions/schema/utils/SchemaExtractionError.js +10 -0
- package/dist/actions/schema/utils/SchemaExtractionError.js.map +1 -0
- package/dist/actions/schema/utils/schemaStoreValidation.js +1 -15
- package/dist/actions/schema/utils/schemaStoreValidation.js.map +1 -1
- package/dist/actions/schema/utils/uniqByProjectIdDataset.js +1 -1
- package/dist/actions/schema/utils/uniqByProjectIdDataset.js.map +1 -1
- package/dist/actions/schema/validateSchema.worker.js +1 -8
- package/dist/actions/schema/validateSchema.worker.js.map +1 -1
- package/dist/actions/schema/watchExtractSchema.js +72 -0
- package/dist/actions/schema/watchExtractSchema.js.map +1 -0
- package/dist/actions/telemetry/isTrueish.js +10 -0
- package/dist/actions/telemetry/isTrueish.js.map +1 -0
- package/dist/actions/telemetry/resolveConsent.js +2 -1
- package/dist/actions/telemetry/resolveConsent.js.map +1 -1
- package/dist/actions/telemetry/setConsent.js +2 -1
- package/dist/actions/telemetry/setConsent.js.map +1 -1
- package/dist/actions/telemetry/telemetryDebug.js +2 -2
- package/dist/actions/telemetry/telemetryDebug.js.map +1 -1
- package/dist/actions/users/getMembersForProject.js.map +1 -1
- package/dist/actions/users/getPendingInvitations.js +1 -1
- package/dist/actions/users/getPendingInvitations.js.map +1 -1
- package/dist/actions/users/types.js.map +1 -1
- package/dist/actions/versions/filterSanityModules.js.map +1 -1
- package/dist/actions/versions/findSanityModulesVersions.js +2 -3
- package/dist/actions/versions/findSanityModulesVersions.js.map +1 -1
- package/dist/actions/versions/getFormatters.js +1 -1
- package/dist/actions/versions/getFormatters.js.map +1 -1
- package/dist/actions/versions/tryFindLatestVersion.js +1 -1
- package/dist/actions/versions/tryFindLatestVersion.js.map +1 -1
- package/dist/commands/backup/disable.js +22 -7
- package/dist/commands/backup/disable.js.map +1 -1
- package/dist/commands/backup/download.js +19 -10
- package/dist/commands/backup/download.js.map +1 -1
- package/dist/commands/backup/enable.js +22 -7
- package/dist/commands/backup/enable.js.map +1 -1
- package/dist/commands/backup/list.js +20 -8
- package/dist/commands/backup/list.js.map +1 -1
- package/dist/commands/build.js +2 -5
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/cors/add.js +20 -7
- package/dist/commands/cors/add.js.map +1 -1
- package/dist/commands/cors/delete.js +22 -7
- package/dist/commands/cors/delete.js.map +1 -1
- package/dist/commands/cors/list.js +22 -7
- package/dist/commands/cors/list.js.map +1 -1
- package/dist/commands/dataset/alias/create.js +26 -7
- package/dist/commands/dataset/alias/create.js.map +1 -1
- package/dist/commands/dataset/alias/delete.js +20 -7
- package/dist/commands/dataset/alias/delete.js.map +1 -1
- package/dist/commands/dataset/alias/link.js +20 -7
- package/dist/commands/dataset/alias/link.js.map +1 -1
- package/dist/commands/dataset/alias/unlink.js +20 -7
- package/dist/commands/dataset/alias/unlink.js.map +1 -1
- package/dist/commands/dataset/copy.js +45 -30
- package/dist/commands/dataset/copy.js.map +1 -1
- package/dist/commands/dataset/create.js +32 -7
- package/dist/commands/dataset/create.js.map +1 -1
- package/dist/commands/dataset/delete.js +16 -7
- package/dist/commands/dataset/delete.js.map +1 -1
- package/dist/commands/dataset/embeddings/disable.js +77 -0
- package/dist/commands/dataset/embeddings/disable.js.map +1 -0
- package/dist/commands/dataset/embeddings/enable.js +141 -0
- package/dist/commands/dataset/embeddings/enable.js.map +1 -0
- package/dist/commands/dataset/embeddings/status.js +72 -0
- package/dist/commands/dataset/embeddings/status.js.map +1 -0
- package/dist/commands/dataset/export.js +25 -16
- package/dist/commands/dataset/export.js.map +1 -1
- package/dist/commands/dataset/import.js +306 -1
- package/dist/commands/dataset/import.js.map +1 -1
- package/dist/commands/dataset/list.js +22 -7
- package/dist/commands/dataset/list.js.map +1 -1
- package/dist/commands/dataset/visibility/get.js +18 -7
- package/dist/commands/dataset/visibility/get.js.map +1 -1
- package/dist/commands/dataset/visibility/set.js +22 -7
- package/dist/commands/dataset/visibility/set.js.map +1 -1
- package/dist/commands/debug.js +4 -2
- package/dist/commands/debug.js.map +1 -1
- package/dist/commands/deploy.js +22 -11
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/dev.js +2 -4
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/doctor.js +125 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/documents/create.js +19 -12
- package/dist/commands/documents/create.js.map +1 -1
- package/dist/commands/documents/delete.js +19 -12
- package/dist/commands/documents/delete.js.map +1 -1
- package/dist/commands/documents/get.js +17 -12
- package/dist/commands/documents/get.js.map +1 -1
- package/dist/commands/documents/query.js +26 -18
- package/dist/commands/documents/query.js.map +1 -1
- package/dist/commands/documents/validate.js +32 -10
- package/dist/commands/documents/validate.js.map +1 -1
- package/dist/commands/graphql/deploy.js +58 -30
- package/dist/commands/graphql/deploy.js.map +1 -1
- package/dist/commands/graphql/list.js +15 -7
- package/dist/commands/graphql/list.js.map +1 -1
- package/dist/commands/graphql/undeploy.js +37 -19
- package/dist/commands/graphql/undeploy.js.map +1 -1
- package/dist/commands/hook/attempt.js +22 -7
- package/dist/commands/hook/attempt.js.map +1 -1
- package/dist/commands/hook/create.js +23 -8
- package/dist/commands/hook/create.js.map +1 -1
- package/dist/commands/hook/delete.js +22 -7
- package/dist/commands/hook/delete.js.map +1 -1
- package/dist/commands/hook/list.js +22 -7
- package/dist/commands/hook/list.js.map +1 -1
- package/dist/commands/hook/logs.js +21 -8
- package/dist/commands/hook/logs.js.map +1 -1
- package/dist/commands/init.js +55 -32
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/login.js +19 -6
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logout.js +8 -6
- package/dist/commands/logout.js.map +1 -1
- package/dist/commands/manage.js +0 -1
- package/dist/commands/manage.js.map +1 -1
- package/dist/commands/manifest/extract.js +14 -10
- package/dist/commands/manifest/extract.js.map +1 -1
- package/dist/commands/mcp/configure.js +4 -2
- package/dist/commands/mcp/configure.js.map +1 -1
- package/dist/commands/media/create-aspect.js +4 -4
- package/dist/commands/media/create-aspect.js.map +1 -1
- package/dist/commands/media/delete-aspect.js +9 -7
- package/dist/commands/media/delete-aspect.js.map +1 -1
- package/dist/commands/media/deploy-aspect.js +22 -9
- package/dist/commands/media/deploy-aspect.js.map +1 -1
- package/dist/commands/media/export.js +9 -7
- package/dist/commands/media/export.js.map +1 -1
- package/dist/commands/media/import.js +10 -8
- package/dist/commands/media/import.js.map +1 -1
- package/dist/commands/preview.js +5 -8
- package/dist/commands/preview.js.map +1 -1
- package/dist/commands/projects/list.js +2 -1
- package/dist/commands/projects/list.js.map +1 -1
- package/dist/commands/schema/delete.js +33 -34
- package/dist/commands/schema/delete.js.map +1 -1
- package/dist/commands/schema/deploy.js +19 -30
- package/dist/commands/schema/deploy.js.map +1 -1
- package/dist/commands/schema/extract.js +32 -4
- package/dist/commands/schema/extract.js.map +1 -1
- package/dist/commands/schema/list.js +10 -31
- package/dist/commands/schema/list.js.map +1 -1
- package/dist/commands/tokens/add.js +24 -7
- package/dist/commands/tokens/add.js.map +1 -1
- package/dist/commands/tokens/delete.js +20 -7
- package/dist/commands/tokens/delete.js.map +1 -1
- package/dist/commands/tokens/list.js +20 -7
- package/dist/commands/tokens/list.js.map +1 -1
- package/dist/commands/users/invite.js +24 -7
- package/dist/commands/users/invite.js.map +1 -1
- package/dist/commands/users/list.js +76 -33
- package/dist/commands/users/list.js.map +1 -1
- package/dist/commands/versions.js +1 -1
- package/dist/commands/versions.js.map +1 -1
- package/dist/config/createCliConfig.js +1 -2
- package/dist/config/createCliConfig.js.map +1 -1
- package/dist/exports/_internal.d.ts +132 -0
- package/dist/exports/_internal.js +4 -0
- package/dist/exports/_internal.js.map +1 -0
- package/dist/exports/index.d.ts +113 -0
- package/dist/exports/index.js +6 -0
- package/dist/exports/index.js.map +1 -0
- package/dist/hooks/init/checkForUpdates.js +14 -0
- package/dist/hooks/init/checkForUpdates.js.map +1 -0
- package/dist/hooks/prerun/flushTelemetry.worker.js +1 -1
- package/dist/hooks/prerun/flushTelemetry.worker.js.map +1 -1
- package/dist/hooks/prerun/injectEnvVariables.js +9 -1
- package/dist/hooks/prerun/injectEnvVariables.js.map +1 -1
- package/dist/hooks/prerun/setupTelemetry.js +16 -10
- package/dist/hooks/prerun/setupTelemetry.js.map +1 -1
- package/dist/prompts/promptForProject.js +64 -0
- package/dist/prompts/promptForProject.js.map +1 -0
- package/dist/{actions/auth/login/promptProviders.js → prompts/promptForProviders.js} +3 -3
- package/dist/prompts/promptForProviders.js.map +1 -0
- package/dist/prompts/selectMediaLibrary.js +1 -1
- package/dist/prompts/selectMediaLibrary.js.map +1 -1
- package/dist/server/devServer.js +4 -2
- package/dist/server/devServer.js.map +1 -1
- package/dist/server/previewServer.js +2 -2
- package/dist/server/previewServer.js.map +1 -1
- package/dist/server/vite/plugin-schema-extraction.js +201 -0
- package/dist/server/vite/plugin-schema-extraction.js.map +1 -0
- package/dist/server/vite/plugin-typegen.js +217 -0
- package/dist/server/vite/plugin-typegen.js.map +1 -0
- package/dist/services/auth.js +42 -3
- package/dist/services/auth.js.map +1 -1
- package/dist/services/datasets.js +7 -5
- package/dist/services/datasets.js.map +1 -1
- package/dist/services/docs.js +2 -2
- package/dist/services/docs.js.map +1 -1
- package/dist/services/embeddings.js +25 -0
- package/dist/services/embeddings.js.map +1 -0
- package/dist/services/getUrlHeaders.js +7 -18
- package/dist/services/getUrlHeaders.js.map +1 -1
- package/dist/services/grants.js +13 -0
- package/dist/services/grants.js.map +1 -0
- package/dist/services/graphql.js +1 -1
- package/dist/services/graphql.js.map +1 -1
- package/dist/services/mcp.js +55 -1
- package/dist/services/mcp.js.map +1 -1
- package/dist/services/projects.js +4 -2
- package/dist/services/projects.js.map +1 -1
- package/dist/services/schemas.js +1 -1
- package/dist/services/schemas.js.map +1 -1
- package/dist/services/telemetry.js +2 -1
- package/dist/services/telemetry.js.map +1 -1
- package/dist/services/userApplications.js +21 -6
- package/dist/services/userApplications.js.map +1 -1
- package/dist/telemetry/extractSchema.telemetry.js +10 -0
- package/dist/telemetry/extractSchema.telemetry.js.map +1 -1
- package/dist/types/grants.js +3 -0
- package/dist/types/grants.js.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -1
- package/dist/util/checkProjectPermissions.js +21 -0
- package/dist/util/checkProjectPermissions.js.map +1 -0
- package/dist/util/cliClient.js +5 -3
- package/dist/util/cliClient.js.map +1 -1
- package/dist/util/compareDependencyVersions.js +74 -38
- package/dist/util/compareDependencyVersions.js.map +1 -1
- package/dist/util/createExpiringConfig.js +64 -0
- package/dist/util/createExpiringConfig.js.map +1 -0
- package/dist/util/detectFramework.js +135 -0
- package/dist/util/detectFramework.js.map +1 -0
- package/dist/util/errorMessages.js +0 -1
- package/dist/util/errorMessages.js.map +1 -1
- package/dist/util/extractDocumentsFromNdjsonOrTarball.js +1 -2
- package/dist/util/extractDocumentsFromNdjsonOrTarball.js.map +1 -1
- package/dist/util/getCliVersion.js +1 -1
- package/dist/util/getCliVersion.js.map +1 -1
- package/dist/util/getLocalPackageVersion.js +33 -23
- package/dist/util/getLocalPackageVersion.js.map +1 -1
- package/dist/util/getProjectDefaults.js +22 -28
- package/dist/util/getProjectDefaults.js.map +1 -1
- package/dist/util/getSharedServerConfig.js +1 -0
- package/dist/util/getSharedServerConfig.js.map +1 -1
- package/dist/util/getWorkspace.js +1 -1
- package/dist/util/getWorkspace.js.map +1 -1
- package/dist/util/gitConfig.js +45 -0
- package/dist/util/gitConfig.js.map +1 -0
- package/dist/util/isSchemaError.js +11 -0
- package/dist/util/isSchemaError.js.map +1 -0
- package/dist/util/isTar.js +8 -0
- package/dist/util/isTar.js.map +1 -0
- package/dist/util/packageManager/getPeerDependencies.js +44 -0
- package/dist/util/packageManager/getPeerDependencies.js.map +1 -0
- package/dist/util/packageManager/installationInfo/analyzeIssues.js +225 -0
- package/dist/util/packageManager/installationInfo/analyzeIssues.js.map +1 -0
- package/dist/util/packageManager/installationInfo/commands.js +73 -0
- package/dist/util/packageManager/installationInfo/commands.js.map +1 -0
- package/dist/util/packageManager/installationInfo/detectCliInstallation.js +66 -0
- package/dist/util/packageManager/installationInfo/detectCliInstallation.js.map +1 -0
- package/dist/util/packageManager/installationInfo/detectGlobals.js +295 -0
- package/dist/util/packageManager/installationInfo/detectGlobals.js.map +1 -0
- package/dist/util/packageManager/installationInfo/detectPackages.js +190 -0
- package/dist/util/packageManager/installationInfo/detectPackages.js.map +1 -0
- package/dist/util/packageManager/installationInfo/detectWorkspace.js +192 -0
- package/dist/util/packageManager/installationInfo/detectWorkspace.js.map +1 -0
- package/dist/util/packageManager/installationInfo/index.js +4 -0
- package/dist/util/packageManager/installationInfo/index.js.map +1 -0
- package/dist/util/packageManager/installationInfo/readJsonFile.js +14 -0
- package/dist/util/packageManager/installationInfo/readJsonFile.js.map +1 -0
- package/dist/util/packageManager/installationInfo/resolveVersionRange.js +42 -0
- package/dist/util/packageManager/installationInfo/resolveVersionRange.js.map +1 -0
- package/dist/util/packageManager/installationInfo/types.js +3 -0
- package/dist/util/packageManager/installationInfo/types.js.map +1 -0
- package/dist/util/packageManager/packageManagerChoice.js +1 -20
- package/dist/util/packageManager/packageManagerChoice.js.map +1 -1
- package/dist/util/packageManager/upgradePackages.js +4 -1
- package/dist/util/packageManager/upgradePackages.js.map +1 -1
- package/dist/util/promiseRaceWithTimeout.js +28 -0
- package/dist/util/promiseRaceWithTimeout.js.map +1 -0
- package/dist/util/readdirRecursive.js.map +1 -1
- package/dist/util/resolveLatestVersions.js +2 -2
- package/dist/util/resolveLatestVersions.js.map +1 -1
- package/dist/util/sharedFlags.js +54 -0
- package/dist/util/sharedFlags.js.map +1 -0
- package/dist/util/telemetry/cleanupOldTelemetryFiles.js +30 -0
- package/dist/util/telemetry/cleanupOldTelemetryFiles.js.map +1 -0
- package/dist/util/telemetry/createTelemetryStore.js +95 -0
- package/dist/util/telemetry/createTelemetryStore.js.map +1 -0
- package/dist/util/telemetry/createTraceId.js +10 -0
- package/dist/util/telemetry/createTraceId.js.map +1 -0
- package/dist/util/telemetry/findTelemetryFiles.js +35 -0
- package/dist/util/telemetry/findTelemetryFiles.js.map +1 -0
- package/dist/util/telemetry/flushTelemetryFiles.js +118 -0
- package/dist/util/telemetry/flushTelemetryFiles.js.map +1 -0
- package/dist/util/telemetry/generateTelemetryFilePath.js +30 -0
- package/dist/util/telemetry/generateTelemetryFilePath.js.map +1 -0
- package/dist/util/telemetry/logger.js +59 -0
- package/dist/util/telemetry/logger.js.map +1 -0
- package/dist/util/telemetry/readNDJSON.js +28 -0
- package/dist/util/telemetry/readNDJSON.js.map +1 -0
- package/dist/util/telemetry/telemetryStoreDebug.js +7 -0
- package/dist/util/telemetry/telemetryStoreDebug.js.map +1 -0
- package/dist/util/telemetry/trace.js +150 -0
- package/dist/util/telemetry/trace.js.map +1 -0
- package/dist/util/toForwardSlashes.js +8 -0
- package/dist/util/toForwardSlashes.js.map +1 -0
- package/dist/util/update/fetchLatestVersion.js +21 -0
- package/dist/util/update/fetchLatestVersion.js.map +1 -0
- package/dist/util/update/getUpdateCommand.js +20 -0
- package/dist/util/update/getUpdateCommand.js.map +1 -0
- package/dist/util/update/isInstalledUsingYarn.js +17 -0
- package/dist/util/update/isInstalledUsingYarn.js.map +1 -0
- package/dist/util/update/showNotificationUpdate.js +31 -0
- package/dist/util/update/showNotificationUpdate.js.map +1 -0
- package/dist/util/update/updateChecker.js +60 -0
- package/dist/util/update/updateChecker.js.map +1 -0
- package/dist/util/update/updateCheckerDebug.js +4 -0
- package/dist/util/update/updateCheckerDebug.js.map +1 -0
- package/oclif.config.js +1 -0
- package/oclif.manifest.json +1285 -492
- package/package.json +72 -73
- package/static/favicons/apple-touch-icon.png +0 -0
- package/static/favicons/favicon-192.png +0 -0
- package/static/favicons/favicon-512.png +0 -0
- package/static/favicons/favicon-96.png +0 -0
- package/static/favicons/favicon.ico +0 -0
- package/static/favicons/favicon.svg +12 -0
- package/dist/actions/auth/login/promptProviders.js.map +0 -1
- package/dist/actions/dev/getCoreAppUrl.js +0 -10
- package/dist/actions/dev/getCoreAppUrl.js.map +0 -1
- package/dist/actions/schema/schemaStoreTypes.js +0 -19
- package/dist/actions/schema/schemaStoreTypes.js.map +0 -1
- package/dist/actions/schema/utils/manifestExtractor.js +0 -33
- package/dist/actions/schema/utils/manifestExtractor.js.map +0 -1
- package/dist/actions/schema/utils/manifestReader.js +0 -71
- package/dist/actions/schema/utils/manifestReader.js.map +0 -1
- package/dist/index.d.ts +0 -2326
- package/dist/index.js +0 -6
- package/dist/index.js.map +0 -1
- package/dist/studioDependencies.js.map +0 -1
- package/dist/typings/deepSortObject.d.js +0 -2
- package/dist/typings/deepSortObject.d.js.map +0 -1
- package/dist/util/findNdjsonEntry.js +0 -21
- package/dist/util/findNdjsonEntry.js.map +0 -1
- package/dist/util/importStudioConfig.js +0 -40
- package/dist/util/importStudioConfig.js.map +0 -1
- package/dist/util/readModuleVersion.js +0 -15
- package/dist/util/readModuleVersion.js.map +0 -1
- package/dist/util/readPackageJson.js +0 -44
- package/dist/util/readPackageJson.js.map +0 -1
- package/dist/util/readPackageManifest.js +0 -46
- package/dist/util/readPackageManifest.js.map +0 -1
- package/dist/util/uniqBy.js +0 -14
- package/dist/util/uniqBy.js.map +0 -1
- package/dist/util/workerChannels.js +0 -172
- package/dist/util/workerChannels.js.map +0 -1
- /package/dist/{studioDependencies.js → actions/init/studioDependencies.js} +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getYarnMajorVersion } from '@sanity/cli-core/package-manager';
|
|
1
2
|
import { execa } from 'execa';
|
|
2
3
|
import { getPartialEnvWithNpmPath } from './packageManagerChoice.js';
|
|
3
4
|
/**
|
|
@@ -52,8 +53,10 @@ import { getPartialEnvWithNpmPath } from './packageManagerChoice.js';
|
|
|
52
53
|
}
|
|
53
54
|
case 'yarn':
|
|
54
55
|
{
|
|
56
|
+
const yarnMajor = getYarnMajorVersion();
|
|
57
|
+
const upgradeCmd = yarnMajor !== undefined && yarnMajor >= 2 ? 'up' : 'upgrade';
|
|
55
58
|
const yarnArgs = [
|
|
56
|
-
|
|
59
|
+
upgradeCmd,
|
|
57
60
|
...upgradePackageArgs
|
|
58
61
|
];
|
|
59
62
|
output.log(`Running 'yarn ${yarnArgs.join(' ')}'`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/util/packageManager/upgradePackages.ts"],"sourcesContent":["import {type Output} from '@sanity/cli-core'\nimport {execa, type Options, type Result} from 'execa'\n\nimport {getPartialEnvWithNpmPath, type PackageManager} from './packageManagerChoice.js'\n\n/**\n * @internal\n */\ninterface UpgradeOptions {\n packageManager: PackageManager\n packages: [name: string, version: string][]\n}\n\n/**\n * @internal\n */\nexport async function upgradePackages(\n options: UpgradeOptions,\n context: {output: Output; workDir: string},\n): Promise<void> {\n const {packageManager, packages} = options\n const {output, workDir} = context\n const execOptions: Options = {\n cwd: workDir,\n encoding: 'utf8',\n env: getPartialEnvWithNpmPath(workDir),\n stdio: 'inherit',\n }\n const upgradePackageArgs = packages.map((pkg) => pkg.join('@'))\n let result: Result | undefined\n switch (packageManager) {\n case 'bun': {\n const bunArgs = ['update', ...upgradePackageArgs]\n output.log(`Running 'bun ${bunArgs.join(' ')}'`)\n result = await execa('bun', bunArgs, execOptions)\n\n break\n }\n case 'manual': {\n output.log(\n `Manual installation selected - run 'npm upgrade ${upgradePackageArgs.join(' ')}' or equivalent`,\n )\n\n break\n }\n case 'npm': {\n const npmArgs = ['install', '--legacy-peer-deps', ...upgradePackageArgs]\n output.log(`Running 'npm ${npmArgs.join(' ')}'`)\n result = await execa('npm', npmArgs, execOptions)\n\n break\n }\n case 'pnpm': {\n const pnpmArgs = ['upgrade', ...upgradePackageArgs]\n output.log(`Running 'pnpm ${pnpmArgs.join(' ')}'`)\n result = await execa('pnpm', pnpmArgs, execOptions)\n\n break\n }\n case 'yarn': {\n const
|
|
1
|
+
{"version":3,"sources":["../../../src/util/packageManager/upgradePackages.ts"],"sourcesContent":["import {type Output} from '@sanity/cli-core'\nimport {getYarnMajorVersion} from '@sanity/cli-core/package-manager'\nimport {execa, type Options, type Result} from 'execa'\n\nimport {getPartialEnvWithNpmPath, type PackageManager} from './packageManagerChoice.js'\n\n/**\n * @internal\n */\ninterface UpgradeOptions {\n packageManager: PackageManager\n packages: [name: string, version: string][]\n}\n\n/**\n * @internal\n */\nexport async function upgradePackages(\n options: UpgradeOptions,\n context: {output: Output; workDir: string},\n): Promise<void> {\n const {packageManager, packages} = options\n const {output, workDir} = context\n const execOptions: Options = {\n cwd: workDir,\n encoding: 'utf8',\n env: getPartialEnvWithNpmPath(workDir),\n stdio: 'inherit',\n }\n const upgradePackageArgs = packages.map((pkg) => pkg.join('@'))\n let result: Result | undefined\n switch (packageManager) {\n case 'bun': {\n const bunArgs = ['update', ...upgradePackageArgs]\n output.log(`Running 'bun ${bunArgs.join(' ')}'`)\n result = await execa('bun', bunArgs, execOptions)\n\n break\n }\n case 'manual': {\n output.log(\n `Manual installation selected - run 'npm upgrade ${upgradePackageArgs.join(' ')}' or equivalent`,\n )\n\n break\n }\n case 'npm': {\n const npmArgs = ['install', '--legacy-peer-deps', ...upgradePackageArgs]\n output.log(`Running 'npm ${npmArgs.join(' ')}'`)\n result = await execa('npm', npmArgs, execOptions)\n\n break\n }\n case 'pnpm': {\n const pnpmArgs = ['upgrade', ...upgradePackageArgs]\n output.log(`Running 'pnpm ${pnpmArgs.join(' ')}'`)\n result = await execa('pnpm', pnpmArgs, execOptions)\n\n break\n }\n case 'yarn': {\n const yarnMajor = getYarnMajorVersion()\n const upgradeCmd = yarnMajor !== undefined && yarnMajor >= 2 ? 'up' : 'upgrade'\n const yarnArgs = [upgradeCmd, ...upgradePackageArgs]\n output.log(`Running 'yarn ${yarnArgs.join(' ')}'`)\n result = await execa('yarn', yarnArgs, execOptions)\n\n break\n }\n // No default\n }\n\n if (result?.exitCode || result?.failed) {\n throw new Error('Package upgrade failed')\n }\n}\n"],"names":["getYarnMajorVersion","execa","getPartialEnvWithNpmPath","upgradePackages","options","context","packageManager","packages","output","workDir","execOptions","cwd","encoding","env","stdio","upgradePackageArgs","map","pkg","join","result","bunArgs","log","npmArgs","pnpmArgs","yarnMajor","upgradeCmd","undefined","yarnArgs","exitCode","failed","Error"],"mappings":"AACA,SAAQA,mBAAmB,QAAO,mCAAkC;AACpE,SAAQC,KAAK,QAAkC,QAAO;AAEtD,SAAQC,wBAAwB,QAA4B,4BAA2B;AAUvF;;CAEC,GACD,OAAO,eAAeC,gBACpBC,OAAuB,EACvBC,OAA0C;IAE1C,MAAM,EAACC,cAAc,EAAEC,QAAQ,EAAC,GAAGH;IACnC,MAAM,EAACI,MAAM,EAAEC,OAAO,EAAC,GAAGJ;IAC1B,MAAMK,cAAuB;QAC3BC,KAAKF;QACLG,UAAU;QACVC,KAAKX,yBAAyBO;QAC9BK,OAAO;IACT;IACA,MAAMC,qBAAqBR,SAASS,GAAG,CAAC,CAACC,MAAQA,IAAIC,IAAI,CAAC;IAC1D,IAAIC;IACJ,OAAQb;QACN,KAAK;YAAO;gBACV,MAAMc,UAAU;oBAAC;uBAAaL;iBAAmB;gBACjDP,OAAOa,GAAG,CAAC,CAAC,aAAa,EAAED,QAAQF,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC/CC,SAAS,MAAMlB,MAAM,OAAOmB,SAASV;gBAErC;YACF;QACA,KAAK;YAAU;gBACbF,OAAOa,GAAG,CACR,CAAC,gDAAgD,EAAEN,mBAAmBG,IAAI,CAAC,KAAK,eAAe,CAAC;gBAGlG;YACF;QACA,KAAK;YAAO;gBACV,MAAMI,UAAU;oBAAC;oBAAW;uBAAyBP;iBAAmB;gBACxEP,OAAOa,GAAG,CAAC,CAAC,aAAa,EAAEC,QAAQJ,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC/CC,SAAS,MAAMlB,MAAM,OAAOqB,SAASZ;gBAErC;YACF;QACA,KAAK;YAAQ;gBACX,MAAMa,WAAW;oBAAC;uBAAcR;iBAAmB;gBACnDP,OAAOa,GAAG,CAAC,CAAC,cAAc,EAAEE,SAASL,IAAI,CAAC,KAAK,CAAC,CAAC;gBACjDC,SAAS,MAAMlB,MAAM,QAAQsB,UAAUb;gBAEvC;YACF;QACA,KAAK;YAAQ;gBACX,MAAMc,YAAYxB;gBAClB,MAAMyB,aAAaD,cAAcE,aAAaF,aAAa,IAAI,OAAO;gBACtE,MAAMG,WAAW;oBAACF;uBAAeV;iBAAmB;gBACpDP,OAAOa,GAAG,CAAC,CAAC,cAAc,EAAEM,SAAST,IAAI,CAAC,KAAK,CAAC,CAAC;gBACjDC,SAAS,MAAMlB,MAAM,QAAQ0B,UAAUjB;gBAEvC;YACF;IAEF;IAEA,IAAIS,QAAQS,YAAYT,QAAQU,QAAQ;QACtC,MAAM,IAAIC,MAAM;IAClB;AACF"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Race a promise against a timeout, with proper cleanup of the timeout timer
|
|
3
|
+
*
|
|
4
|
+
* @param promise - The promise to race
|
|
5
|
+
* @param timeout - Timeout in milliseconds
|
|
6
|
+
* @returns The promise result, or null if timeout wins
|
|
7
|
+
*/ export async function promiseRaceWithTimeout(promise, timeout) {
|
|
8
|
+
let timeoutId;
|
|
9
|
+
try {
|
|
10
|
+
const result = await Promise.race([
|
|
11
|
+
promise,
|
|
12
|
+
new Promise((resolve)=>{
|
|
13
|
+
timeoutId = setTimeout(()=>resolve(null), timeout);
|
|
14
|
+
})
|
|
15
|
+
]);
|
|
16
|
+
// Clear timeout if promise won
|
|
17
|
+
if (timeoutId && result !== null) {
|
|
18
|
+
clearTimeout(timeoutId);
|
|
19
|
+
}
|
|
20
|
+
return result;
|
|
21
|
+
} finally{
|
|
22
|
+
if (timeoutId) {
|
|
23
|
+
clearTimeout(timeoutId);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
//# sourceMappingURL=promiseRaceWithTimeout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/util/promiseRaceWithTimeout.ts"],"sourcesContent":["/**\n * Race a promise against a timeout, with proper cleanup of the timeout timer\n *\n * @param promise - The promise to race\n * @param timeout - Timeout in milliseconds\n * @returns The promise result, or null if timeout wins\n */\nexport async function promiseRaceWithTimeout<T>(\n promise: Promise<T>,\n timeout: number,\n): Promise<T | null> {\n let timeoutId: NodeJS.Timeout | undefined\n\n try {\n const result = await Promise.race([\n promise,\n new Promise<null>((resolve) => {\n timeoutId = setTimeout(() => resolve(null), timeout)\n }),\n ])\n\n // Clear timeout if promise won\n if (timeoutId && result !== null) {\n clearTimeout(timeoutId)\n }\n\n return result\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId)\n }\n }\n}\n"],"names":["promiseRaceWithTimeout","promise","timeout","timeoutId","result","Promise","race","resolve","setTimeout","clearTimeout"],"mappings":"AAAA;;;;;;CAMC,GACD,OAAO,eAAeA,uBACpBC,OAAmB,EACnBC,OAAe;IAEf,IAAIC;IAEJ,IAAI;QACF,MAAMC,SAAS,MAAMC,QAAQC,IAAI,CAAC;YAChCL;YACA,IAAII,QAAc,CAACE;gBACjBJ,YAAYK,WAAW,IAAMD,QAAQ,OAAOL;YAC9C;SACD;QAED,+BAA+B;QAC/B,IAAIC,aAAaC,WAAW,MAAM;YAChCK,aAAaN;QACf;QAEA,OAAOC;IACT,SAAU;QACR,IAAID,WAAW;YACbM,aAAaN;QACf;IACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/util/readdirRecursive.ts"],"sourcesContent":["import fs from 'node:fs/promises'\nimport path from 'node:path'\n\
|
|
1
|
+
{"version":3,"sources":["../../src/util/readdirRecursive.ts"],"sourcesContent":["import fs from 'node:fs/promises'\nimport path from 'node:path'\n\ninterface ReaddirItem {\n isDir: boolean\n path: string\n}\n\nexport async function readdirRecursive(dir: string): Promise<ReaddirItem[]> {\n let content: ReaddirItem[] = []\n\n const currentPath = path.resolve(dir)\n const dirContent = (await fs.readdir(currentPath)).map((item) => path.join(currentPath, item))\n\n for (const subPath of dirContent) {\n const stat = await fs.stat(subPath)\n const isDir = stat.isDirectory()\n content.push({isDir, path: subPath})\n\n if (isDir) {\n content = [...content, ...(await readdirRecursive(subPath))]\n }\n }\n\n return content\n}\n"],"names":["fs","path","readdirRecursive","dir","content","currentPath","resolve","dirContent","readdir","map","item","join","subPath","stat","isDir","isDirectory","push"],"mappings":"AAAA,OAAOA,QAAQ,mBAAkB;AACjC,OAAOC,UAAU,YAAW;AAO5B,OAAO,eAAeC,iBAAiBC,GAAW;IAChD,IAAIC,UAAyB,EAAE;IAE/B,MAAMC,cAAcJ,KAAKK,OAAO,CAACH;IACjC,MAAMI,aAAa,AAAC,CAAA,MAAMP,GAAGQ,OAAO,CAACH,YAAW,EAAGI,GAAG,CAAC,CAACC,OAAST,KAAKU,IAAI,CAACN,aAAaK;IAExF,KAAK,MAAME,WAAWL,WAAY;QAChC,MAAMM,OAAO,MAAMb,GAAGa,IAAI,CAACD;QAC3B,MAAME,QAAQD,KAAKE,WAAW;QAC9BX,QAAQY,IAAI,CAAC;YAACF;YAAOb,MAAMW;QAAO;QAElC,IAAIE,OAAO;YACTV,UAAU;mBAAIA;mBAAa,MAAMF,iBAAiBU;aAAU;QAC9D;IACF;IAEA,OAAOR;AACT"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { getLatestVersion } from 'get-latest-version';
|
|
2
2
|
import promiseProps from 'promise-props-recursive';
|
|
3
3
|
/**
|
|
4
4
|
* Resolve the latest versions of given packages within their defined ranges
|
|
@@ -8,7 +8,7 @@ import promiseProps from 'promise-props-recursive';
|
|
|
8
8
|
*/ export function resolveLatestVersions(pkgs) {
|
|
9
9
|
const lookups = {};
|
|
10
10
|
for (const [packageName, range] of Object.entries(pkgs)){
|
|
11
|
-
lookups[packageName] = range === 'latest' ?
|
|
11
|
+
lookups[packageName] = range === 'latest' ? getLatestVersion(packageName, {
|
|
12
12
|
range
|
|
13
13
|
}).then(caretify) : range;
|
|
14
14
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/util/resolveLatestVersions.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"sources":["../../src/util/resolveLatestVersions.ts"],"sourcesContent":["import {getLatestVersion} from 'get-latest-version'\nimport promiseProps from 'promise-props-recursive'\n\n/**\n * Resolve the latest versions of given packages within their defined ranges\n *\n * @param pkgs - `{packageName: rangeOrTag}`\n * @returns Object of resolved version numbers\n */\nexport function resolveLatestVersions(\n pkgs: Record<string, string>,\n): Promise<Record<string, string>> {\n const lookups: Record<string, Promise<string> | string> = {}\n for (const [packageName, range] of Object.entries(pkgs)) {\n lookups[packageName] =\n range === 'latest' ? getLatestVersion(packageName, {range}).then(caretify) : range\n }\n\n return promiseProps(lookups)\n}\n\nfunction caretify(version: string | undefined) {\n return version ? `^${version}` : 'latest'\n}\n"],"names":["getLatestVersion","promiseProps","resolveLatestVersions","pkgs","lookups","packageName","range","Object","entries","then","caretify","version"],"mappings":"AAAA,SAAQA,gBAAgB,QAAO,qBAAoB;AACnD,OAAOC,kBAAkB,0BAAyB;AAElD;;;;;CAKC,GACD,OAAO,SAASC,sBACdC,IAA4B;IAE5B,MAAMC,UAAoD,CAAC;IAC3D,KAAK,MAAM,CAACC,aAAaC,MAAM,IAAIC,OAAOC,OAAO,CAACL,MAAO;QACvDC,OAAO,CAACC,YAAY,GAClBC,UAAU,WAAWN,iBAAiBK,aAAa;YAACC;QAAK,GAAGG,IAAI,CAACC,YAAYJ;IACjF;IAEA,OAAOL,aAAaG;AACtB;AAEA,SAASM,SAASC,OAA2B;IAC3C,OAAOA,UAAU,CAAC,CAAC,EAAEA,SAAS,GAAG;AACnC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
2
|
+
const OVERRIDE_SUFFIX = ' (overrides CLI configuration)';
|
|
3
|
+
/**
|
|
4
|
+
* Returns a `--project-id` / `-p` flag definition.
|
|
5
|
+
*
|
|
6
|
+
* Locked: flag name (`project-id`), char (`p`), `helpValue` (`<id>`), and parse (trims + validates non-empty).
|
|
7
|
+
*/ export function getProjectIdFlag(options) {
|
|
8
|
+
const { description: baseDescription, helpGroup, semantics, ...rest } = options;
|
|
9
|
+
const isOverride = semantics === 'override';
|
|
10
|
+
const description = (baseDescription ?? 'Project ID to use') + (isOverride ? OVERRIDE_SUFFIX : '');
|
|
11
|
+
return {
|
|
12
|
+
'project-id': Flags.string({
|
|
13
|
+
description,
|
|
14
|
+
helpGroup: helpGroup ?? (isOverride ? 'OVERRIDE' : undefined),
|
|
15
|
+
helpValue: '<id>',
|
|
16
|
+
...rest,
|
|
17
|
+
char: 'p',
|
|
18
|
+
parse: async (input)=>{
|
|
19
|
+
const trimmed = input.trim();
|
|
20
|
+
if (trimmed === '') {
|
|
21
|
+
throw new Error('`--project-id` cannot be empty if provided');
|
|
22
|
+
}
|
|
23
|
+
return trimmed;
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Returns a `--dataset` / `-d` flag definition.
|
|
30
|
+
*
|
|
31
|
+
* Locked: flag name (`dataset`), char (`d`), `helpValue` (`<name>`), and parse (trims + validates non-empty).
|
|
32
|
+
*/ export function getDatasetFlag(options) {
|
|
33
|
+
const { description: baseDescription, helpGroup, semantics, ...rest } = options;
|
|
34
|
+
const isOverride = semantics === 'override';
|
|
35
|
+
const description = (baseDescription ?? 'Dataset to use') + (isOverride ? OVERRIDE_SUFFIX : '');
|
|
36
|
+
return {
|
|
37
|
+
dataset: Flags.string({
|
|
38
|
+
description,
|
|
39
|
+
helpGroup: helpGroup ?? (isOverride ? 'OVERRIDE' : undefined),
|
|
40
|
+
helpValue: '<name>',
|
|
41
|
+
...rest,
|
|
42
|
+
char: 'd',
|
|
43
|
+
parse: async (input)=>{
|
|
44
|
+
const trimmed = input.trim();
|
|
45
|
+
if (trimmed === '') {
|
|
46
|
+
throw new Error('`--dataset` cannot be empty if provided');
|
|
47
|
+
}
|
|
48
|
+
return trimmed;
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
//# sourceMappingURL=sharedFlags.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/util/sharedFlags.ts"],"sourcesContent":["import {Flags} from '@oclif/core'\n\n/**\n * Controls how the flag relates to CLI configuration:\n *\n * - `'override'` — The command falls back to CLI config (sanity.cli.ts) when the flag is not\n * provided. The flag description automatically gets an \" (overrides CLI configuration)\" suffix,\n * and `helpGroup` defaults to `'OVERRIDE'`.\n *\n * - `'specify'` — The command does NOT fall back to CLI config; the flag is simply how the user\n * provides the value. No suffix is appended, and no default `helpGroup` is set.\n */\ntype FlagSemantics = 'override' | 'specify'\n\n/**\n * Options accepted by the shared flag getters.\n * Locked properties (char, parse, name, helpValue) are excluded to ensure\n * consistent behavior across all commands.\n */\ninterface SharedFlagOptions {\n /**\n * Controls description suffix and default helpGroup.\n * @see {@link FlagSemantics}\n */\n semantics: FlagSemantics\n\n dependsOn?: string[]\n description?: string\n env?: string\n exclusive?: string[]\n helpGroup?: string\n hidden?: boolean\n required?: boolean\n}\n\nconst OVERRIDE_SUFFIX = ' (overrides CLI configuration)'\n\n/**\n * Returns a `--project-id` / `-p` flag definition.\n *\n * Locked: flag name (`project-id`), char (`p`), `helpValue` (`<id>`), and parse (trims + validates non-empty).\n */\nexport function getProjectIdFlag(options: SharedFlagOptions) {\n const {description: baseDescription, helpGroup, semantics, ...rest} = options\n const isOverride = semantics === 'override'\n const description = (baseDescription ?? 'Project ID to use') + (isOverride ? OVERRIDE_SUFFIX : '')\n\n return {\n 'project-id': Flags.string({\n description,\n helpGroup: helpGroup ?? (isOverride ? 'OVERRIDE' : undefined),\n helpValue: '<id>',\n ...rest,\n char: 'p',\n parse: async (input: string) => {\n const trimmed = input.trim()\n if (trimmed === '') {\n throw new Error('`--project-id` cannot be empty if provided')\n }\n return trimmed\n },\n }),\n }\n}\n\n/**\n * Returns a `--dataset` / `-d` flag definition.\n *\n * Locked: flag name (`dataset`), char (`d`), `helpValue` (`<name>`), and parse (trims + validates non-empty).\n */\nexport function getDatasetFlag(options: SharedFlagOptions) {\n const {description: baseDescription, helpGroup, semantics, ...rest} = options\n const isOverride = semantics === 'override'\n const description = (baseDescription ?? 'Dataset to use') + (isOverride ? OVERRIDE_SUFFIX : '')\n\n return {\n dataset: Flags.string({\n description,\n helpGroup: helpGroup ?? (isOverride ? 'OVERRIDE' : undefined),\n helpValue: '<name>',\n ...rest,\n char: 'd',\n parse: async (input: string) => {\n const trimmed = input.trim()\n if (trimmed === '') {\n throw new Error('`--dataset` cannot be empty if provided')\n }\n return trimmed\n },\n }),\n }\n}\n"],"names":["Flags","OVERRIDE_SUFFIX","getProjectIdFlag","options","description","baseDescription","helpGroup","semantics","rest","isOverride","string","undefined","helpValue","char","parse","input","trimmed","trim","Error","getDatasetFlag","dataset"],"mappings":"AAAA,SAAQA,KAAK,QAAO,cAAa;AAmCjC,MAAMC,kBAAkB;AAExB;;;;CAIC,GACD,OAAO,SAASC,iBAAiBC,OAA0B;IACzD,MAAM,EAACC,aAAaC,eAAe,EAAEC,SAAS,EAAEC,SAAS,EAAE,GAAGC,MAAK,GAAGL;IACtE,MAAMM,aAAaF,cAAc;IACjC,MAAMH,cAAc,AAACC,CAAAA,mBAAmB,mBAAkB,IAAMI,CAAAA,aAAaR,kBAAkB,EAAC;IAEhG,OAAO;QACL,cAAcD,MAAMU,MAAM,CAAC;YACzBN;YACAE,WAAWA,aAAcG,CAAAA,aAAa,aAAaE,SAAQ;YAC3DC,WAAW;YACX,GAAGJ,IAAI;YACPK,MAAM;YACNC,OAAO,OAAOC;gBACZ,MAAMC,UAAUD,MAAME,IAAI;gBAC1B,IAAID,YAAY,IAAI;oBAClB,MAAM,IAAIE,MAAM;gBAClB;gBACA,OAAOF;YACT;QACF;IACF;AACF;AAEA;;;;CAIC,GACD,OAAO,SAASG,eAAehB,OAA0B;IACvD,MAAM,EAACC,aAAaC,eAAe,EAAEC,SAAS,EAAEC,SAAS,EAAE,GAAGC,MAAK,GAAGL;IACtE,MAAMM,aAAaF,cAAc;IACjC,MAAMH,cAAc,AAACC,CAAAA,mBAAmB,gBAAe,IAAMI,CAAAA,aAAaR,kBAAkB,EAAC;IAE7F,OAAO;QACLmB,SAASpB,MAAMU,MAAM,CAAC;YACpBN;YACAE,WAAWA,aAAcG,CAAAA,aAAa,aAAaE,SAAQ;YAC3DC,WAAW;YACX,GAAGJ,IAAI;YACPK,MAAM;YACNC,OAAO,OAAOC;gBACZ,MAAMC,UAAUD,MAAME,IAAI;gBAC1B,IAAID,YAAY,IAAI;oBAClB,MAAM,IAAIE,MAAM;gBAClB;gBACA,OAAOF;YACT;QACF;IACF;AACF"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { rm, stat } from 'node:fs/promises';
|
|
2
|
+
import { findTelemetryFiles } from './findTelemetryFiles.js';
|
|
3
|
+
import { telemetryStoreDebug } from './telemetryStoreDebug.js';
|
|
4
|
+
/**
|
|
5
|
+
* Cleans up telemetry files older than the specified number of days
|
|
6
|
+
* @internal
|
|
7
|
+
*/ export async function cleanupOldTelemetryFiles(maxAgeDays = 7) {
|
|
8
|
+
try {
|
|
9
|
+
const files = await findTelemetryFiles();
|
|
10
|
+
const cutoffTime = Date.now() - maxAgeDays * 24 * 60 * 60 * 1000;
|
|
11
|
+
for (const filePath of files){
|
|
12
|
+
try {
|
|
13
|
+
const stats = await stat(filePath);
|
|
14
|
+
if (stats.mtime.getTime() < cutoffTime) {
|
|
15
|
+
telemetryStoreDebug('Cleaning up old telemetry file: %s', filePath);
|
|
16
|
+
await rm(filePath, {
|
|
17
|
+
force: true
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
} catch (error) {
|
|
21
|
+
telemetryStoreDebug('Error checking/removing old file %s: %o', filePath, error);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
} catch (error) {
|
|
25
|
+
telemetryStoreDebug('Error during cleanup: %o', error);
|
|
26
|
+
// Don't throw - cleanup is best effort
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
//# sourceMappingURL=cleanupOldTelemetryFiles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/util/telemetry/cleanupOldTelemetryFiles.ts"],"sourcesContent":["import {rm, stat} from 'node:fs/promises'\n\nimport {findTelemetryFiles} from './findTelemetryFiles.js'\nimport {telemetryStoreDebug} from './telemetryStoreDebug.js'\n\n/**\n * Cleans up telemetry files older than the specified number of days\n * @internal\n */\nexport async function cleanupOldTelemetryFiles(maxAgeDays: number = 7): Promise<void> {\n try {\n const files = await findTelemetryFiles()\n const cutoffTime = Date.now() - maxAgeDays * 24 * 60 * 60 * 1000\n\n for (const filePath of files) {\n try {\n const stats = await stat(filePath)\n if (stats.mtime.getTime() < cutoffTime) {\n telemetryStoreDebug('Cleaning up old telemetry file: %s', filePath)\n await rm(filePath, {force: true})\n }\n } catch (error) {\n telemetryStoreDebug('Error checking/removing old file %s: %o', filePath, error)\n }\n }\n } catch (error) {\n telemetryStoreDebug('Error during cleanup: %o', error)\n // Don't throw - cleanup is best effort\n }\n}\n"],"names":["rm","stat","findTelemetryFiles","telemetryStoreDebug","cleanupOldTelemetryFiles","maxAgeDays","files","cutoffTime","Date","now","filePath","stats","mtime","getTime","force","error"],"mappings":"AAAA,SAAQA,EAAE,EAAEC,IAAI,QAAO,mBAAkB;AAEzC,SAAQC,kBAAkB,QAAO,0BAAyB;AAC1D,SAAQC,mBAAmB,QAAO,2BAA0B;AAE5D;;;CAGC,GACD,OAAO,eAAeC,yBAAyBC,aAAqB,CAAC;IACnE,IAAI;QACF,MAAMC,QAAQ,MAAMJ;QACpB,MAAMK,aAAaC,KAAKC,GAAG,KAAKJ,aAAa,KAAK,KAAK,KAAK;QAE5D,KAAK,MAAMK,YAAYJ,MAAO;YAC5B,IAAI;gBACF,MAAMK,QAAQ,MAAMV,KAAKS;gBACzB,IAAIC,MAAMC,KAAK,CAACC,OAAO,KAAKN,YAAY;oBACtCJ,oBAAoB,sCAAsCO;oBAC1D,MAAMV,GAAGU,UAAU;wBAACI,OAAO;oBAAI;gBACjC;YACF,EAAE,OAAOC,OAAO;gBACdZ,oBAAoB,2CAA2CO,UAAUK;YAC3E;QACF;IACF,EAAE,OAAOA,OAAO;QACdZ,oBAAoB,4BAA4BY;IAChD,uCAAuC;IACzC;AACF"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { appendFileSync } from 'node:fs';
|
|
2
|
+
import { mkdir } from 'node:fs/promises';
|
|
3
|
+
import { dirname } from 'node:path';
|
|
4
|
+
import { generateTelemetryFilePath } from './generateTelemetryFilePath.js';
|
|
5
|
+
import { createLogger } from './logger.js';
|
|
6
|
+
import { telemetryStoreDebug } from './telemetryStoreDebug.js';
|
|
7
|
+
/**
|
|
8
|
+
* Creates a file-based telemetry store with cached consent and reliable synchronous I/O.
|
|
9
|
+
*
|
|
10
|
+
* Key optimizations:
|
|
11
|
+
* - Consent resolved once at creation and cached (vs checking on every emit)
|
|
12
|
+
* - File path generated and directory created once during initialization
|
|
13
|
+
* - Synchronous file writes to ensure events are captured even during process exit
|
|
14
|
+
*
|
|
15
|
+
* @param sessionId - Unique session identifier for file isolation
|
|
16
|
+
* @param options - Configuration options
|
|
17
|
+
* @returns TelemetryStore instance compatible with the telemetry interface
|
|
18
|
+
*
|
|
19
|
+
* @internal
|
|
20
|
+
*/ export function createTelemetryStore(sessionId, options) {
|
|
21
|
+
telemetryStoreDebug('Creating telemetry store with sessionId: %s', sessionId);
|
|
22
|
+
let cachedConsent = null;
|
|
23
|
+
let filePath = null;
|
|
24
|
+
const initializeConsent = async ()=>{
|
|
25
|
+
if (cachedConsent) return;
|
|
26
|
+
try {
|
|
27
|
+
cachedConsent = await options.resolveConsent();
|
|
28
|
+
telemetryStoreDebug('Cached consent status: %s', cachedConsent.status);
|
|
29
|
+
} catch (error) {
|
|
30
|
+
telemetryStoreDebug('Failed to initialize consent, treating as undetermined: %o', error);
|
|
31
|
+
cachedConsent = {
|
|
32
|
+
reason: 'fetchError',
|
|
33
|
+
status: 'undetermined'
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
const initializeFilePath = async ()=>{
|
|
38
|
+
if (filePath) return;
|
|
39
|
+
try {
|
|
40
|
+
filePath = await generateTelemetryFilePath(sessionId);
|
|
41
|
+
telemetryStoreDebug('Generated file path: %s', filePath);
|
|
42
|
+
await mkdir(dirname(filePath), {
|
|
43
|
+
recursive: true
|
|
44
|
+
});
|
|
45
|
+
telemetryStoreDebug('Created directory structure for: %s', filePath);
|
|
46
|
+
} catch (error) {
|
|
47
|
+
telemetryStoreDebug('Failed to initialize file path: %o', error);
|
|
48
|
+
filePath = null;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
const emit = (event)=>{
|
|
52
|
+
if (!cachedConsent || cachedConsent.status !== 'granted') {
|
|
53
|
+
if (cachedConsent) {
|
|
54
|
+
telemetryStoreDebug('Cached consent not granted (%s), skipping event: %s', cachedConsent.status, event.type);
|
|
55
|
+
} else {
|
|
56
|
+
telemetryStoreDebug('Consent not resolved, skipping event: %s', event.type);
|
|
57
|
+
}
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (!filePath) {
|
|
61
|
+
telemetryStoreDebug('File path not initialized, skipping event: %s', event.type);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
telemetryStoreDebug('Emitting event: %s', event.type);
|
|
65
|
+
try {
|
|
66
|
+
const eventLine = JSON.stringify(event) + '\n';
|
|
67
|
+
// We use synchronous file writes to ensure telemetry events are captured even when
|
|
68
|
+
// the process exits abruptly (process.exit, uncaught exceptions, SIGTERM, etc.).
|
|
69
|
+
// The performance impact is probably negligible and is worth the trade-off
|
|
70
|
+
// for 100% reliability. Async writes would be lost when the event loop
|
|
71
|
+
// shuts down during process exit.
|
|
72
|
+
appendFileSync(filePath, eventLine, 'utf8');
|
|
73
|
+
telemetryStoreDebug('Successfully wrote event to file: %s', filePath);
|
|
74
|
+
} catch (error) {
|
|
75
|
+
telemetryStoreDebug('Failed to write telemetry event: %o', error);
|
|
76
|
+
// Silent failure - don't break CLI functionality
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
const logger = createLogger(sessionId, emit);
|
|
80
|
+
// Initialize both consent and file path concurrently
|
|
81
|
+
Promise.allSettled([
|
|
82
|
+
initializeConsent(),
|
|
83
|
+
initializeFilePath()
|
|
84
|
+
]).then((results)=>{
|
|
85
|
+
for (const [index, result] of results.entries()){
|
|
86
|
+
if (result.status === 'rejected') {
|
|
87
|
+
const type = index === 0 ? 'consent' : 'file path';
|
|
88
|
+
telemetryStoreDebug('Error initializing %s: %o', type, result.reason);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
return logger;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
//# sourceMappingURL=createTelemetryStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/util/telemetry/createTelemetryStore.ts"],"sourcesContent":["import {appendFileSync} from 'node:fs'\nimport {mkdir} from 'node:fs/promises'\nimport {dirname} from 'node:path'\n\nimport {\n type CLITelemetryStore,\n type ConsentInformation,\n type TelemetryUserProperties,\n} from '@sanity/cli-core'\nimport {type TelemetryEvent} from '@sanity/telemetry'\n\nimport {generateTelemetryFilePath} from './generateTelemetryFilePath.js'\nimport {createLogger} from './logger.js'\nimport {telemetryStoreDebug} from './telemetryStoreDebug.js'\n\n/**\n * FILE MANAGEMENT STRATEGY:\n *\n * The telemetry system uses a multi-file approach to handle concurrent CLI processes:\n *\n * 1. WRITING (per session):\n * - Each CLI session gets a unique file: telemetry-\\{hash\\}-\\{env\\}-\\{sessionId\\}.ndjson\n * - Prevents write conflicts when multiple CLI commands run simultaneously\n * - Events are written using an RxJS queue for ordered processing with retry logic\n *\n * 2. FLUSHING (aggregate all sessions):\n * - findTelemetryFiles() discovers ALL telemetry files for user/environment\n * - Events are collected from all session files and sent as a batch\n * - Files are deleted after successful transmission\n *\n * 3. CLEANUP (background maintenance):\n * - cleanupOldTelemetryFiles() removes stale files older than 7 days\n * - Prevents disk space accumulation from abandoned sessions\n */\n\ninterface CreateTelemetryStoreOptions {\n resolveConsent: () => Promise<ConsentInformation>\n}\n\n/**\n * Creates a file-based telemetry store with cached consent and reliable synchronous I/O.\n *\n * Key optimizations:\n * - Consent resolved once at creation and cached (vs checking on every emit)\n * - File path generated and directory created once during initialization\n * - Synchronous file writes to ensure events are captured even during process exit\n *\n * @param sessionId - Unique session identifier for file isolation\n * @param options - Configuration options\n * @returns TelemetryStore instance compatible with the telemetry interface\n *\n * @internal\n */\nexport function createTelemetryStore(\n sessionId: string,\n options: CreateTelemetryStoreOptions,\n): CLITelemetryStore {\n telemetryStoreDebug('Creating telemetry store with sessionId: %s', sessionId)\n\n let cachedConsent: ConsentInformation | null = null\n let filePath: string | null = null\n\n const initializeConsent = async () => {\n if (cachedConsent) return\n\n try {\n cachedConsent = await options.resolveConsent()\n telemetryStoreDebug('Cached consent status: %s', cachedConsent.status)\n } catch (error) {\n telemetryStoreDebug('Failed to initialize consent, treating as undetermined: %o', error)\n cachedConsent = {reason: 'fetchError', status: 'undetermined'}\n }\n }\n\n const initializeFilePath = async () => {\n if (filePath) return\n\n try {\n filePath = await generateTelemetryFilePath(sessionId)\n telemetryStoreDebug('Generated file path: %s', filePath)\n\n await mkdir(dirname(filePath), {recursive: true})\n telemetryStoreDebug('Created directory structure for: %s', filePath)\n } catch (error) {\n telemetryStoreDebug('Failed to initialize file path: %o', error)\n filePath = null\n }\n }\n\n const emit = (event: TelemetryEvent) => {\n if (!cachedConsent || cachedConsent.status !== 'granted') {\n if (cachedConsent) {\n telemetryStoreDebug(\n 'Cached consent not granted (%s), skipping event: %s',\n cachedConsent.status,\n event.type,\n )\n } else {\n telemetryStoreDebug('Consent not resolved, skipping event: %s', event.type)\n }\n return\n }\n\n if (!filePath) {\n telemetryStoreDebug('File path not initialized, skipping event: %s', event.type)\n return\n }\n\n telemetryStoreDebug('Emitting event: %s', event.type)\n\n try {\n const eventLine = JSON.stringify(event) + '\\n'\n\n // We use synchronous file writes to ensure telemetry events are captured even when\n // the process exits abruptly (process.exit, uncaught exceptions, SIGTERM, etc.).\n // The performance impact is probably negligible and is worth the trade-off\n // for 100% reliability. Async writes would be lost when the event loop\n // shuts down during process exit.\n appendFileSync(filePath, eventLine, 'utf8')\n telemetryStoreDebug('Successfully wrote event to file: %s', filePath)\n } catch (error) {\n telemetryStoreDebug('Failed to write telemetry event: %o', error)\n // Silent failure - don't break CLI functionality\n }\n }\n\n const logger = createLogger<TelemetryUserProperties>(sessionId, emit)\n\n // Initialize both consent and file path concurrently\n Promise.allSettled([initializeConsent(), initializeFilePath()]).then((results) => {\n for (const [index, result] of results.entries()) {\n if (result.status === 'rejected') {\n const type = index === 0 ? 'consent' : 'file path'\n telemetryStoreDebug('Error initializing %s: %o', type, result.reason)\n }\n }\n })\n\n return logger\n}\n"],"names":["appendFileSync","mkdir","dirname","generateTelemetryFilePath","createLogger","telemetryStoreDebug","createTelemetryStore","sessionId","options","cachedConsent","filePath","initializeConsent","resolveConsent","status","error","reason","initializeFilePath","recursive","emit","event","type","eventLine","JSON","stringify","logger","Promise","allSettled","then","results","index","result","entries"],"mappings":"AAAA,SAAQA,cAAc,QAAO,UAAS;AACtC,SAAQC,KAAK,QAAO,mBAAkB;AACtC,SAAQC,OAAO,QAAO,YAAW;AASjC,SAAQC,yBAAyB,QAAO,iCAAgC;AACxE,SAAQC,YAAY,QAAO,cAAa;AACxC,SAAQC,mBAAmB,QAAO,2BAA0B;AA0B5D;;;;;;;;;;;;;CAaC,GACD,OAAO,SAASC,qBACdC,SAAiB,EACjBC,OAAoC;IAEpCH,oBAAoB,+CAA+CE;IAEnE,IAAIE,gBAA2C;IAC/C,IAAIC,WAA0B;IAE9B,MAAMC,oBAAoB;QACxB,IAAIF,eAAe;QAEnB,IAAI;YACFA,gBAAgB,MAAMD,QAAQI,cAAc;YAC5CP,oBAAoB,6BAA6BI,cAAcI,MAAM;QACvE,EAAE,OAAOC,OAAO;YACdT,oBAAoB,8DAA8DS;YAClFL,gBAAgB;gBAACM,QAAQ;gBAAcF,QAAQ;YAAc;QAC/D;IACF;IAEA,MAAMG,qBAAqB;QACzB,IAAIN,UAAU;QAEd,IAAI;YACFA,WAAW,MAAMP,0BAA0BI;YAC3CF,oBAAoB,2BAA2BK;YAE/C,MAAMT,MAAMC,QAAQQ,WAAW;gBAACO,WAAW;YAAI;YAC/CZ,oBAAoB,uCAAuCK;QAC7D,EAAE,OAAOI,OAAO;YACdT,oBAAoB,sCAAsCS;YAC1DJ,WAAW;QACb;IACF;IAEA,MAAMQ,OAAO,CAACC;QACZ,IAAI,CAACV,iBAAiBA,cAAcI,MAAM,KAAK,WAAW;YACxD,IAAIJ,eAAe;gBACjBJ,oBACE,uDACAI,cAAcI,MAAM,EACpBM,MAAMC,IAAI;YAEd,OAAO;gBACLf,oBAAoB,4CAA4Cc,MAAMC,IAAI;YAC5E;YACA;QACF;QAEA,IAAI,CAACV,UAAU;YACbL,oBAAoB,iDAAiDc,MAAMC,IAAI;YAC/E;QACF;QAEAf,oBAAoB,sBAAsBc,MAAMC,IAAI;QAEpD,IAAI;YACF,MAAMC,YAAYC,KAAKC,SAAS,CAACJ,SAAS;YAE1C,mFAAmF;YACnF,iFAAiF;YACjF,2EAA2E;YAC3E,uEAAuE;YACvE,kCAAkC;YAClCnB,eAAeU,UAAUW,WAAW;YACpChB,oBAAoB,wCAAwCK;QAC9D,EAAE,OAAOI,OAAO;YACdT,oBAAoB,uCAAuCS;QAC3D,iDAAiD;QACnD;IACF;IAEA,MAAMU,SAASpB,aAAsCG,WAAWW;IAEhE,qDAAqD;IACrDO,QAAQC,UAAU,CAAC;QAACf;QAAqBK;KAAqB,EAAEW,IAAI,CAAC,CAACC;QACpE,KAAK,MAAM,CAACC,OAAOC,OAAO,IAAIF,QAAQG,OAAO,GAAI;YAC/C,IAAID,OAAOjB,MAAM,KAAK,YAAY;gBAChC,MAAMO,OAAOS,UAAU,IAAI,YAAY;gBACvCxB,oBAAoB,6BAA6Be,MAAMU,OAAOf,MAAM;YACtE;QACF;IACF;IAEA,OAAOS;AACT"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/util/telemetry/createTraceId.ts"],"sourcesContent":["import {typeid} from 'typeid-js'\n\ntype TraceId = string & {__type: 'TraceId'}\n\n/**\n * Creates a unique trace ID using typeid\n *\n * @internal\n */\nexport function createTraceId(): TraceId {\n return typeid('trace').toString() as TraceId\n}\n"],"names":["typeid","createTraceId","toString"],"mappings":"AAAA,SAAQA,MAAM,QAAO,YAAW;AAIhC;;;;CAIC,GACD,OAAO,SAASC;IACd,OAAOD,OAAO,SAASE,QAAQ;AACjC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { getTelemetryBaseInfo, normalizePath } from '@sanity/cli-core';
|
|
3
|
+
import { glob } from 'tinyglobby';
|
|
4
|
+
import { telemetryStoreDebug } from './telemetryStoreDebug.js';
|
|
5
|
+
/**
|
|
6
|
+
* Discovers and returns paths to all telemetry files for the current user/environment.
|
|
7
|
+
*
|
|
8
|
+
* This function is used during:
|
|
9
|
+
* - Flush operations: to collect and send events from all CLI sessions
|
|
10
|
+
* - Cleanup operations: to find old files that should be removed
|
|
11
|
+
*
|
|
12
|
+
* Uses glob patterns to match files across all sessions (not just the current one).
|
|
13
|
+
*
|
|
14
|
+
* @returns Promise resolving to array of file paths, empty if no files exist
|
|
15
|
+
* @internal
|
|
16
|
+
*/ export async function findTelemetryFiles() {
|
|
17
|
+
try {
|
|
18
|
+
const { basePattern, directory } = await getTelemetryBaseInfo();
|
|
19
|
+
const pattern = `${basePattern}-*.ndjson`;
|
|
20
|
+
const fullPattern = join(directory, pattern);
|
|
21
|
+
telemetryStoreDebug('Looking for files matching pattern: %s', fullPattern);
|
|
22
|
+
// Converts windows backslashes to forward slashes for glob pattern
|
|
23
|
+
const matchingFiles = await glob(normalizePath(fullPattern));
|
|
24
|
+
telemetryStoreDebug('Found %d matching telemetry files', matchingFiles.length);
|
|
25
|
+
return matchingFiles;
|
|
26
|
+
} catch (error) {
|
|
27
|
+
if (error.code === 'ENOENT') {
|
|
28
|
+
telemetryStoreDebug('Telemetry directory does not exist yet');
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
throw error;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
//# sourceMappingURL=findTelemetryFiles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/util/telemetry/findTelemetryFiles.ts"],"sourcesContent":["import {join} from 'node:path'\n\nimport {getTelemetryBaseInfo, normalizePath} from '@sanity/cli-core'\nimport {glob} from 'tinyglobby'\n\nimport {telemetryStoreDebug} from './telemetryStoreDebug.js'\n\n/**\n * Discovers and returns paths to all telemetry files for the current user/environment.\n *\n * This function is used during:\n * - Flush operations: to collect and send events from all CLI sessions\n * - Cleanup operations: to find old files that should be removed\n *\n * Uses glob patterns to match files across all sessions (not just the current one).\n *\n * @returns Promise resolving to array of file paths, empty if no files exist\n * @internal\n */\nexport async function findTelemetryFiles(): Promise<string[]> {\n try {\n const {basePattern, directory} = await getTelemetryBaseInfo()\n const pattern = `${basePattern}-*.ndjson`\n const fullPattern = join(directory, pattern)\n telemetryStoreDebug('Looking for files matching pattern: %s', fullPattern)\n\n // Converts windows backslashes to forward slashes for glob pattern\n const matchingFiles = await glob(normalizePath(fullPattern))\n telemetryStoreDebug('Found %d matching telemetry files', matchingFiles.length)\n return matchingFiles\n } catch (error) {\n if ((error as {code?: string}).code === 'ENOENT') {\n telemetryStoreDebug('Telemetry directory does not exist yet')\n return []\n }\n throw error\n }\n}\n"],"names":["join","getTelemetryBaseInfo","normalizePath","glob","telemetryStoreDebug","findTelemetryFiles","basePattern","directory","pattern","fullPattern","matchingFiles","length","error","code"],"mappings":"AAAA,SAAQA,IAAI,QAAO,YAAW;AAE9B,SAAQC,oBAAoB,EAAEC,aAAa,QAAO,mBAAkB;AACpE,SAAQC,IAAI,QAAO,aAAY;AAE/B,SAAQC,mBAAmB,QAAO,2BAA0B;AAE5D;;;;;;;;;;;CAWC,GACD,OAAO,eAAeC;IACpB,IAAI;QACF,MAAM,EAACC,WAAW,EAAEC,SAAS,EAAC,GAAG,MAAMN;QACvC,MAAMO,UAAU,GAAGF,YAAY,SAAS,CAAC;QACzC,MAAMG,cAAcT,KAAKO,WAAWC;QACpCJ,oBAAoB,0CAA0CK;QAE9D,mEAAmE;QACnE,MAAMC,gBAAgB,MAAMP,KAAKD,cAAcO;QAC/CL,oBAAoB,qCAAqCM,cAAcC,MAAM;QAC7E,OAAOD;IACT,EAAE,OAAOE,OAAO;QACd,IAAI,AAACA,MAA0BC,IAAI,KAAK,UAAU;YAChDT,oBAAoB;YACpB,OAAO,EAAE;QACX;QACA,MAAMQ;IACR;AACF"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { rm } from 'node:fs/promises';
|
|
2
|
+
import { catchError, defer, from, lastValueFrom, map, mergeMap, of, reduce, switchMap, tap } from 'rxjs';
|
|
3
|
+
import { cleanupOldTelemetryFiles } from './cleanupOldTelemetryFiles.js';
|
|
4
|
+
import { findTelemetryFiles } from './findTelemetryFiles.js';
|
|
5
|
+
import { readNDJSON } from './readNDJSON.js';
|
|
6
|
+
import { telemetryStoreDebug } from './telemetryStoreDebug.js';
|
|
7
|
+
/**
|
|
8
|
+
* Standalone, stateless function to flush telemetry files.
|
|
9
|
+
*
|
|
10
|
+
* This function can be used independently of the telemetry store, making it
|
|
11
|
+
* suitable for use in child processes or other contexts where store state
|
|
12
|
+
* is not available.
|
|
13
|
+
*
|
|
14
|
+
* @param options - Configuration for consent resolution and event sending
|
|
15
|
+
* @returns Promise that resolves when flush operation is complete
|
|
16
|
+
*
|
|
17
|
+
* @internal
|
|
18
|
+
*/ export async function flushTelemetryFiles(options) {
|
|
19
|
+
telemetryStoreDebug('Starting standalone flush operation');
|
|
20
|
+
// Helper function for deleting files with consistent error handling
|
|
21
|
+
const deleteFiles = (files, reason)=>{
|
|
22
|
+
if (files.length === 0) {
|
|
23
|
+
// of() is not same as of(undefined) in rxjs
|
|
24
|
+
// eslint-disable-next-line unicorn/no-useless-undefined
|
|
25
|
+
return of(undefined);
|
|
26
|
+
}
|
|
27
|
+
return from(files).pipe(mergeMap((filePath)=>from(rm(filePath, {
|
|
28
|
+
force: true
|
|
29
|
+
})).pipe(tap(()=>{
|
|
30
|
+
telemetryStoreDebug(`Deleted file ${reason}: %s`, filePath);
|
|
31
|
+
}), catchError((error)=>{
|
|
32
|
+
telemetryStoreDebug('Error deleting file %s: %o', filePath, error);
|
|
33
|
+
// of() is not same as of(undefined) in rxjs
|
|
34
|
+
// eslint-disable-next-line unicorn/no-useless-undefined
|
|
35
|
+
return of(undefined);
|
|
36
|
+
}))), // Collect all deletions into a single completion value
|
|
37
|
+
reduce(()=>undefined, undefined));
|
|
38
|
+
};
|
|
39
|
+
const flush$ = defer(()=>from(options.resolveConsent())).pipe(tap((currentConsent)=>{
|
|
40
|
+
telemetryStoreDebug('Current consent status for flush: %s', currentConsent.status);
|
|
41
|
+
}), switchMap((currentConsent)=>{
|
|
42
|
+
// First cleanup old files, then process current files
|
|
43
|
+
return defer(()=>from(cleanupOldTelemetryFiles())).pipe(switchMap(()=>defer(()=>from(findTelemetryFiles()))), switchMap((filePaths)=>{
|
|
44
|
+
if (filePaths.length === 0) {
|
|
45
|
+
telemetryStoreDebug('No telemetry files found, nothing to flush');
|
|
46
|
+
return of({
|
|
47
|
+
allEvents: [],
|
|
48
|
+
consent: currentConsent,
|
|
49
|
+
emptyFiles: [],
|
|
50
|
+
filesToDelete: []
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
telemetryStoreDebug('Found %d telemetry files to process', filePaths.length);
|
|
54
|
+
return from(filePaths).pipe(mergeMap((filePath)=>{
|
|
55
|
+
return defer(()=>from(readNDJSON(filePath))).pipe(tap((events)=>{
|
|
56
|
+
telemetryStoreDebug('Read %d events from %s', events.length, filePath);
|
|
57
|
+
}), catchError((error)=>{
|
|
58
|
+
if (error.code === 'ENOENT') {
|
|
59
|
+
telemetryStoreDebug('File %s no longer exists, skipping', filePath);
|
|
60
|
+
return of([]);
|
|
61
|
+
}
|
|
62
|
+
telemetryStoreDebug('Error reading file %s: %o', filePath, error);
|
|
63
|
+
return of([]);
|
|
64
|
+
}), map((events)=>({
|
|
65
|
+
events,
|
|
66
|
+
filePath
|
|
67
|
+
})));
|
|
68
|
+
}), reduce((acc, current)=>{
|
|
69
|
+
if (current.events.length > 0) {
|
|
70
|
+
acc.allEvents.push(...current.events);
|
|
71
|
+
acc.filesToDelete.push(current.filePath);
|
|
72
|
+
} else {
|
|
73
|
+
acc.emptyFiles.push(current.filePath);
|
|
74
|
+
}
|
|
75
|
+
return acc;
|
|
76
|
+
}, {
|
|
77
|
+
allEvents: [],
|
|
78
|
+
emptyFiles: [],
|
|
79
|
+
filesToDelete: []
|
|
80
|
+
}), map((result)=>({
|
|
81
|
+
...result,
|
|
82
|
+
consent: currentConsent
|
|
83
|
+
})));
|
|
84
|
+
}));
|
|
85
|
+
}), switchMap(({ allEvents, consent, emptyFiles, filesToDelete })=>{
|
|
86
|
+
telemetryStoreDebug('Found %d total events to flush from %d files (%d empty)', allEvents.length, filesToDelete.length, emptyFiles.length);
|
|
87
|
+
// Always clean up empty files regardless of consent or event count
|
|
88
|
+
const cleanupEmpty$ = emptyFiles.length > 0 ? deleteFiles(emptyFiles, 'empty files') : of(undefined);
|
|
89
|
+
if (consent.status !== 'granted' || allEvents.length === 0) {
|
|
90
|
+
if (consent.status === 'granted') {
|
|
91
|
+
telemetryStoreDebug('No events to send, cleaning up files');
|
|
92
|
+
return cleanupEmpty$;
|
|
93
|
+
} else {
|
|
94
|
+
telemetryStoreDebug('Consent not granted (%s), cleaning up %d files without sending events', consent.status, filesToDelete.length);
|
|
95
|
+
return deleteFiles([
|
|
96
|
+
...filesToDelete,
|
|
97
|
+
...emptyFiles
|
|
98
|
+
], `without sending (consent: ${consent.status})`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// Send events and then delete all files (including empty ones)
|
|
102
|
+
telemetryStoreDebug('Sending %d events to backend', allEvents.length);
|
|
103
|
+
return defer(()=>from(options.sendEvents(allEvents))).pipe(tap(()=>{
|
|
104
|
+
telemetryStoreDebug('Successfully sent events, deleting %d files', filesToDelete.length);
|
|
105
|
+
}), switchMap(()=>deleteFiles([
|
|
106
|
+
...filesToDelete,
|
|
107
|
+
...emptyFiles
|
|
108
|
+
], 'after successful send')));
|
|
109
|
+
}), tap(()=>{
|
|
110
|
+
telemetryStoreDebug('Standalone flush operation completed successfully');
|
|
111
|
+
}), map(()=>undefined), catchError((error)=>{
|
|
112
|
+
telemetryStoreDebug('Error during standalone flush operation: %o', error);
|
|
113
|
+
throw error;
|
|
114
|
+
}));
|
|
115
|
+
return lastValueFrom(flush$);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
//# sourceMappingURL=flushTelemetryFiles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/util/telemetry/flushTelemetryFiles.ts"],"sourcesContent":["import {rm} from 'node:fs/promises'\n\nimport {type ConsentInformation} from '@sanity/cli-core'\nimport {type TelemetryEvent} from '@sanity/telemetry'\nimport {\n catchError,\n defer,\n from,\n lastValueFrom,\n map,\n mergeMap,\n of,\n reduce,\n switchMap,\n tap,\n} from 'rxjs'\n\nimport {cleanupOldTelemetryFiles} from './cleanupOldTelemetryFiles.js'\nimport {findTelemetryFiles} from './findTelemetryFiles.js'\nimport {readNDJSON} from './readNDJSON.js'\nimport {telemetryStoreDebug} from './telemetryStoreDebug.js'\n\ninterface FlushTelemetryFilesOptions {\n resolveConsent: () => Promise<ConsentInformation>\n sendEvents: (events: TelemetryEvent[]) => Promise<void>\n}\n\n/**\n * Standalone, stateless function to flush telemetry files.\n *\n * This function can be used independently of the telemetry store, making it\n * suitable for use in child processes or other contexts where store state\n * is not available.\n *\n * @param options - Configuration for consent resolution and event sending\n * @returns Promise that resolves when flush operation is complete\n *\n * @internal\n */\nexport async function flushTelemetryFiles(options: FlushTelemetryFilesOptions): Promise<void> {\n telemetryStoreDebug('Starting standalone flush operation')\n\n // Helper function for deleting files with consistent error handling\n const deleteFiles = (files: string[], reason: string) => {\n if (files.length === 0) {\n // of() is not same as of(undefined) in rxjs\n // eslint-disable-next-line unicorn/no-useless-undefined\n return of(undefined)\n }\n\n return from(files).pipe(\n mergeMap((filePath) =>\n from(rm(filePath, {force: true})).pipe(\n tap(() => {\n telemetryStoreDebug(`Deleted file ${reason}: %s`, filePath)\n }),\n catchError((error) => {\n telemetryStoreDebug('Error deleting file %s: %o', filePath, error)\n // of() is not same as of(undefined) in rxjs\n // eslint-disable-next-line unicorn/no-useless-undefined\n return of(undefined)\n }),\n ),\n ),\n // Collect all deletions into a single completion value\n reduce(() => undefined as void, undefined as void),\n )\n }\n\n const flush$ = defer(() => from(options.resolveConsent())).pipe(\n tap((currentConsent) => {\n telemetryStoreDebug('Current consent status for flush: %s', currentConsent.status)\n }),\n switchMap((currentConsent) => {\n // First cleanup old files, then process current files\n return defer(() => from(cleanupOldTelemetryFiles())).pipe(\n switchMap(() => defer(() => from(findTelemetryFiles()))),\n switchMap((filePaths) => {\n if (filePaths.length === 0) {\n telemetryStoreDebug('No telemetry files found, nothing to flush')\n return of({allEvents: [], consent: currentConsent, emptyFiles: [], filesToDelete: []})\n }\n\n telemetryStoreDebug('Found %d telemetry files to process', filePaths.length)\n\n return from(filePaths).pipe(\n mergeMap((filePath) => {\n return defer(() => from(readNDJSON<TelemetryEvent>(filePath))).pipe(\n tap((events) => {\n telemetryStoreDebug('Read %d events from %s', events.length, filePath)\n }),\n catchError((error) => {\n if ((error as {code?: string}).code === 'ENOENT') {\n telemetryStoreDebug('File %s no longer exists, skipping', filePath)\n return of([])\n }\n telemetryStoreDebug('Error reading file %s: %o', filePath, error)\n return of([])\n }),\n map((events) => ({events, filePath})),\n )\n }),\n reduce(\n (\n acc: {allEvents: TelemetryEvent[]; emptyFiles: string[]; filesToDelete: string[]},\n current,\n ) => {\n if (current.events.length > 0) {\n acc.allEvents.push(...current.events)\n acc.filesToDelete.push(current.filePath)\n } else {\n acc.emptyFiles.push(current.filePath)\n }\n return acc\n },\n {allEvents: [], emptyFiles: [], filesToDelete: []},\n ),\n map((result) => ({...result, consent: currentConsent})),\n )\n }),\n )\n }),\n switchMap(({allEvents, consent, emptyFiles, filesToDelete}) => {\n telemetryStoreDebug(\n 'Found %d total events to flush from %d files (%d empty)',\n allEvents.length,\n filesToDelete.length,\n emptyFiles.length,\n )\n\n // Always clean up empty files regardless of consent or event count\n const cleanupEmpty$ =\n emptyFiles.length > 0 ? deleteFiles(emptyFiles, 'empty files') : of(undefined as void)\n\n if (consent.status !== 'granted' || allEvents.length === 0) {\n if (consent.status === 'granted') {\n telemetryStoreDebug('No events to send, cleaning up files')\n return cleanupEmpty$\n } else {\n telemetryStoreDebug(\n 'Consent not granted (%s), cleaning up %d files without sending events',\n consent.status,\n filesToDelete.length,\n )\n return deleteFiles(\n [...filesToDelete, ...emptyFiles],\n `without sending (consent: ${consent.status})`,\n )\n }\n }\n\n // Send events and then delete all files (including empty ones)\n telemetryStoreDebug('Sending %d events to backend', allEvents.length)\n\n return defer(() => from(options.sendEvents(allEvents))).pipe(\n tap(() => {\n telemetryStoreDebug('Successfully sent events, deleting %d files', filesToDelete.length)\n }),\n switchMap(() => deleteFiles([...filesToDelete, ...emptyFiles], 'after successful send')),\n )\n }),\n tap(() => {\n telemetryStoreDebug('Standalone flush operation completed successfully')\n }),\n map(() => undefined as void),\n catchError((error) => {\n telemetryStoreDebug('Error during standalone flush operation: %o', error)\n throw error\n }),\n )\n\n return lastValueFrom(flush$)\n}\n"],"names":["rm","catchError","defer","from","lastValueFrom","map","mergeMap","of","reduce","switchMap","tap","cleanupOldTelemetryFiles","findTelemetryFiles","readNDJSON","telemetryStoreDebug","flushTelemetryFiles","options","deleteFiles","files","reason","length","undefined","pipe","filePath","force","error","flush$","resolveConsent","currentConsent","status","filePaths","allEvents","consent","emptyFiles","filesToDelete","events","code","acc","current","push","result","cleanupEmpty$","sendEvents"],"mappings":"AAAA,SAAQA,EAAE,QAAO,mBAAkB;AAInC,SACEC,UAAU,EACVC,KAAK,EACLC,IAAI,EACJC,aAAa,EACbC,GAAG,EACHC,QAAQ,EACRC,EAAE,EACFC,MAAM,EACNC,SAAS,EACTC,GAAG,QACE,OAAM;AAEb,SAAQC,wBAAwB,QAAO,gCAA+B;AACtE,SAAQC,kBAAkB,QAAO,0BAAyB;AAC1D,SAAQC,UAAU,QAAO,kBAAiB;AAC1C,SAAQC,mBAAmB,QAAO,2BAA0B;AAO5D;;;;;;;;;;;CAWC,GACD,OAAO,eAAeC,oBAAoBC,OAAmC;IAC3EF,oBAAoB;IAEpB,oEAAoE;IACpE,MAAMG,cAAc,CAACC,OAAiBC;QACpC,IAAID,MAAME,MAAM,KAAK,GAAG;YACtB,4CAA4C;YAC5C,wDAAwD;YACxD,OAAOb,GAAGc;QACZ;QAEA,OAAOlB,KAAKe,OAAOI,IAAI,CACrBhB,SAAS,CAACiB,WACRpB,KAAKH,GAAGuB,UAAU;gBAACC,OAAO;YAAI,IAAIF,IAAI,CACpCZ,IAAI;gBACFI,oBAAoB,CAAC,aAAa,EAAEK,OAAO,IAAI,CAAC,EAAEI;YACpD,IACAtB,WAAW,CAACwB;gBACVX,oBAAoB,8BAA8BS,UAAUE;gBAC5D,4CAA4C;gBAC5C,wDAAwD;gBACxD,OAAOlB,GAAGc;YACZ,MAGJ,uDAAuD;QACvDb,OAAO,IAAMa,WAAmBA;IAEpC;IAEA,MAAMK,SAASxB,MAAM,IAAMC,KAAKa,QAAQW,cAAc,KAAKL,IAAI,CAC7DZ,IAAI,CAACkB;QACHd,oBAAoB,wCAAwCc,eAAeC,MAAM;IACnF,IACApB,UAAU,CAACmB;QACT,sDAAsD;QACtD,OAAO1B,MAAM,IAAMC,KAAKQ,6BAA6BW,IAAI,CACvDb,UAAU,IAAMP,MAAM,IAAMC,KAAKS,yBACjCH,UAAU,CAACqB;YACT,IAAIA,UAAUV,MAAM,KAAK,GAAG;gBAC1BN,oBAAoB;gBACpB,OAAOP,GAAG;oBAACwB,WAAW,EAAE;oBAAEC,SAASJ;oBAAgBK,YAAY,EAAE;oBAAEC,eAAe,EAAE;gBAAA;YACtF;YAEApB,oBAAoB,uCAAuCgB,UAAUV,MAAM;YAE3E,OAAOjB,KAAK2B,WAAWR,IAAI,CACzBhB,SAAS,CAACiB;gBACR,OAAOrB,MAAM,IAAMC,KAAKU,WAA2BU,YAAYD,IAAI,CACjEZ,IAAI,CAACyB;oBACHrB,oBAAoB,0BAA0BqB,OAAOf,MAAM,EAAEG;gBAC/D,IACAtB,WAAW,CAACwB;oBACV,IAAI,AAACA,MAA0BW,IAAI,KAAK,UAAU;wBAChDtB,oBAAoB,sCAAsCS;wBAC1D,OAAOhB,GAAG,EAAE;oBACd;oBACAO,oBAAoB,6BAA6BS,UAAUE;oBAC3D,OAAOlB,GAAG,EAAE;gBACd,IACAF,IAAI,CAAC8B,SAAY,CAAA;wBAACA;wBAAQZ;oBAAQ,CAAA;YAEtC,IACAf,OACE,CACE6B,KACAC;gBAEA,IAAIA,QAAQH,MAAM,CAACf,MAAM,GAAG,GAAG;oBAC7BiB,IAAIN,SAAS,CAACQ,IAAI,IAAID,QAAQH,MAAM;oBACpCE,IAAIH,aAAa,CAACK,IAAI,CAACD,QAAQf,QAAQ;gBACzC,OAAO;oBACLc,IAAIJ,UAAU,CAACM,IAAI,CAACD,QAAQf,QAAQ;gBACtC;gBACA,OAAOc;YACT,GACA;gBAACN,WAAW,EAAE;gBAAEE,YAAY,EAAE;gBAAEC,eAAe,EAAE;YAAA,IAEnD7B,IAAI,CAACmC,SAAY,CAAA;oBAAC,GAAGA,MAAM;oBAAER,SAASJ;gBAAc,CAAA;QAExD;IAEJ,IACAnB,UAAU,CAAC,EAACsB,SAAS,EAAEC,OAAO,EAAEC,UAAU,EAAEC,aAAa,EAAC;QACxDpB,oBACE,2DACAiB,UAAUX,MAAM,EAChBc,cAAcd,MAAM,EACpBa,WAAWb,MAAM;QAGnB,mEAAmE;QACnE,MAAMqB,gBACJR,WAAWb,MAAM,GAAG,IAAIH,YAAYgB,YAAY,iBAAiB1B,GAAGc;QAEtE,IAAIW,QAAQH,MAAM,KAAK,aAAaE,UAAUX,MAAM,KAAK,GAAG;YAC1D,IAAIY,QAAQH,MAAM,KAAK,WAAW;gBAChCf,oBAAoB;gBACpB,OAAO2B;YACT,OAAO;gBACL3B,oBACE,yEACAkB,QAAQH,MAAM,EACdK,cAAcd,MAAM;gBAEtB,OAAOH,YACL;uBAAIiB;uBAAkBD;iBAAW,EACjC,CAAC,0BAA0B,EAAED,QAAQH,MAAM,CAAC,CAAC,CAAC;YAElD;QACF;QAEA,+DAA+D;QAC/Df,oBAAoB,gCAAgCiB,UAAUX,MAAM;QAEpE,OAAOlB,MAAM,IAAMC,KAAKa,QAAQ0B,UAAU,CAACX,aAAaT,IAAI,CAC1DZ,IAAI;YACFI,oBAAoB,+CAA+CoB,cAAcd,MAAM;QACzF,IACAX,UAAU,IAAMQ,YAAY;mBAAIiB;mBAAkBD;aAAW,EAAE;IAEnE,IACAvB,IAAI;QACFI,oBAAoB;IACtB,IACAT,IAAI,IAAMgB,YACVpB,WAAW,CAACwB;QACVX,oBAAoB,+CAA+CW;QACnE,MAAMA;IACR;IAGF,OAAOrB,cAAcsB;AACvB"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { getTelemetryBaseInfo } from '@sanity/cli-core';
|
|
3
|
+
import { telemetryStoreDebug } from './telemetryStoreDebug.js';
|
|
4
|
+
/**
|
|
5
|
+
* Generates a unique telemetry file path for a specific CLI session.
|
|
6
|
+
*
|
|
7
|
+
* File format: `telemetry-\{hashedToken\}-\{env\}-\{sessionId\}.ndjson`
|
|
8
|
+
*
|
|
9
|
+
* The sessionId ensures each CLI process writes to its own file, preventing:
|
|
10
|
+
* - File write conflicts when multiple CLI commands run concurrently
|
|
11
|
+
* - Race conditions during file operations
|
|
12
|
+
* - Data corruption from simultaneous writes
|
|
13
|
+
*
|
|
14
|
+
* During flush, all session files are discovered and aggregated together.
|
|
15
|
+
*
|
|
16
|
+
* @param sessionId - Unique identifier for this CLI session
|
|
17
|
+
* @returns Promise resolving to the full file path for this session's telemetry
|
|
18
|
+
* @internal
|
|
19
|
+
*/ export async function generateTelemetryFilePath(sessionId) {
|
|
20
|
+
telemetryStoreDebug('Generating telemetry file path for sessionId: %s', sessionId);
|
|
21
|
+
const { basePattern, directory, environment, hashedToken } = await getTelemetryBaseInfo();
|
|
22
|
+
telemetryStoreDebug('Generated token hash: %s', hashedToken);
|
|
23
|
+
telemetryStoreDebug('Detected environment: %s', environment);
|
|
24
|
+
const fileName = `${basePattern}-${sessionId}.ndjson`;
|
|
25
|
+
const filePath = join(directory, fileName);
|
|
26
|
+
telemetryStoreDebug('Telemetry file path: %s', filePath);
|
|
27
|
+
return filePath;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
//# sourceMappingURL=generateTelemetryFilePath.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/util/telemetry/generateTelemetryFilePath.ts"],"sourcesContent":["import {join} from 'node:path'\n\nimport {getTelemetryBaseInfo} from '@sanity/cli-core'\n\nimport {telemetryStoreDebug} from './telemetryStoreDebug.js'\n\n/**\n * Generates a unique telemetry file path for a specific CLI session.\n *\n * File format: `telemetry-\\{hashedToken\\}-\\{env\\}-\\{sessionId\\}.ndjson`\n *\n * The sessionId ensures each CLI process writes to its own file, preventing:\n * - File write conflicts when multiple CLI commands run concurrently\n * - Race conditions during file operations\n * - Data corruption from simultaneous writes\n *\n * During flush, all session files are discovered and aggregated together.\n *\n * @param sessionId - Unique identifier for this CLI session\n * @returns Promise resolving to the full file path for this session's telemetry\n * @internal\n */\nexport async function generateTelemetryFilePath(sessionId: string): Promise<string> {\n telemetryStoreDebug('Generating telemetry file path for sessionId: %s', sessionId)\n\n const {basePattern, directory, environment, hashedToken} = await getTelemetryBaseInfo()\n\n telemetryStoreDebug('Generated token hash: %s', hashedToken)\n telemetryStoreDebug('Detected environment: %s', environment)\n\n const fileName = `${basePattern}-${sessionId}.ndjson`\n const filePath = join(directory, fileName)\n telemetryStoreDebug('Telemetry file path: %s', filePath)\n\n return filePath\n}\n"],"names":["join","getTelemetryBaseInfo","telemetryStoreDebug","generateTelemetryFilePath","sessionId","basePattern","directory","environment","hashedToken","fileName","filePath"],"mappings":"AAAA,SAAQA,IAAI,QAAO,YAAW;AAE9B,SAAQC,oBAAoB,QAAO,mBAAkB;AAErD,SAAQC,mBAAmB,QAAO,2BAA0B;AAE5D;;;;;;;;;;;;;;;CAeC,GACD,OAAO,eAAeC,0BAA0BC,SAAiB;IAC/DF,oBAAoB,oDAAoDE;IAExE,MAAM,EAACC,WAAW,EAAEC,SAAS,EAAEC,WAAW,EAAEC,WAAW,EAAC,GAAG,MAAMP;IAEjEC,oBAAoB,4BAA4BM;IAChDN,oBAAoB,4BAA4BK;IAEhD,MAAME,WAAW,GAAGJ,YAAY,CAAC,EAAED,UAAU,OAAO,CAAC;IACrD,MAAMM,WAAWV,KAAKM,WAAWG;IACjCP,oBAAoB,2BAA2BQ;IAE/C,OAAOA;AACT"}
|