@sanity/cli 8.18.0 → 8.19.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.
@@ -58,12 +58,16 @@ export async function bootstrapRemoteTemplate(opts) {
58
58
  const readToken = needsReadToken ? (await createToken({
59
59
  label: READ_TOKEN_LABEL,
60
60
  projectId: variables.projectId,
61
- roleName: API_READ_TOKEN_ROLE
61
+ roleNames: [
62
+ API_READ_TOKEN_ROLE
63
+ ]
62
64
  })).token : undefined;
63
65
  const writeToken = needsWriteToken ? (await createToken({
64
66
  label: WRITE_TOKEN_LABEL,
65
67
  projectId: variables.projectId,
66
- roleName: API_WRITE_TOKEN_ROLE
68
+ roleNames: [
69
+ API_WRITE_TOKEN_ROLE
70
+ ]
67
71
  })).token : undefined;
68
72
  for (const pkg of packages ?? [
69
73
  ''
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/init/bootstrapRemoteTemplate.ts"],"sourcesContent":["import {mkdir} from 'node:fs/promises'\nimport {join} from 'node:path'\n\nimport {Output, subdebug} from '@sanity/cli-core'\nimport {logSymbols, spinner} from '@sanity/cli-core/ux'\nimport {getMonoRepo, GitHubFileReader, validateTemplate} from '@sanity/template-validator'\nimport {type Framework, frameworks} from '@vercel/frameworks'\n\nimport {createCorsOrigin} from '../../services/cors.js'\nimport {createToken} from '../../services/tokens.js'\nimport {detectFrameworkRecord} from '../../util/detectFramework.js'\nimport {getDefaultPortForFramework} from '../../util/frameworkPort.js'\nimport {type GenerateConfigOptions} from './createStudioConfig.js'\nimport {tryGitInit} from './git.js'\nimport {\n applyEnvVariables,\n checkIfNeedsApiToken,\n downloadAndExtractRepo,\n getGitHubRawContentUrl,\n type RepoInfo,\n tryApplyPackageName,\n} from './remoteTemplate.js'\nimport {updateInitialTemplateMetadata} from './updateInitialTemplateMetadata.js'\n\nconst debug = subdebug('init:bootstrapRemoteTemplate')\n\ninterface BootstrapRemoteOptions {\n output: Output\n outputPath: string\n packageName: string\n repoInfo: RepoInfo\n variables: GenerateConfigOptions['variables']\n\n bearerToken?: string\n}\n\nconst SANITY_DEFAULT_PORT = 3333\nconst READ_TOKEN_LABEL = 'Live Preview API'\nconst WRITE_TOKEN_LABEL = 'App Write Token'\nconst INITIAL_COMMIT_MESSAGE = 'Initial commit from Sanity CLI'\nconst API_READ_TOKEN_ROLE = 'viewer'\nconst API_WRITE_TOKEN_ROLE = 'editor'\n\nexport async function bootstrapRemoteTemplate(opts: BootstrapRemoteOptions): Promise<void> {\n const {bearerToken, output, outputPath, packageName, repoInfo, variables} = opts\n const name = [repoInfo.username, repoInfo.name, repoInfo.filePath].filter(Boolean).join('/')\n const contentsUrl = getGitHubRawContentUrl(repoInfo)\n const headers: Record<string, string> = {}\n if (bearerToken) {\n headers.Authorization = `Bearer ${bearerToken}`\n }\n const spin = spinner(`Bootstrapping files from template \"${name}\"`).start()\n const corsAdded: number[] = [SANITY_DEFAULT_PORT]\n\n debug('Validating remote template')\n const fileReader = new GitHubFileReader(contentsUrl, headers)\n const packages = await getMonoRepo(fileReader)\n const validation = await validateTemplate(fileReader, packages)\n if (!validation.isValid) {\n throw new Error(validation.errors.join('\\n'))\n }\n\n debug('Create new directory \"%s\"', outputPath)\n await mkdir(outputPath, {recursive: true})\n\n debug('Downloading and extracting repo to %s', outputPath)\n await downloadAndExtractRepo(outputPath, repoInfo, bearerToken)\n\n debug('Checking if template needs read token')\n const needsReadToken = await Promise.all(\n (packages ?? ['']).map((pkg) => checkIfNeedsApiToken(join(outputPath, pkg), 'read')),\n ).then((results) => results.some(Boolean))\n const needsWriteToken = await Promise.all(\n (packages ?? ['']).map((pkg) => checkIfNeedsApiToken(join(outputPath, pkg), 'write')),\n ).then((results) => results.some(Boolean))\n\n debug('Applying environment variables')\n const readToken = needsReadToken\n ? (\n await createToken({\n label: READ_TOKEN_LABEL,\n projectId: variables.projectId,\n roleName: API_READ_TOKEN_ROLE,\n })\n ).token\n : undefined\n const writeToken = needsWriteToken\n ? (\n await createToken({\n label: WRITE_TOKEN_LABEL,\n projectId: variables.projectId,\n roleName: API_WRITE_TOKEN_ROLE,\n })\n ).token\n : undefined\n\n for (const pkg of packages ?? ['']) {\n const packagePath = join(outputPath, pkg)\n const packageFramework: Framework | null = await detectFrameworkRecord({\n frameworkList: frameworks as readonly Framework[],\n rootPath: packagePath,\n })\n\n const port = getDefaultPortForFramework(packageFramework?.slug)\n if (!corsAdded.includes(port)) {\n debug('Setting CORS origin to http://localhost:%d', port)\n await createCorsOrigin({\n allowCredentials: true,\n origin: `http://localhost:${port}`,\n projectId: variables.projectId,\n })\n corsAdded.push(port)\n }\n\n debug('Applying environment variables to %s', pkg)\n // Next.js uses `.env.local` for local environment variables\n const envName = packageFramework?.slug === 'nextjs' ? '.env.local' : '.env'\n await applyEnvVariables(packagePath, {...variables, readToken, writeToken}, envName)\n }\n\n debug('Setting package name to %s', packageName)\n await tryApplyPackageName(outputPath, packageName)\n\n debug('Initializing git repository')\n tryGitInit(outputPath, INITIAL_COMMIT_MESSAGE)\n\n debug('Updating initial template metadata')\n await updateInitialTemplateMetadata(variables.projectId, `external-${name}`)\n\n spin.succeed()\n const newlyAddedPorts = corsAdded.slice(1)\n if (newlyAddedPorts.length > 0) {\n output.log(\n `${logSymbols.success} CORS origins added (${newlyAddedPorts.map((p) => `localhost:${p}`).join(', ')})`,\n )\n }\n if (readToken) output.log(`${logSymbols.success} API token generated (${READ_TOKEN_LABEL})`)\n if (writeToken) output.log(`${logSymbols.success} API token generated (${WRITE_TOKEN_LABEL})`)\n}\n"],"names":["mkdir","join","subdebug","logSymbols","spinner","getMonoRepo","GitHubFileReader","validateTemplate","frameworks","createCorsOrigin","createToken","detectFrameworkRecord","getDefaultPortForFramework","tryGitInit","applyEnvVariables","checkIfNeedsApiToken","downloadAndExtractRepo","getGitHubRawContentUrl","tryApplyPackageName","updateInitialTemplateMetadata","debug","SANITY_DEFAULT_PORT","READ_TOKEN_LABEL","WRITE_TOKEN_LABEL","INITIAL_COMMIT_MESSAGE","API_READ_TOKEN_ROLE","API_WRITE_TOKEN_ROLE","bootstrapRemoteTemplate","opts","bearerToken","output","outputPath","packageName","repoInfo","variables","name","username","filePath","filter","Boolean","contentsUrl","headers","Authorization","spin","start","corsAdded","fileReader","packages","validation","isValid","Error","errors","recursive","needsReadToken","Promise","all","map","pkg","then","results","some","needsWriteToken","readToken","label","projectId","roleName","token","undefined","writeToken","packagePath","packageFramework","frameworkList","rootPath","port","slug","includes","allowCredentials","origin","push","envName","succeed","newlyAddedPorts","slice","length","log","success","p"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/actions/init/bootstrapRemoteTemplate.ts"],"sourcesContent":["import {mkdir} from 'node:fs/promises'\nimport {join} from 'node:path'\n\nimport {Output, subdebug} from '@sanity/cli-core'\nimport {logSymbols, spinner} from '@sanity/cli-core/ux'\nimport {getMonoRepo, GitHubFileReader, validateTemplate} from '@sanity/template-validator'\nimport {type Framework, frameworks} from '@vercel/frameworks'\n\nimport {createCorsOrigin} from '../../services/cors.js'\nimport {createToken} from '../../services/tokens.js'\nimport {detectFrameworkRecord} from '../../util/detectFramework.js'\nimport {getDefaultPortForFramework} from '../../util/frameworkPort.js'\nimport {type GenerateConfigOptions} from './createStudioConfig.js'\nimport {tryGitInit} from './git.js'\nimport {\n applyEnvVariables,\n checkIfNeedsApiToken,\n downloadAndExtractRepo,\n getGitHubRawContentUrl,\n type RepoInfo,\n tryApplyPackageName,\n} from './remoteTemplate.js'\nimport {updateInitialTemplateMetadata} from './updateInitialTemplateMetadata.js'\n\nconst debug = subdebug('init:bootstrapRemoteTemplate')\n\ninterface BootstrapRemoteOptions {\n output: Output\n outputPath: string\n packageName: string\n repoInfo: RepoInfo\n variables: GenerateConfigOptions['variables']\n\n bearerToken?: string\n}\n\nconst SANITY_DEFAULT_PORT = 3333\nconst READ_TOKEN_LABEL = 'Live Preview API'\nconst WRITE_TOKEN_LABEL = 'App Write Token'\nconst INITIAL_COMMIT_MESSAGE = 'Initial commit from Sanity CLI'\nconst API_READ_TOKEN_ROLE = 'viewer'\nconst API_WRITE_TOKEN_ROLE = 'editor'\n\nexport async function bootstrapRemoteTemplate(opts: BootstrapRemoteOptions): Promise<void> {\n const {bearerToken, output, outputPath, packageName, repoInfo, variables} = opts\n const name = [repoInfo.username, repoInfo.name, repoInfo.filePath].filter(Boolean).join('/')\n const contentsUrl = getGitHubRawContentUrl(repoInfo)\n const headers: Record<string, string> = {}\n if (bearerToken) {\n headers.Authorization = `Bearer ${bearerToken}`\n }\n const spin = spinner(`Bootstrapping files from template \"${name}\"`).start()\n const corsAdded: number[] = [SANITY_DEFAULT_PORT]\n\n debug('Validating remote template')\n const fileReader = new GitHubFileReader(contentsUrl, headers)\n const packages = await getMonoRepo(fileReader)\n const validation = await validateTemplate(fileReader, packages)\n if (!validation.isValid) {\n throw new Error(validation.errors.join('\\n'))\n }\n\n debug('Create new directory \"%s\"', outputPath)\n await mkdir(outputPath, {recursive: true})\n\n debug('Downloading and extracting repo to %s', outputPath)\n await downloadAndExtractRepo(outputPath, repoInfo, bearerToken)\n\n debug('Checking if template needs read token')\n const needsReadToken = await Promise.all(\n (packages ?? ['']).map((pkg) => checkIfNeedsApiToken(join(outputPath, pkg), 'read')),\n ).then((results) => results.some(Boolean))\n const needsWriteToken = await Promise.all(\n (packages ?? ['']).map((pkg) => checkIfNeedsApiToken(join(outputPath, pkg), 'write')),\n ).then((results) => results.some(Boolean))\n\n debug('Applying environment variables')\n const readToken = needsReadToken\n ? (\n await createToken({\n label: READ_TOKEN_LABEL,\n projectId: variables.projectId,\n roleNames: [API_READ_TOKEN_ROLE],\n })\n ).token\n : undefined\n const writeToken = needsWriteToken\n ? (\n await createToken({\n label: WRITE_TOKEN_LABEL,\n projectId: variables.projectId,\n roleNames: [API_WRITE_TOKEN_ROLE],\n })\n ).token\n : undefined\n\n for (const pkg of packages ?? ['']) {\n const packagePath = join(outputPath, pkg)\n const packageFramework: Framework | null = await detectFrameworkRecord({\n frameworkList: frameworks as readonly Framework[],\n rootPath: packagePath,\n })\n\n const port = getDefaultPortForFramework(packageFramework?.slug)\n if (!corsAdded.includes(port)) {\n debug('Setting CORS origin to http://localhost:%d', port)\n await createCorsOrigin({\n allowCredentials: true,\n origin: `http://localhost:${port}`,\n projectId: variables.projectId,\n })\n corsAdded.push(port)\n }\n\n debug('Applying environment variables to %s', pkg)\n // Next.js uses `.env.local` for local environment variables\n const envName = packageFramework?.slug === 'nextjs' ? '.env.local' : '.env'\n await applyEnvVariables(packagePath, {...variables, readToken, writeToken}, envName)\n }\n\n debug('Setting package name to %s', packageName)\n await tryApplyPackageName(outputPath, packageName)\n\n debug('Initializing git repository')\n tryGitInit(outputPath, INITIAL_COMMIT_MESSAGE)\n\n debug('Updating initial template metadata')\n await updateInitialTemplateMetadata(variables.projectId, `external-${name}`)\n\n spin.succeed()\n const newlyAddedPorts = corsAdded.slice(1)\n if (newlyAddedPorts.length > 0) {\n output.log(\n `${logSymbols.success} CORS origins added (${newlyAddedPorts.map((p) => `localhost:${p}`).join(', ')})`,\n )\n }\n if (readToken) output.log(`${logSymbols.success} API token generated (${READ_TOKEN_LABEL})`)\n if (writeToken) output.log(`${logSymbols.success} API token generated (${WRITE_TOKEN_LABEL})`)\n}\n"],"names":["mkdir","join","subdebug","logSymbols","spinner","getMonoRepo","GitHubFileReader","validateTemplate","frameworks","createCorsOrigin","createToken","detectFrameworkRecord","getDefaultPortForFramework","tryGitInit","applyEnvVariables","checkIfNeedsApiToken","downloadAndExtractRepo","getGitHubRawContentUrl","tryApplyPackageName","updateInitialTemplateMetadata","debug","SANITY_DEFAULT_PORT","READ_TOKEN_LABEL","WRITE_TOKEN_LABEL","INITIAL_COMMIT_MESSAGE","API_READ_TOKEN_ROLE","API_WRITE_TOKEN_ROLE","bootstrapRemoteTemplate","opts","bearerToken","output","outputPath","packageName","repoInfo","variables","name","username","filePath","filter","Boolean","contentsUrl","headers","Authorization","spin","start","corsAdded","fileReader","packages","validation","isValid","Error","errors","recursive","needsReadToken","Promise","all","map","pkg","then","results","some","needsWriteToken","readToken","label","projectId","roleNames","token","undefined","writeToken","packagePath","packageFramework","frameworkList","rootPath","port","slug","includes","allowCredentials","origin","push","envName","succeed","newlyAddedPorts","slice","length","log","success","p"],"mappings":"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"}
@@ -0,0 +1,192 @@
1
+ export const DEFAULT_ROLE = {
2
+ name: 'viewer',
3
+ title: 'Viewer'
4
+ };
5
+ const PROJECT_PREFIX = 'project:';
6
+ const viewer = (roleName)=>({
7
+ key: 'viewer',
8
+ roleName,
9
+ title: 'Viewer'
10
+ });
11
+ const editor = (roleName)=>({
12
+ key: 'editor',
13
+ roleName,
14
+ title: 'Editor'
15
+ });
16
+ export const ORG_PERMISSIONS = [
17
+ {
18
+ key: 'context',
19
+ roles: [
20
+ viewer('knowledge-base-viewer-robot'),
21
+ editor('knowledge-base-editor-robot'),
22
+ {
23
+ key: 'developer',
24
+ roleName: 'knowledge-base-developer-robot',
25
+ title: 'Developer'
26
+ }
27
+ ],
28
+ title: 'Context'
29
+ },
30
+ {
31
+ key: 'blueprints',
32
+ roleName: 'blueprints-deployer-robot',
33
+ title: 'Blueprints'
34
+ },
35
+ {
36
+ key: 'media-library',
37
+ roles: [
38
+ viewer('media-library-viewer-robot'),
39
+ editor('media-library-editor-robot')
40
+ ],
41
+ title: 'Media Library'
42
+ },
43
+ {
44
+ key: 'canvas',
45
+ roles: [
46
+ viewer('canvas-viewer-robot'),
47
+ editor('canvas-editor-robot')
48
+ ],
49
+ title: 'Canvas'
50
+ },
51
+ {
52
+ key: 'sdk-apps',
53
+ roleName: 'sdk-app-editor-robot',
54
+ title: 'Manage SDK Apps'
55
+ },
56
+ {
57
+ key: 'access',
58
+ roles: [
59
+ viewer('access-viewer-robot'),
60
+ editor('access-manager-robot')
61
+ ],
62
+ title: 'Manage Access'
63
+ },
64
+ {
65
+ key: 'deploy-studios',
66
+ roleName: 'deploy-studio-robot',
67
+ title: 'Deploy Studios (all projects)'
68
+ }
69
+ ];
70
+ const findOrgPermission = (key)=>ORG_PERMISSIONS.find((permission)=>permission.key === key);
71
+ const isProjectGrant = (grant)=>grant.key.startsWith(PROJECT_PREFIX);
72
+ const orgGrants = (grants)=>grants.filter((grant)=>!isProjectGrant(grant));
73
+ export function projectGrantKey(projectId) {
74
+ return `${PROJECT_PREFIX}${projectId}`;
75
+ }
76
+ export function parseGrant(value) {
77
+ const [key = '', roleList, ...extra] = value.split('=');
78
+ const roles = roleList?.split(',') ?? [];
79
+ if (extra.length > 0 || roles.includes('')) {
80
+ return {
81
+ error: `Invalid grant "${value}". Use <permission>[=<role>] or project:<projectId>[=<role>[,<role>]]`
82
+ };
83
+ }
84
+ const grant = {
85
+ key,
86
+ roles: roles.length > 0 ? roles : [
87
+ DEFAULT_ROLE.name
88
+ ]
89
+ };
90
+ if (key.startsWith(PROJECT_PREFIX) && key.length > PROJECT_PREFIX.length) {
91
+ return {
92
+ grant
93
+ };
94
+ }
95
+ const permission = findOrgPermission(key);
96
+ if (!permission) {
97
+ const keys = [
98
+ ...ORG_PERMISSIONS.map((p)=>p.key),
99
+ `${PROJECT_PREFIX}<projectId>`
100
+ ];
101
+ return {
102
+ error: `Unknown grant "${key}". Use one of: ${keys.join(', ')}`
103
+ };
104
+ }
105
+ if ('roleName' in permission) {
106
+ return roles.length > 0 ? {
107
+ error: `Grant "${key}" does not take a role. Pass it as --grant ${key}`
108
+ } : {
109
+ grant: {
110
+ key,
111
+ roles: []
112
+ }
113
+ };
114
+ }
115
+ if (roles.length > 1) {
116
+ return {
117
+ error: `Grant "${key}" takes one role. Pass it as --grant ${key}=<role>`
118
+ };
119
+ }
120
+ const roleKeys = permission.roles.map((role)=>role.key);
121
+ if (roles[0] && !roleKeys.includes(roles[0])) {
122
+ return {
123
+ error: `Invalid role "${roles[0]}" for "${key}". Use one of: ${roleKeys.join(', ')}`
124
+ };
125
+ }
126
+ return {
127
+ grant
128
+ };
129
+ }
130
+ export function formatGrant({ key, roles }) {
131
+ return roles.length > 0 ? `${key}=${roles.join(',')}` : key;
132
+ }
133
+ export function findGrantConflict(grants) {
134
+ const roleByPermission = new Map();
135
+ for (const { key, roles } of orgGrants(grants)){
136
+ if (roleByPermission.has(key) && roleByPermission.get(key) !== roles[0]) {
137
+ return `Grant "${key}" was given with different roles. Pass it once.`;
138
+ }
139
+ roleByPermission.set(key, roles[0]);
140
+ }
141
+ return undefined;
142
+ }
143
+ function toOrganizationRoleNames(grants) {
144
+ const roleNames = orgGrants(grants).flatMap(({ key, roles })=>{
145
+ const permission = findOrgPermission(key);
146
+ if (!permission) return [];
147
+ if ('roleName' in permission) return [
148
+ permission.roleName
149
+ ];
150
+ return permission.roles.filter((role)=>roles.includes(role.key)).map((role)=>role.roleName);
151
+ });
152
+ return [
153
+ ...new Set(roleNames)
154
+ ];
155
+ }
156
+ function toProjectMemberships(grants) {
157
+ const rolesByProject = new Map();
158
+ for (const grant of grants.filter((grant)=>isProjectGrant(grant))){
159
+ const projectId = grant.key.slice(PROJECT_PREFIX.length);
160
+ rolesByProject.set(projectId, new Set([
161
+ ...rolesByProject.get(projectId) ?? [],
162
+ ...grant.roles
163
+ ]));
164
+ }
165
+ return [
166
+ ...rolesByProject
167
+ ].map(([resourceId, roleNames])=>({
168
+ resourceId,
169
+ resourceType: 'project',
170
+ roleNames: [
171
+ ...roleNames
172
+ ]
173
+ }));
174
+ }
175
+ export function getProjectTokenMembership(grants) {
176
+ const [membership, ...otherProjects] = toProjectMemberships(grants);
177
+ return otherProjects.length === 0 && toOrganizationRoleNames(grants).length === 0 ? membership : undefined;
178
+ }
179
+ export function toMemberships(grants, organizationId) {
180
+ const roleNames = toOrganizationRoleNames(grants);
181
+ const projectMemberships = toProjectMemberships(grants);
182
+ return roleNames.length > 0 ? [
183
+ {
184
+ resourceId: organizationId,
185
+ resourceType: 'organization',
186
+ roleNames
187
+ },
188
+ ...projectMemberships
189
+ ] : projectMemberships;
190
+ }
191
+
192
+ //# sourceMappingURL=grants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/actions/tokens/grants.ts"],"sourcesContent":["import {type Membership, type SelectedTokenRole} from './types.js'\n\ntype OrgRole = {key: string; roleName: string; title: string}\n\nexport type OrgPermission = {key: string; title: string} & ({roleName: string} | {roles: OrgRole[]})\n\nexport type Grant = {key: string; roles: string[]}\n\nexport const DEFAULT_ROLE = {\n name: 'viewer',\n title: 'Viewer',\n} satisfies SelectedTokenRole\n\nconst PROJECT_PREFIX = 'project:'\n\nconst viewer = (roleName: string): OrgRole => ({\n key: 'viewer',\n roleName,\n title: 'Viewer',\n})\nconst editor = (roleName: string): OrgRole => ({\n key: 'editor',\n roleName,\n title: 'Editor',\n})\n\nexport const ORG_PERMISSIONS: OrgPermission[] = [\n {\n key: 'context',\n roles: [\n viewer('knowledge-base-viewer-robot'),\n editor('knowledge-base-editor-robot'),\n {\n key: 'developer',\n roleName: 'knowledge-base-developer-robot',\n title: 'Developer',\n },\n ],\n title: 'Context',\n },\n {\n key: 'blueprints',\n roleName: 'blueprints-deployer-robot',\n title: 'Blueprints',\n },\n {\n key: 'media-library',\n roles: [viewer('media-library-viewer-robot'), editor('media-library-editor-robot')],\n title: 'Media Library',\n },\n {\n key: 'canvas',\n roles: [viewer('canvas-viewer-robot'), editor('canvas-editor-robot')],\n title: 'Canvas',\n },\n {\n key: 'sdk-apps',\n roleName: 'sdk-app-editor-robot',\n title: 'Manage SDK Apps',\n },\n {\n key: 'access',\n roles: [viewer('access-viewer-robot'), editor('access-manager-robot')],\n title: 'Manage Access',\n },\n {\n key: 'deploy-studios',\n roleName: 'deploy-studio-robot',\n title: 'Deploy Studios (all projects)',\n },\n]\n\nconst findOrgPermission = (key: string) =>\n ORG_PERMISSIONS.find((permission) => permission.key === key)\n\nconst isProjectGrant = (grant: Grant) => grant.key.startsWith(PROJECT_PREFIX)\n\nconst orgGrants = (grants: Grant[]) => grants.filter((grant) => !isProjectGrant(grant))\n\nexport function projectGrantKey(projectId: string): string {\n return `${PROJECT_PREFIX}${projectId}`\n}\n\nexport function parseGrant(value: string): {error: string} | {grant: Grant} {\n const [key = '', roleList, ...extra] = value.split('=')\n const roles = roleList?.split(',') ?? []\n if (extra.length > 0 || roles.includes('')) {\n return {\n error: `Invalid grant \"${value}\". Use <permission>[=<role>] or project:<projectId>[=<role>[,<role>]]`,\n }\n }\n const grant = {key, roles: roles.length > 0 ? roles : [DEFAULT_ROLE.name]}\n\n if (key.startsWith(PROJECT_PREFIX) && key.length > PROJECT_PREFIX.length) {\n return {grant}\n }\n\n const permission = findOrgPermission(key)\n if (!permission) {\n const keys = [...ORG_PERMISSIONS.map((p) => p.key), `${PROJECT_PREFIX}<projectId>`]\n return {error: `Unknown grant \"${key}\". Use one of: ${keys.join(', ')}`}\n }\n\n if ('roleName' in permission) {\n return roles.length > 0\n ? {\n error: `Grant \"${key}\" does not take a role. Pass it as --grant ${key}`,\n }\n : {grant: {key, roles: []}}\n }\n\n if (roles.length > 1) {\n return {\n error: `Grant \"${key}\" takes one role. Pass it as --grant ${key}=<role>`,\n }\n }\n\n const roleKeys = permission.roles.map((role) => role.key)\n if (roles[0] && !roleKeys.includes(roles[0])) {\n return {\n error: `Invalid role \"${roles[0]}\" for \"${key}\". Use one of: ${roleKeys.join(', ')}`,\n }\n }\n\n return {grant}\n}\n\nexport function formatGrant({key, roles}: Grant): string {\n return roles.length > 0 ? `${key}=${roles.join(',')}` : key\n}\n\nexport function findGrantConflict(grants: Grant[]): string | undefined {\n const roleByPermission = new Map<string, string | undefined>()\n for (const {key, roles} of orgGrants(grants)) {\n if (roleByPermission.has(key) && roleByPermission.get(key) !== roles[0]) {\n return `Grant \"${key}\" was given with different roles. Pass it once.`\n }\n roleByPermission.set(key, roles[0])\n }\n return undefined\n}\n\nfunction toOrganizationRoleNames(grants: Grant[]): string[] {\n const roleNames = orgGrants(grants).flatMap(({key, roles}) => {\n const permission = findOrgPermission(key)\n if (!permission) return []\n if ('roleName' in permission) return [permission.roleName]\n return permission.roles.filter((role) => roles.includes(role.key)).map((role) => role.roleName)\n })\n return [...new Set(roleNames)]\n}\n\nfunction toProjectMemberships(grants: Grant[]): Membership[] {\n const rolesByProject = new Map<string, Set<string>>()\n for (const grant of grants.filter((grant) => isProjectGrant(grant))) {\n const projectId = grant.key.slice(PROJECT_PREFIX.length)\n rolesByProject.set(\n projectId,\n new Set([...(rolesByProject.get(projectId) ?? []), ...grant.roles]),\n )\n }\n\n return [...rolesByProject].map(([resourceId, roleNames]) => ({\n resourceId,\n resourceType: 'project',\n roleNames: [...roleNames],\n }))\n}\n\nexport function getProjectTokenMembership(grants: Grant[]): Membership | undefined {\n const [membership, ...otherProjects] = toProjectMemberships(grants)\n return otherProjects.length === 0 && toOrganizationRoleNames(grants).length === 0\n ? membership\n : undefined\n}\n\nexport function toMemberships(grants: Grant[], organizationId: string): Membership[] {\n const roleNames = toOrganizationRoleNames(grants)\n const projectMemberships = toProjectMemberships(grants)\n return roleNames.length > 0\n ? [{resourceId: organizationId, resourceType: 'organization', roleNames}, ...projectMemberships]\n : projectMemberships\n}\n"],"names":["DEFAULT_ROLE","name","title","PROJECT_PREFIX","viewer","roleName","key","editor","ORG_PERMISSIONS","roles","findOrgPermission","find","permission","isProjectGrant","grant","startsWith","orgGrants","grants","filter","projectGrantKey","projectId","parseGrant","value","roleList","extra","split","length","includes","error","keys","map","p","join","roleKeys","role","formatGrant","findGrantConflict","roleByPermission","Map","has","get","set","undefined","toOrganizationRoleNames","roleNames","flatMap","Set","toProjectMemberships","rolesByProject","slice","resourceId","resourceType","getProjectTokenMembership","membership","otherProjects","toMemberships","organizationId","projectMemberships"],"mappings":"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"}