← Public packages
@kody/figma
Read Figma files, nodes, comments, components, styles, and images through OAuth or a token.
scripts/self-check.mjs
151 lines · 5.1 KB · JavaScriptimport 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')