Skip to content

Commit 89ebfb6

Browse files
committed
Merge remote-tracking branch 'origin/main' into colep/sd-2222-bug-undoredo-on-a-tracked-change-not-bringing-back-the-tc
2 parents 085472b + 2d10f2a commit 89ebfb6

275 files changed

Lines changed: 15402 additions & 2395 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci-superdoc.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,6 @@ jobs:
7777
- name: Run slow tests
7878
run: pnpm test:slow
7979

80-
- name: Consumer typecheck (skipLibCheck off)
81-
run: bash packages/superdoc/tests/consumer-types/run.sh
82-
8380
- name: Install Playwright for UMD smoke test
8481
run: pnpm --filter @superdoc/umd-smoke-test exec playwright install --with-deps chromium
8582

.github/workflows/deploy-demos.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ jobs:
5050
run: pnpm --filter superdoc-esign-demo build
5151
env:
5252
VITE_BASE_PATH: /esign/
53+
VITE_API_BASE_URL: https://esign-demo-proxy-server-191591660773.us-central1.run.app
5354

5455
- name: Prepare combined publish directory
5556
run: |

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,5 @@ packages/sdk/langs/python/superdoc/generated/
103103
packages/sdk/tools/*.json
104104
# Note: apps/docs/document-api/reference/ stays committed because Mintlify
105105
# deploys directly from git with no pre-build hook support.
106+
107+
.playwright-cli/

apps/cli/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,11 @@
1010
"skill"
1111
],
1212
"scripts": {
13+
"predev": "node scripts/ensure-superdoc-build.js",
1314
"dev": "bun run src/index.ts",
15+
"prebuild": "node scripts/ensure-superdoc-build.js",
1416
"build": "bun build src/index.ts --outdir dist --target node --format esm",
17+
"prebuild:native": "node scripts/ensure-superdoc-build.js",
1518
"build:native": "bun build src/index.ts --compile --outfile dist/superdoc",
1619
"build:native:all": "node scripts/build-native-cli.js --all",
1720
"build:native:host": "node scripts/build-native-cli.js",
@@ -20,10 +23,12 @@
2023
"build:prepublish": "node scripts/build-and-stage.js",
2124
"publish:platforms": "node scripts/publish.js --tag latest",
2225
"publish:platforms:dry": "node scripts/publish.js --tag latest --dry-run",
26+
"pretest": "node scripts/ensure-superdoc-build.js",
2327
"test": "NODE_ENV=test bun test",
2428
"lint": "eslint .",
2529
"lint:fix": "eslint --fix .",
2630
"format": "prettier --write .",
31+
"pretypecheck": "node scripts/ensure-superdoc-build.js --types",
2732
"typecheck": "tsc --noEmit -p tsconfig.check.json",
2833
"prepublishOnly": "pnpm run build",
2934
"release": "pnpx semantic-release",

apps/cli/scripts/build-native-cli.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { existsSync, mkdirSync, readFileSync } from 'node:fs';
44
import path from 'node:path';
55
import { spawnSync } from 'node:child_process';
66
import { cliRoot, ensureNoUnknownFlags, getOptionalFlagValue, isDirectExecution, repoRoot } from './utils.js';
7+
import { ensureSuperdocBuild } from './ensure-superdoc-build.js';
78

89
const cliEntry = path.join(cliRoot, 'src/index.ts');
910
const cliPackagePath = path.join(cliRoot, 'package.json');
@@ -155,6 +156,7 @@ async function writeManifest(entries) {
155156
*/
156157
export async function main(argv = process.argv.slice(2)) {
157158
ensureNoUnknownFlags(argv, allowedFlags);
159+
ensureSuperdocBuild();
158160
const targets = resolveRequestedTargets(argv);
159161
const hostTarget = resolveHostTargetId();
160162

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import path from 'node:path';
2+
import { ensureNoUnknownFlags, isDirectExecution, repoRoot, runCommand } from './utils.js';
3+
4+
const allowedFlags = new Set(['--types']);
5+
const superdocRoot = path.join(repoRoot, 'packages/superdoc');
6+
7+
/**
8+
* Ensures the packaged `superdoc` runtime exists for CLI entrypoints that now
9+
* consume `superdoc/super-editor` instead of raw `@superdoc/super-editor/*` source.
10+
*
11+
* `--types` performs the full published build so package type exports exist.
12+
* Without it, a faster runtime-only build is sufficient for Bun execution.
13+
*
14+
* @param {{ includeTypes?: boolean }} [options]
15+
* @returns {void}
16+
*/
17+
export function ensureSuperdocBuild(options = {}) {
18+
const includeTypes = options.includeTypes === true;
19+
const scriptName = includeTypes ? 'build:es' : 'build:dev';
20+
const label = includeTypes ? 'Build packaged SuperDoc runtime and types' : 'Build packaged SuperDoc runtime';
21+
22+
runCommand('pnpm', ['--prefix', superdocRoot, 'run', scriptName], label);
23+
}
24+
25+
/**
26+
* CLI wrapper around {@link ensureSuperdocBuild}.
27+
*
28+
* @param {string[]} [argv=process.argv.slice(2)]
29+
* @returns {void}
30+
*/
31+
export function main(argv = process.argv.slice(2)) {
32+
ensureNoUnknownFlags(argv, allowedFlags);
33+
ensureSuperdocBuild({ includeTypes: argv.includes('--types') });
34+
}
35+
36+
if (isDirectExecution(import.meta.url)) {
37+
try {
38+
main();
39+
} catch (error) {
40+
console.error(error instanceof Error ? error.message : error);
41+
process.exitCode = 1;
42+
}
43+
}

apps/cli/src/__tests__/cli.test.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { access, copyFile, mkdir, readFile, rm, writeFile } from 'node:fs/promis
33
import { join } from 'node:path';
44
import { run } from '../index';
55
import { resolveListDocFixture, resolveSourceDocFixture } from './fixtures';
6+
import { writeListDocWithoutParaIds } from './unstable-list-fixture';
67

78
type RunResult = {
89
code: number;
@@ -1218,6 +1219,55 @@ describe('superdoc CLI', () => {
12181219
expect(getEnvelope.data.item.address.nodeId).toBe(address.nodeId);
12191220
});
12201221

1222+
test('lists list/get keep list item addresses stable for docs without paraIds in stateless mode', async () => {
1223+
const source = join(TEST_DIR, 'lists-no-paraids-stateless.docx');
1224+
await writeListDocWithoutParaIds(source);
1225+
1226+
const address = await firstListItemAddress(['lists', 'list', source, '--limit', '1']);
1227+
1228+
const getResult = await runCli(['lists', 'get', source, '--address-json', JSON.stringify(address)]);
1229+
expect(getResult.code).toBe(0);
1230+
1231+
const getEnvelope = parseJsonOutput<
1232+
SuccessEnvelope<{
1233+
address: ListItemAddress;
1234+
item: { address: ListItemAddress };
1235+
}>
1236+
>(getResult);
1237+
expect(getEnvelope.data.item.address.nodeId).toBe(address.nodeId);
1238+
1239+
const secondAddress = await firstListItemAddress(['lists', 'list', source, '--limit', '1']);
1240+
expect(secondAddress.nodeId).toBe(address.nodeId);
1241+
});
1242+
1243+
test('lists list/get keep list item addresses stable for docs without paraIds in stateful mode', async () => {
1244+
const source = join(TEST_DIR, 'lists-no-paraids-stateful.docx');
1245+
await writeListDocWithoutParaIds(source);
1246+
1247+
try {
1248+
const openResult = await runCli(['open', source]);
1249+
expect(openResult.code).toBe(0);
1250+
1251+
const address = await firstListItemAddress(['lists', 'list', '--limit', '1']);
1252+
1253+
const getResult = await runCli(['lists', 'get', '--address-json', JSON.stringify(address)]);
1254+
expect(getResult.code).toBe(0);
1255+
1256+
const getEnvelope = parseJsonOutput<
1257+
SuccessEnvelope<{
1258+
address: ListItemAddress;
1259+
item: { address: ListItemAddress };
1260+
}>
1261+
>(getResult);
1262+
expect(getEnvelope.data.item.address.nodeId).toBe(address.nodeId);
1263+
1264+
const secondAddress = await firstListItemAddress(['lists', 'list', '--limit', '1']);
1265+
expect(secondAddress.nodeId).toBe(address.nodeId);
1266+
} finally {
1267+
await runCli(['close', '--discard']);
1268+
}
1269+
});
1270+
12211271
test('lists list pretty prints list rows', async () => {
12221272
const result = await runCli(['lists', 'list', LIST_SAMPLE_DOC, '--limit', '2', '--output', 'pretty']);
12231273
expect(result.code).toBe(0);

apps/cli/src/__tests__/conformance/scenarios.ts

Lines changed: 8 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -590,31 +590,6 @@ function cellMutationScenario(
590590
};
591591
}
592592

593-
/** Table-scoped mutation in a session: uses --table-node-id instead of --node-id. */
594-
function tableScopedMutationScenario(
595-
op: string,
596-
extraArgs: string[],
597-
): (harness: ConformanceHarness) => Promise<ScenarioInvocation> {
598-
return async (harness) => {
599-
const label = `table-${op.replace(/\./g, '-')}`;
600-
const stateDir = await harness.createStateDir(`${label}-success`);
601-
const { tableNodeId, sessionId } = await harness.createTableFixture(stateDir, label);
602-
return {
603-
stateDir,
604-
args: [
605-
...commandTokens(`doc.${op}` as CliOperationId),
606-
'--session',
607-
sessionId,
608-
'--table-node-id',
609-
tableNodeId,
610-
...extraArgs,
611-
'--out',
612-
harness.createOutputPath(`${label}-out`),
613-
],
614-
};
615-
};
616-
}
617-
618593
function tocMutationScenario(
619594
op: string,
620595
extraArgs: string[],
@@ -2983,9 +2958,9 @@ export const SUCCESS_SCENARIOS = {
29832958
'doc.tables.split': tableMutationScenario('tables.split', ['--at-row-index', '1']),
29842959
'doc.tables.convertToText': tableMutationScenario('tables.convertToText', ['--delimiter', 'tab']),
29852960
'doc.tables.setLayout': tableMutationScenario('tables.setLayout', ['--alignment', 'center']),
2986-
'doc.tables.insertRow': tableScopedMutationScenario('tables.insertRow', ['--row-index', '0', '--position', 'below']),
2987-
'doc.tables.deleteRow': tableScopedMutationScenario('tables.deleteRow', ['--row-index', '0']),
2988-
'doc.tables.setRowHeight': tableScopedMutationScenario('tables.setRowHeight', [
2961+
'doc.tables.insertRow': tableMutationScenario('tables.insertRow', ['--row-index', '0', '--position', 'below']),
2962+
'doc.tables.deleteRow': tableMutationScenario('tables.deleteRow', ['--row-index', '0']),
2963+
'doc.tables.setRowHeight': tableMutationScenario('tables.setRowHeight', [
29892964
'--row-index',
29902965
'0',
29912966
'--height-pt',
@@ -2994,19 +2969,19 @@ export const SUCCESS_SCENARIOS = {
29942969
'atLeast',
29952970
]),
29962971
'doc.tables.distributeRows': tableMutationScenario('tables.distributeRows', []),
2997-
'doc.tables.setRowOptions': tableScopedMutationScenario('tables.setRowOptions', [
2972+
'doc.tables.setRowOptions': tableMutationScenario('tables.setRowOptions', [
29982973
'--row-index',
29992974
'0',
30002975
'--allow-break-across-pages',
30012976
]),
3002-
'doc.tables.insertColumn': tableScopedMutationScenario('tables.insertColumn', [
2977+
'doc.tables.insertColumn': tableMutationScenario('tables.insertColumn', [
30032978
'--column-index',
30042979
'0',
30052980
'--position',
30062981
'right',
30072982
]),
3008-
'doc.tables.deleteColumn': tableScopedMutationScenario('tables.deleteColumn', ['--column-index', '0']),
3009-
'doc.tables.setColumnWidth': tableScopedMutationScenario('tables.setColumnWidth', [
2983+
'doc.tables.deleteColumn': tableMutationScenario('tables.deleteColumn', ['--column-index', '0']),
2984+
'doc.tables.setColumnWidth': tableMutationScenario('tables.setColumnWidth', [
30102985
'--column-index',
30112986
'0',
30122987
'--width-pt',
@@ -3015,7 +2990,7 @@ export const SUCCESS_SCENARIOS = {
30152990
'doc.tables.distributeColumns': tableMutationScenario('tables.distributeColumns', []),
30162991
'doc.tables.insertCell': cellMutationScenario('tables.insertCell', ['--mode', 'shiftRight']),
30172992
'doc.tables.deleteCell': cellMutationScenario('tables.deleteCell', ['--mode', 'shiftLeft']),
3018-
'doc.tables.mergeCells': tableScopedMutationScenario('tables.mergeCells', [
2993+
'doc.tables.mergeCells': tableMutationScenario('tables.mergeCells', [
30192994
'--start-json',
30202995
JSON.stringify({ rowIndex: 0, columnIndex: 0 }),
30212996
'--end-json',

0 commit comments

Comments
 (0)