@dimina-kit/devkit 0.1.2-dev.20260703051110 → 0.1.2-dev.20260703101348
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +9 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -7
- package/dist/open-project-watcher-error-callback.test.d.ts +2 -0
- package/dist/open-project-watcher-error-callback.test.d.ts.map +1 -0
- package/dist/open-project-watcher-error-callback.test.js +191 -0
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -41,6 +41,14 @@ export interface OpenProjectOptions {
|
|
|
41
41
|
* worker's piped stdout/stderr, tagged with their source stream.
|
|
42
42
|
*/
|
|
43
43
|
onLog?: (entry: CompileLogEntry) => void;
|
|
44
|
+
/**
|
|
45
|
+
* Fired when the file watcher emits `'error'` (EMFILE, permission loss, …)
|
|
46
|
+
* AFTER its initial scan already resolved `ready` — i.e. the session is
|
|
47
|
+
* live and auto-rebuild-on-save has silently stopped working. A pre-ready
|
|
48
|
+
* error instead rejects `openProject` itself (see `createProjectWatcher`),
|
|
49
|
+
* so this only ever fires once per session, at most.
|
|
50
|
+
*/
|
|
51
|
+
onWatcherError?: (err: unknown) => void;
|
|
44
52
|
}
|
|
45
53
|
export declare function openProject(opts: OpenProjectOptions): Promise<ProjectSession>;
|
|
46
54
|
/**
|
|
@@ -49,7 +57,7 @@ export declare function openProject(opts: OpenProjectOptions): Promise<ProjectSe
|
|
|
49
57
|
* watcher and whose `ready` resolves once the initial scan is complete (only
|
|
50
58
|
* changes made after that point are guaranteed to surface).
|
|
51
59
|
*/
|
|
52
|
-
export declare function createProjectWatcher(projectPath: string, onChange: () => void | Promise<void
|
|
60
|
+
export declare function createProjectWatcher(projectPath: string, onChange: () => void | Promise<void>, onWatcherError?: (err: unknown) => void): {
|
|
53
61
|
close: () => Promise<void>;
|
|
54
62
|
ready: Promise<void>;
|
|
55
63
|
};
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAgB,eAAe,EAAiB,MAAM,qBAAqB,CAAA;AAEvF,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAA;AAC/D,YAAY,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AACzD,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAyCzE,MAAM,WAAW,OAAO;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACZ;AAED,MAAM,WAAW,cAAc;IAC9B,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC1B;AAED,MAAM,WAAW,kBAAkB;IAClC,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;;;OAIG;IACH,SAAS,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAA;IAC5E,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,oFAAoF;IACpF,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IACtB,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC;;;;OAIG;IACH,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAgB,eAAe,EAAiB,MAAM,qBAAqB,CAAA;AAEvF,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAA;AAC/D,YAAY,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AACzD,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAyCzE,MAAM,WAAW,OAAO;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACZ;AAED,MAAM,WAAW,cAAc;IAC9B,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC1B;AAED,MAAM,WAAW,kBAAkB;IAClC,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;;;OAIG;IACH,SAAS,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAA;IAC5E,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,oFAAoF;IACpF,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IACtB,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC;;;;OAIG;IACH,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAA;IACxC;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAA;CACvC;AAuFD,wBAAsB,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,cAAc,CAAC,CAwInF;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CACnC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EACpC,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,GACrC;IAAE,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CA2DtD"}
|
package/dist/index.js
CHANGED
|
@@ -114,7 +114,7 @@ async function cleanupFailedOpen(watcher, compileWorker, server) {
|
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
116
|
export async function openProject(opts) {
|
|
117
|
-
const { projectPath: rawProjectPath, port = 0, sourcemap = false, fileTypes, simulatorDir, containerDir: overrideContainerDir, outputDir, watch = true, onRebuild, onBuildError, onLog, } = opts;
|
|
117
|
+
const { projectPath: rawProjectPath, port = 0, sourcemap = false, fileTypes, simulatorDir, containerDir: overrideContainerDir, outputDir, watch = true, onRebuild, onBuildError, onLog, onWatcherError, } = opts;
|
|
118
118
|
const projectPath = path.resolve(rawProjectPath);
|
|
119
119
|
const buildOptions = { sourcemap, fileTypes };
|
|
120
120
|
const resolvedPort = port === 0 ? await getRandomPort() : port;
|
|
@@ -194,7 +194,9 @@ export async function openProject(opts) {
|
|
|
194
194
|
// a build is in flight is never dropped: it coalesces into exactly one
|
|
195
195
|
// trailing rebuild once the current run settles.
|
|
196
196
|
const rebuildScheduler = createRebuildScheduler(() => runRebuild(compileWorker, buildRequest, sessionApps, () => reload, onRebuild, onBuildError));
|
|
197
|
-
watcher = watch
|
|
197
|
+
watcher = watch
|
|
198
|
+
? createProjectWatcher(projectPath, () => rebuildScheduler.schedule(), onWatcherError)
|
|
199
|
+
: null;
|
|
198
200
|
// Don't resolve until the watcher's initial scan is done: a save landing
|
|
199
201
|
// in the gap between `openProject` resolving and chokidar going live
|
|
200
202
|
// (fsevents stream not yet active on macOS) would otherwise be silently
|
|
@@ -232,7 +234,7 @@ export async function openProject(opts) {
|
|
|
232
234
|
* watcher and whose `ready` resolves once the initial scan is complete (only
|
|
233
235
|
* changes made after that point are guaranteed to surface).
|
|
234
236
|
*/
|
|
235
|
-
export function createProjectWatcher(projectPath, onChange) {
|
|
237
|
+
export function createProjectWatcher(projectPath, onChange, onWatcherError) {
|
|
236
238
|
// Ignore dotfiles/dot-directories that live *inside* the project (.git,
|
|
237
239
|
// .DS_Store, editor scratch, etc.) without nuking the whole watch when the
|
|
238
240
|
// project itself sits under a dotted ancestor path. A regex like
|
|
@@ -267,12 +269,24 @@ export function createProjectWatcher(projectPath, onChange) {
|
|
|
267
269
|
// A watcher 'error' before the initial scan completes (EMFILE, permission
|
|
268
270
|
// loss, …) must REJECT `ready`: resolving only on 'ready' would leave
|
|
269
271
|
// `await watcher.ready` — and the whole openProject — hung forever. The
|
|
270
|
-
// listener also doubles as the EventEmitter unhandled-'error' guard.
|
|
271
|
-
//
|
|
272
|
+
// listener also doubles as the EventEmitter unhandled-'error' guard. Once
|
|
273
|
+
// `ready` has settled, the reject above is a no-op — that's the live-session
|
|
274
|
+
// case (watcher died mid-session, not at open time) and is instead surfaced
|
|
275
|
+
// through `onWatcherError`, the only remaining signal that auto-rebuild has
|
|
276
|
+
// silently stopped.
|
|
277
|
+
let readySettled = false;
|
|
272
278
|
const ready = new Promise((resolve, reject) => {
|
|
273
|
-
watcher.once('ready', () =>
|
|
279
|
+
watcher.once('ready', () => {
|
|
280
|
+
readySettled = true;
|
|
281
|
+
resolve();
|
|
282
|
+
});
|
|
274
283
|
watcher.on('error', (err) => {
|
|
275
|
-
|
|
284
|
+
if (!readySettled) {
|
|
285
|
+
readySettled = true;
|
|
286
|
+
reject(err instanceof Error ? err : new Error(String(err)));
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
onWatcherError?.(err);
|
|
276
290
|
});
|
|
277
291
|
});
|
|
278
292
|
return {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-project-watcher-error-callback.test.d.ts","sourceRoot":"","sources":["../src/open-project-watcher-error-callback.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { PassThrough } from 'node:stream';
|
|
6
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
7
|
+
import * as devkit from './index.js';
|
|
8
|
+
/**
|
|
9
|
+
* Contract: `openProject` gains an `onWatcherError?: (err: unknown) => void`
|
|
10
|
+
* option. A watcher 'error' BEFORE the initial scan completes must keep
|
|
11
|
+
* rejecting `openProject` exactly as today (see open-project-cleanup.test.ts)
|
|
12
|
+
* — `onWatcherError` must NOT be called for that pre-ready path, so callers
|
|
13
|
+
* don't get a double signal for the same failure.
|
|
14
|
+
*
|
|
15
|
+
* A watcher 'error' AFTER 'ready' (EMFILE, permission loss mid-session, …) is
|
|
16
|
+
* TODAY silently dropped: `createProjectWatcher`'s `watcher.on('error', ...)`
|
|
17
|
+
* only rejects the (long-since-settled) `ready` promise, a no-op once ready
|
|
18
|
+
* has already resolved. The project keeps "running" with a dead watcher and
|
|
19
|
+
* nothing downstream ever finds out — a save after that point compiles
|
|
20
|
+
* nothing, forever, with no diagnostic. The fix: `openProject` must forward a
|
|
21
|
+
* post-ready watcher 'error' to `onWatcherError` so a caller (devtools'
|
|
22
|
+
* workspace-service) can surface "auto-rebuild stopped working" instead of
|
|
23
|
+
* silently going stale.
|
|
24
|
+
*
|
|
25
|
+
* Harness: verbatim copy of open-project-cleanup.test.ts's fake-fork +
|
|
26
|
+
* fake-watcher setup (fork/fe/chokidar all mocked so the failure point is
|
|
27
|
+
* injectable), plus a FakeWatcher that can fire 'error' AFTER 'ready'.
|
|
28
|
+
*/
|
|
29
|
+
const mocks = vi.hoisted(() => ({
|
|
30
|
+
fork: vi.fn(),
|
|
31
|
+
feStart: vi.fn(),
|
|
32
|
+
watch: vi.fn(),
|
|
33
|
+
}));
|
|
34
|
+
vi.mock('node:child_process', async (importOriginal) => {
|
|
35
|
+
const actual = await importOriginal();
|
|
36
|
+
return { ...actual, fork: mocks.fork, default: { ...actual, fork: mocks.fork } };
|
|
37
|
+
});
|
|
38
|
+
vi.mock('child_process', async (importOriginal) => {
|
|
39
|
+
const actual = await importOriginal();
|
|
40
|
+
return { ...actual, fork: mocks.fork, default: { ...actual, fork: mocks.fork } };
|
|
41
|
+
});
|
|
42
|
+
vi.mock('../fe/index.js', () => ({ start: mocks.feStart }));
|
|
43
|
+
vi.mock('chokidar', () => ({
|
|
44
|
+
default: { watch: mocks.watch },
|
|
45
|
+
watch: mocks.watch,
|
|
46
|
+
}));
|
|
47
|
+
class FakeChild extends EventEmitter {
|
|
48
|
+
stdout = new PassThrough();
|
|
49
|
+
stderr = new PassThrough();
|
|
50
|
+
connected = true;
|
|
51
|
+
pid = 4343;
|
|
52
|
+
send = vi.fn((msg) => {
|
|
53
|
+
const m = msg;
|
|
54
|
+
if (m && m.cmd === 'build') {
|
|
55
|
+
queueMicrotask(() => {
|
|
56
|
+
if (!this.connected)
|
|
57
|
+
return;
|
|
58
|
+
this.emit('message', {
|
|
59
|
+
type: 'result',
|
|
60
|
+
appInfo: { appId: 'watcher_err_app_001', name: 'watcher-err-app', path: String(m.projectPath ?? '') },
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return true;
|
|
65
|
+
});
|
|
66
|
+
kill = vi.fn(() => {
|
|
67
|
+
this.connected = false;
|
|
68
|
+
queueMicrotask(() => this.emit('exit', null, 'SIGTERM'));
|
|
69
|
+
return true;
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
class FakeWatcher extends EventEmitter {
|
|
73
|
+
close = vi.fn(async () => { });
|
|
74
|
+
}
|
|
75
|
+
function makeFakeFe() {
|
|
76
|
+
const server = {
|
|
77
|
+
close: vi.fn((cb) => {
|
|
78
|
+
cb?.();
|
|
79
|
+
return server;
|
|
80
|
+
}),
|
|
81
|
+
closeAllConnections: vi.fn(),
|
|
82
|
+
};
|
|
83
|
+
return { server, reload: vi.fn() };
|
|
84
|
+
}
|
|
85
|
+
const children = [];
|
|
86
|
+
const watchers = [];
|
|
87
|
+
const feInstances = [];
|
|
88
|
+
const cleanupRoots = [];
|
|
89
|
+
beforeEach(() => {
|
|
90
|
+
children.length = 0;
|
|
91
|
+
watchers.length = 0;
|
|
92
|
+
feInstances.length = 0;
|
|
93
|
+
mocks.fork.mockReset();
|
|
94
|
+
mocks.fork.mockImplementation(() => {
|
|
95
|
+
const child = new FakeChild();
|
|
96
|
+
children.push(child);
|
|
97
|
+
return child;
|
|
98
|
+
});
|
|
99
|
+
mocks.feStart.mockReset();
|
|
100
|
+
mocks.feStart.mockImplementation(async () => {
|
|
101
|
+
const fe = makeFakeFe();
|
|
102
|
+
feInstances.push(fe);
|
|
103
|
+
return fe;
|
|
104
|
+
});
|
|
105
|
+
mocks.watch.mockReset();
|
|
106
|
+
});
|
|
107
|
+
afterEach(() => {
|
|
108
|
+
for (const root of cleanupRoots.splice(0)) {
|
|
109
|
+
fs.rmSync(root, { recursive: true, force: true });
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
function makeFixture() {
|
|
113
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'devkit-watcher-err-'));
|
|
114
|
+
cleanupRoots.push(root);
|
|
115
|
+
fs.writeFileSync(path.join(root, 'project.config.json'), JSON.stringify({ appid: 'watcher_err_app_001', projectname: 'watcher-err-app' }));
|
|
116
|
+
return root;
|
|
117
|
+
}
|
|
118
|
+
function sleep(ms) {
|
|
119
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
120
|
+
}
|
|
121
|
+
describe('openProject onWatcherError — post-ready watcher errors are surfaced, pre-ready path is unchanged', () => {
|
|
122
|
+
it('does NOT call onWatcherError for a watcher error BEFORE ready (openProject still rejects, same as today)', async () => {
|
|
123
|
+
const root = makeFixture();
|
|
124
|
+
mocks.watch.mockImplementation(() => {
|
|
125
|
+
const watcher = new FakeWatcher();
|
|
126
|
+
watchers.push(watcher);
|
|
127
|
+
setTimeout(() => {
|
|
128
|
+
try {
|
|
129
|
+
watcher.emit('error', new Error('EMFILE: too many open files, watch'));
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
// no 'error' listener path — matches open-project-cleanup.test.ts
|
|
133
|
+
}
|
|
134
|
+
}, 10);
|
|
135
|
+
return watcher;
|
|
136
|
+
});
|
|
137
|
+
const onWatcherError = vi.fn();
|
|
138
|
+
await expect(devkit.openProject({
|
|
139
|
+
projectPath: root,
|
|
140
|
+
watch: true,
|
|
141
|
+
outputDir: path.join(root, '.out'),
|
|
142
|
+
onWatcherError,
|
|
143
|
+
})).rejects.toThrow();
|
|
144
|
+
expect(onWatcherError, 'a pre-ready watcher error must keep rejecting openProject WITHOUT also invoking onWatcherError — '
|
|
145
|
+
+ 'the caller already gets the failure via the rejected promise').not.toHaveBeenCalled();
|
|
146
|
+
}, 15_000);
|
|
147
|
+
it('calls onWatcherError with the error when the watcher fails AFTER ready — openProject has already resolved by then', async () => {
|
|
148
|
+
const root = makeFixture();
|
|
149
|
+
let capturedWatcher = null;
|
|
150
|
+
mocks.watch.mockImplementation(() => {
|
|
151
|
+
const watcher = new FakeWatcher();
|
|
152
|
+
watchers.push(watcher);
|
|
153
|
+
capturedWatcher = watcher;
|
|
154
|
+
queueMicrotask(() => watcher.emit('ready'));
|
|
155
|
+
return watcher;
|
|
156
|
+
});
|
|
157
|
+
const onWatcherError = vi.fn();
|
|
158
|
+
const session = await devkit.openProject({
|
|
159
|
+
projectPath: root,
|
|
160
|
+
watch: true,
|
|
161
|
+
outputDir: path.join(root, '.out'),
|
|
162
|
+
onWatcherError,
|
|
163
|
+
});
|
|
164
|
+
const postReadyError = new Error('EMFILE: too many open files, watch (post-ready)');
|
|
165
|
+
capturedWatcher.emit('error', postReadyError);
|
|
166
|
+
await sleep(20);
|
|
167
|
+
expect(onWatcherError, 'today nothing listens for a post-ready watcher error beyond the already-settled ready promise — '
|
|
168
|
+
+ 'the project silently stops auto-rebuilding forever with no signal').toHaveBeenCalledWith(postReadyError);
|
|
169
|
+
await session.close();
|
|
170
|
+
}, 15_000);
|
|
171
|
+
it('a post-ready watcher error does not crash the process (no unhandled "error" event) even without onWatcherError supplied', async () => {
|
|
172
|
+
const root = makeFixture();
|
|
173
|
+
let capturedWatcher = null;
|
|
174
|
+
mocks.watch.mockImplementation(() => {
|
|
175
|
+
const watcher = new FakeWatcher();
|
|
176
|
+
watchers.push(watcher);
|
|
177
|
+
capturedWatcher = watcher;
|
|
178
|
+
queueMicrotask(() => watcher.emit('ready'));
|
|
179
|
+
return watcher;
|
|
180
|
+
});
|
|
181
|
+
const session = await devkit.openProject({
|
|
182
|
+
projectPath: root,
|
|
183
|
+
watch: true,
|
|
184
|
+
outputDir: path.join(root, '.out'),
|
|
185
|
+
});
|
|
186
|
+
expect(() => {
|
|
187
|
+
capturedWatcher.emit('error', new Error('EMFILE (no onWatcherError supplied)'));
|
|
188
|
+
}).not.toThrow();
|
|
189
|
+
await session.close();
|
|
190
|
+
}, 15_000);
|
|
191
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dimina-kit/devkit",
|
|
3
|
-
"version": "0.1.2-dev.
|
|
3
|
+
"version": "0.1.2-dev.20260703101348",
|
|
4
4
|
"description": "Development toolkit for Dimina mini-apps with H5 container preview",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dimina",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"cors": "^2.8.6",
|
|
63
63
|
"express": "^5.2.1",
|
|
64
64
|
"open": "^11.0.0",
|
|
65
|
-
"@dimina-kit/compiler": "0.0.1-dev.
|
|
65
|
+
"@dimina-kit/compiler": "0.0.1-dev.20260703101348"
|
|
66
66
|
},
|
|
67
67
|
"publishConfig": {
|
|
68
68
|
"access": "public"
|