Skip to content

Commit 4d23cde

Browse files
umair-ablyclaude
andcommitted
DX-1205: throw on legacy v1 ably/promises and ably/callbacks imports
Add subpath exports for the two v1 entry points (callbacks.js and promises.js at the package root, both removed in mid-2023 during v2 prep) so that code written against v1 — or generated by an LLM trained on v1 docs — fails on import with an actionable migration message instead of Node's generic ERR_PACKAGE_PATH_NOT_EXPORTED. The .js shims throw at module load; the .d.ts siblings keep `@arethetypeswrong/cli` happy across node10/node16/bundler resolution modes, carry an `@deprecated` tag for IDE hovers, and resolve to `never` so any property access errors at compile time. URL points at the in-repo migration guide, matching the convention from DX-1204 (src/common/lib/util/utils.ts:293). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 90a42de commit 4d23cde

6 files changed

Lines changed: 98 additions & 0 deletions

File tree

callbacks.d.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/**
2+
* @deprecated `'ably/callbacks'` was the v1 callback API entry point and has been removed in ably-js v2.
3+
* v2 is promise-only — import from `'ably'` directly and switch to `await` / `.then()`.
4+
*
5+
* Importing this subpath throws at module load with the migration link.
6+
*
7+
* @see https://github.com/ably/ably-js/blob/main/docs/migration-guides/v2/lib.md
8+
*/
9+
declare const ablyCallbacksV1EntryPointRemoved: never;
10+
export = ablyCallbacksV1EntryPointRemoved;

callbacks.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
'use strict';
2+
3+
throw new Error(
4+
"'ably/callbacks' was the v1 callback API entry point and is no longer available. ably-js v2 is promise-only — import from 'ably' directly and switch to await / .then(). See https://github.com/ably/ably-js/blob/main/docs/migration-guides/v2/lib.md",
5+
);

package.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,26 @@
3939
"types": "./liveobjects.d.ts",
4040
"default": "./build/liveobjects.js"
4141
}
42+
},
43+
"./promises": {
44+
"types": "./promises.d.ts",
45+
"default": "./promises.js"
46+
},
47+
"./callbacks": {
48+
"types": "./callbacks.d.ts",
49+
"default": "./callbacks.js"
4250
}
4351
},
4452
"files": [
4553
"build/**",
4654
"ably.d.ts",
55+
"callbacks.d.ts",
56+
"callbacks.js",
4757
"liveobjects.d.ts",
4858
"liveobjects.d.mts",
4959
"modular.d.ts",
60+
"promises.d.ts",
61+
"promises.js",
5062
"push.d.ts",
5163
"resources/**",
5264
"src/**",

promises.d.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/**
2+
* @deprecated `'ably/promises'` was the v1 entry point and is no longer available in ably-js v2.
3+
* v2 is promise-only — import from `'ably'` directly.
4+
*
5+
* Importing this subpath throws at module load with the migration link.
6+
*
7+
* @see https://github.com/ably/ably-js/blob/main/docs/migration-guides/v2/lib.md
8+
*/
9+
declare const ablyPromisesV1EntryPointRemoved: never;
10+
export = ablyPromisesV1EntryPointRemoved;

promises.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
'use strict';
2+
3+
throw new Error(
4+
"'ably/promises' was the v1 entry point. ably-js v2 is promise-only — import from 'ably' directly. See https://github.com/ably/ably-js/blob/main/docs/migration-guides/v2/lib.md",
5+
);
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
'use strict';
2+
3+
define(['chai'], function (chai) {
4+
const { expect } = chai;
5+
const fs = require('fs');
6+
const path = require('path');
7+
const repoRoot = path.resolve(__dirname, '..', '..');
8+
9+
describe('legacy v1 import-path shims', function () {
10+
function loadShim(relPath) {
11+
const abs = path.join(repoRoot, relPath);
12+
delete require.cache[abs];
13+
require(abs);
14+
}
15+
16+
it("'ably/promises' shim throws naming the v1 entry point and migration guide", function () {
17+
expect(() => loadShim('promises.js'))
18+
.to.throw(Error)
19+
.with.property('message')
20+
.that.matches(/'ably\/promises' was the v1 entry point/)
21+
.and.matches(/migration-guides\/v2\/lib\.md/);
22+
});
23+
24+
it("'ably/callbacks' shim throws naming the v1 callback API and migration guide", function () {
25+
expect(() => loadShim('callbacks.js'))
26+
.to.throw(Error)
27+
.with.property('message')
28+
.that.matches(/'ably\/callbacks' was the v1 callback API entry point/)
29+
.and.matches(/migration-guides\/v2\/lib\.md/);
30+
});
31+
32+
it('package.json exports map wires the legacy subpaths to the shim files and their types', function () {
33+
const pkg = JSON.parse(fs.readFileSync(path.join(repoRoot, 'package.json'), 'utf8'));
34+
35+
expect(pkg.exports['./promises'], "exports['./promises']").to.deep.equal({
36+
types: './promises.d.ts',
37+
default: './promises.js',
38+
});
39+
expect(pkg.exports['./callbacks'], "exports['./callbacks']").to.deep.equal({
40+
types: './callbacks.d.ts',
41+
default: './callbacks.js',
42+
});
43+
44+
for (const file of ['promises.js', 'promises.d.ts', 'callbacks.js', 'callbacks.d.ts']) {
45+
expect(fs.existsSync(path.join(repoRoot, file)), file).to.equal(true);
46+
}
47+
});
48+
49+
it("'files' array ships the legacy shim files in the published package", function () {
50+
const pkg = JSON.parse(fs.readFileSync(path.join(repoRoot, 'package.json'), 'utf8'));
51+
for (const file of ['promises.js', 'promises.d.ts', 'callbacks.js', 'callbacks.d.ts']) {
52+
expect(pkg.files, `files[] should include ${file}`).to.include(file);
53+
}
54+
});
55+
});
56+
});

0 commit comments

Comments
 (0)