import assert from 'node:assert/strict' import { readFileSync } from 'node:fs' import { DEFAULT_OAUTH_SCOPES, FIGMA_AUTHORIZE_URL, FIGMA_REQUIRED_HOST, FIGMA_SCOPES, FIGMA_TOKEN_URL, inferOperationFromPath, normalizeNodeId, oauthConnectUrl, parseFileKey, patSetupUrl, scopeForOperation, } from '../src/setup.ts' import { mapComment, mapComponentList, mapFile, mapImageMap } from '../src/models.ts' import { resolveIntegrationName, resolveSecretName } from '../src/auth-names.ts' assert.equal(parseFileKey('AbC123xyz'), 'AbC123xyz') assert.equal( parseFileKey('https://www.figma.com/design/AbC123xyz/Demo?node-id=1-2'), 'AbC123xyz', ) assert.equal(parseFileKey('https://figma.com/file/Key99/Name'), 'Key99') assert.equal(normalizeNodeId('12-34'), '12:34') assert.equal(normalizeNodeId('12:34'), '12:34') assert.equal(scopeForOperation('comments.write'), 'file_comments:write') assert.equal(inferOperationFromPath('POST', '/v1/files/abc/comments'), 'comments.write') assert.equal(inferOperationFromPath('GET', '/v1/files/abc/nodes'), 'files.read') assert.equal(inferOperationFromPath('GET', '/v1/files/abc/meta'), 'files.meta') assert.equal(inferOperationFromPath('GET', '/v1/files/abc/components'), 'library.read') assert.equal(inferOperationFromPath('GET', '/v1/images/abc'), 'files.read') assert.equal(inferOperationFromPath('GET', '/v1/me'), 'users.read') assert.equal(resolveIntegrationName({}), 'figma') assert.equal(resolveIntegrationName({ account: 'work' }), 'figma-work') assert.equal(resolveIntegrationName({ account: 'figma-work' }), 'figma-work') assert.equal(resolveIntegrationName({ integrationName: 'figma-brand' }), 'figma-brand') assert.equal(resolveSecretName({}), 'figmaPat') assert.equal(resolveSecretName({ account: 'work' }), 'figmaPat-work') assert.equal(resolveSecretName({ secretName: 'figmaPlanToken' }), 'figmaPlanToken') const connectUrl = oauthConnectUrl('figma') assert.match(connectUrl, /^https:\/\/kody\.codes\/connect\/oauth\?/) assert.ok(connectUrl.includes(encodeURIComponent(FIGMA_AUTHORIZE_URL))) assert.ok(connectUrl.includes(encodeURIComponent(FIGMA_TOKEN_URL))) assert.ok(connectUrl.includes('file_content%3Aread')) assert.ok(connectUrl.includes(FIGMA_REQUIRED_HOST)) assert.ok(DEFAULT_OAUTH_SCOPES.includes('file_comments:write')) const acceptedScopes = [ 'current_user:read', 'file_content:read', 'file_metadata:read', 'file_comments:read', 'file_comments:write', 'file_versions:read', 'library_content:read', 'library_assets:read', 'folders:read', ] assert.deepEqual([...DEFAULT_OAUTH_SCOPES], acceptedScopes) assert.deepEqual(Object.keys(FIGMA_SCOPES), acceptedScopes) assert.equal( new URL(connectUrl).searchParams.get('scopes'), acceptedScopes.join(' '), ) const readme = readFileSync(new URL('../README.md', import.meta.url), 'utf8') const agents = readFileSync(new URL('../AGENTS.md', import.meta.url), 'utf8') const setupSource = readFileSync(new URL('../src/setup.ts', import.meta.url), 'utf8') const readmeConnectUrl = readme.match( /https:\/\/kody\.codes\/connect\/oauth\?\S+/, )?.[0] assert.ok(readmeConnectUrl) assert.equal( new URL(readmeConnectUrl).searchParams.get('scopes'), acceptedScopes.join(' '), ) const advertised = `${readme}\n${agents}\n${setupSource}` const rejectedScopes = [ 'projects:read', 'project_metadata:read', 'files:read', 'library_analytics:read', 'file_variables:read', 'file_variables:write', 'org:activity_log_read', 'org:ai_metering_usage_read', 'org:developer_log_read', 'org:discovery_read', ] for (const scope of rejectedScopes) { assert.equal( advertised.includes(scope), false, `advertised rejected Figma scope ${scope}`, ) } for (const scope of acceptedScopes) { assert.equal(readme.includes(scope), true) assert.equal(agents.includes(scope), true) } const patUrl = patSetupUrl('figmaPat') assert.match(patUrl, /^https:\/\/kody\.codes\/account\/secrets\/new\?/) assert.ok(patUrl.includes('name=figmaPat')) assert.ok(patUrl.includes('api.figma.com')) const file = mapFile('abc', { name: 'Checkout', lastModified: '2026-01-01T00:00:00Z', version: '1', document: { id: '0:0', name: 'Document', type: 'DOCUMENT', children: [{ id: '0:1', name: 'Page 1', type: 'CANVAS' }], }, components: { a: {}, b: {} }, styles: { c: {} }, }) assert.equal(file.fileKey, 'abc') assert.equal(file.name, 'Checkout') assert.equal(file.componentCount, 2) assert.equal(file.styleCount, 1) assert.equal(file.document?.children[0]?.name, 'Page 1') const comment = mapComment('abc', { id: 'c1', message: 'Hello', user: { id: 'u1', handle: 'ada', email: 'hidden@example.com' }, reactions: [{ emoji: ':eyes:' }, { emoji: ':eyes:' }], }) assert.equal(comment.user?.handle, 'ada') assert.equal('email' in (comment.user ?? {}), false) assert.deepEqual(comment.reactions, [{ emoji: ':eyes:', count: 2 }]) const components = mapComponentList({ meta: { components: { '12:34': { key: 'comp1', name: 'Button', file_key: 'abc', node_id: '12:34' }, }, }, }) assert.equal(components[0]?.name, 'Button') const images = mapImageMap('abc', { images: { '12:34': 'https://example.com/a.png' }, err: null }) assert.equal(images.images[0]?.url, 'https://example.com/a.png') console.log('self-check ok')