Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/update-proto.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
- name: Check for changes
id: diff
run: |
if git diff --quiet keeperapi/src/proto.js keeperapi/src/proto.d.ts; then
if git diff --quiet keeperapi/src/proto.js keeperapi/src/proto.d.ts keeperapi/src/proto; then
echo "changed=false" >> $GITHUB_OUTPUT
else
echo "changed=true" >> $GITHUB_OUTPUT
Expand All @@ -54,7 +54,7 @@ jobs:
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git checkout -b "bot/update-proto"
git add keeperapi/src/proto.js keeperapi/src/proto.d.ts
git add keeperapi/src/proto.js keeperapi/src/proto.d.ts keeperapi/src/proto
git commit -m "chore: regenerate protobuf files"
git push --force origin "bot/update-proto"

Expand Down
1 change: 1 addition & 0 deletions keeperapi/.prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ package-lock.json
dist/
proto.js
proto.d.ts
src/proto/
4 changes: 2 additions & 2 deletions keeperapi/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions keeperapi/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@keeper-security/keeperapi",
"description": "Keeper API Javascript SDK",
"version": "18.0.1",
"version": "18.0.2",
"browser": "dist/browser/index.js",
"main": "dist/index.cjs.js",
"types": "dist/node/index.d.ts",
Expand All @@ -16,8 +16,7 @@
"scripts": {
"start": "rollup -cw",
"build": "node ./scripts/cleanDistFolder.js && rollup -c && cp src/proto.d.ts dist",
"update-proto:es6": "pbjs -t static-module --force-number -w es6 -o src/proto.js ../../keeperapp-protobuf/APIRequest.proto ../../keeperapp-protobuf/AccountSummary.proto ../../keeperapp-protobuf/automator.proto ../../keeperapp-protobuf/breachwatch.proto ../../keeperapp-protobuf/client.proto ../../keeperapp-protobuf/externalservice.proto ../../keeperapp-protobuf/folder.proto ../../keeperapp-protobuf/push.proto ../../keeperapp-protobuf/record.proto ../../keeperapp-protobuf/servicelogger.proto ../../keeperapp-protobuf/ssocloud.proto ../../keeperapp-protobuf/token.proto ../../keeperapp-protobuf/upsell.proto ../../keeperapp-protobuf/SyncDown.proto ../../keeperapp-protobuf/BI.proto ../../keeperapp-protobuf/router.proto ../../keeperapp-protobuf/record_endpoints.proto ../../keeperapp-protobuf/remove.proto && pbts -o src/proto.d.ts src/proto.js",
"update-proto:cjs": "pbjs -t json-module -w commonjs -o src/proto.js ../../keeperapp-protobuf/APIRequest.proto ../../keeperapp-protobuf/AccountSummary.proto ../../keeperapp-protobuf/automator.proto ../../keeperapp-protobuf/breachwatch.proto ../../keeperapp-protobuf/client.proto ../../keeperapp-protobuf/externalservice.proto ../../keeperapp-protobuf/folder.proto ../../keeperapp-protobuf/push.proto ../../keeperapp-protobuf/record.proto ../../keeperapp-protobuf/servicelogger.proto ../../keeperapp-protobuf/ssocloud.proto ../../keeperapp-protobuf/token.proto ../../keeperapp-protobuf/upsell.proto ../../keeperapp-protobuf/SyncDown.proto ../../keeperapp-protobuf/BI.proto ../../keeperapp-protobuf/router.proto ../../keeperapp-protobuf/record_endpoints.proto ../../keeperapp-protobuf/remove.proto && pbjs -t static-module -w commonjs ../../keeperapp-protobuf/APIRequest.proto ../../keeperapp-protobuf/AccountSummary.proto ../../keeperapp-protobuf/automator.proto ../../keeperapp-protobuf/breachwatch.proto ../../keeperapp-protobuf/client.proto ../../keeperapp-protobuf/externalservice.proto ../../keeperapp-protobuf/folder.proto ../../keeperapp-protobuf/push.proto ../../keeperapp-protobuf/record.proto ../../keeperapp-protobuf/servicelogger.proto ../../keeperapp-protobuf/ssocloud.proto ../../keeperapp-protobuf/token.proto ../../keeperapp-protobuf/upsell.proto ../../keeperapp-protobuf/SyncDown.proto ../../keeperapp-protobuf/BI.proto ../../keeperapp-protobuf/router.proto ../../keeperapp-protobuf/record_endpoints.proto ../../keeperapp-protobuf/remove.proto | pbts -o src/proto.d.ts -",
"update-proto:es6": "node scripts/generate-proto.mjs",
"format": "prettier --write .",
"format:check": "prettier --check .",
"test": "jest",
Expand Down
121 changes: 121 additions & 0 deletions keeperapi/scripts/generate-proto.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import * as pbjs from 'protobufjs-cli/pbjs.js'
import * as pbts from 'protobufjs-cli/pbts.js'
import { writeFileSync, mkdirSync, rmSync, readdirSync, existsSync } from 'node:fs'
import { join, dirname } from 'node:path'
import { fileURLToPath } from 'node:url'

const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..')
const PROTO_DIR = join(ROOT, '../../keeperapp-protobuf')

const PROTO_FILES = [
'APIRequest.proto',
'AccountSummary.proto',
'automator.proto',
'breachwatch.proto',
'client.proto',
'externalservice.proto',
'folder.proto',
'push.proto',
'record.proto',
'servicelogger.proto',
'ssocloud.proto',
'token.proto',
'upsell.proto',
'SyncDown.proto',
'BI.proto',
'router.proto',
'record_endpoints.proto',
'remove.proto',
]

// Explicit filename overrides. 'folder' (lowercase) collides with 'Folder' on case-insensitive
// filesystems — renamed to Remove.js since its content is entirely folder.v3.remove.
const FILENAME_OVERRIDES = {
folder: 'Remove',
}

const run = (tool, args) =>
new Promise((resolve, reject) => tool.main(args, (err, output) => (err ? reject(err) : resolve(output))))

async function main() {
if (!existsSync(PROTO_DIR)) {
console.error(`keeperapp-protobuf not found at ${PROTO_DIR}`)
console.error('Clone it alongside keeper-sdk-javascript before running this script.')
process.exit(1)
}

// --- pbjs -----------------------------------------------------------------

console.log('Running pbjs...')
const combined = await run(pbjs, [
'--target',
'static-module',
'--force-number',
'--no-verify',
'--no-delimited',
'--wrap',
'es6',
'--path',
PROTO_DIR,
...PROTO_FILES,
])

// --- pbts -----------------------------------------------------------------

console.log('Running pbts...')
const tmpFile = join(ROOT, 'src/_proto_tmp.js')
writeFileSync(tmpFile, combined)
const declarations = await run(pbts, [tmpFile])
rmSync(tmpFile)
writeFileSync(join(ROOT, 'src/proto.d.ts'), declarations)
console.log('Generated src/proto.d.ts')

// --- Split combined output into per-namespace files -----------------------

const lines = combined.split('\n')
const ESLINT_HEADER = lines[0]
const NAMESPACE_RE = /^export const (\w+) = \$root\.\w+ = \(\(\) => \{/

const splits = []
for (let i = 0; i < lines.length; i++) {
const m = lines[i].match(NAMESPACE_RE)
if (m) splits.push({ name: m[1], startLine: i })
}

if (splits.length === 0) throw new Error('No namespaces found — pbjs output format may have changed')

const protoDir = join(ROOT, 'src/proto')
mkdirSync(protoDir, { recursive: true })
for (const f of readdirSync(protoDir)) {
if (f !== 'root.js' && f !== 'index.js') rmSync(join(protoDir, f))
}

// One file per namespace
for (let i = 0; i < splits.length; i++) {
const { name, startLine } = splits[i]
const endLine = i + 1 < splits.length ? splits[i + 1].startLine : lines.length
const body = lines.slice(startLine, endLine).join('\n')
const filename = FILENAME_OVERRIDES[name] ?? name

writeFileSync(
join(protoDir, `${filename}.js`),
[ESLINT_HEADER, `import { $protobuf, $Reader, $Writer, $util, $root } from './root.js';`, '', body].join(
'\n'
)
)
}

// index.js — re-exports all namespaces in pbjs output order (= dependency order)
writeFileSync(
join(protoDir, 'index.js'),
splits.map(({ name }) => `export { ${name} } from './${FILENAME_OVERRIDES[name] ?? name}.js';`).join('\n') +
'\n'
)

console.log(`Split into ${splits.length} namespace files: ${splits.map((s) => s.name).join(', ')}`)
}

main().catch((err) => {
console.error(err)
process.exit(1)
})
Loading
Loading