openxiangda-cli 2.0.0-alpha.99 → 2.0.1

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.
Files changed (124) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +4 -8
  3. package/bin/run.js +2 -12
  4. package/dist/base.d.ts +30 -6
  5. package/dist/base.d.ts.map +1 -1
  6. package/dist/base.js +119 -22
  7. package/dist/base.js.map +1 -1
  8. package/dist/commands/accept.d.ts +8 -3
  9. package/dist/commands/accept.d.ts.map +1 -1
  10. package/dist/commands/admin.d.ts +32 -0
  11. package/dist/commands/admin.d.ts.map +1 -0
  12. package/dist/commands/admin.js +27 -0
  13. package/dist/commands/admin.js.map +1 -0
  14. package/dist/commands/auth.d.ts +30 -0
  15. package/dist/commands/auth.d.ts.map +1 -0
  16. package/dist/commands/auth.js +13 -0
  17. package/dist/commands/auth.js.map +1 -0
  18. package/dist/commands/cancel.d.ts +30 -0
  19. package/dist/commands/cancel.d.ts.map +1 -0
  20. package/dist/commands/cancel.js +12 -0
  21. package/dist/commands/cancel.js.map +1 -0
  22. package/dist/commands/check.d.ts +12 -3
  23. package/dist/commands/check.d.ts.map +1 -1
  24. package/dist/commands/check.js +21 -4
  25. package/dist/commands/check.js.map +1 -1
  26. package/dist/commands/context.d.ts +27 -0
  27. package/dist/commands/context.d.ts.map +1 -0
  28. package/dist/commands/context.js +10 -0
  29. package/dist/commands/context.js.map +1 -0
  30. package/dist/commands/create.d.ts +20 -3
  31. package/dist/commands/create.d.ts.map +1 -1
  32. package/dist/commands/create.js +396 -22
  33. package/dist/commands/create.js.map +1 -1
  34. package/dist/commands/deploy.d.ts +13 -3
  35. package/dist/commands/deploy.d.ts.map +1 -1
  36. package/dist/commands/deploy.js +17 -16
  37. package/dist/commands/deploy.js.map +1 -1
  38. package/dist/commands/dev.d.ts +10 -3
  39. package/dist/commands/dev.d.ts.map +1 -1
  40. package/dist/commands/dev.js +7 -4
  41. package/dist/commands/dev.js.map +1 -1
  42. package/dist/commands/docs.d.ts +30 -0
  43. package/dist/commands/docs.d.ts.map +1 -0
  44. package/dist/commands/docs.js +20 -0
  45. package/dist/commands/docs.js.map +1 -0
  46. package/dist/commands/login.d.ts +8 -3
  47. package/dist/commands/login.d.ts.map +1 -1
  48. package/dist/commands/login.js +1 -1
  49. package/dist/commands/login.js.map +1 -1
  50. package/dist/commands/logs.d.ts +10 -3
  51. package/dist/commands/logs.d.ts.map +1 -1
  52. package/dist/commands/logs.js +7 -3
  53. package/dist/commands/logs.js.map +1 -1
  54. package/dist/commands/retry.d.ts +30 -0
  55. package/dist/commands/retry.d.ts.map +1 -0
  56. package/dist/commands/retry.js +12 -0
  57. package/dist/commands/retry.js.map +1 -0
  58. package/dist/commands/rollback.d.ts +11 -3
  59. package/dist/commands/rollback.d.ts.map +1 -1
  60. package/dist/commands/rollback.js +9 -3
  61. package/dist/commands/rollback.js.map +1 -1
  62. package/dist/commands/skill.d.ts +9 -3
  63. package/dist/commands/skill.d.ts.map +1 -1
  64. package/dist/commands/skill.js +9 -2
  65. package/dist/commands/skill.js.map +1 -1
  66. package/dist/commands/spec.d.ts +42 -0
  67. package/dist/commands/spec.d.ts.map +1 -0
  68. package/dist/commands/spec.js +123 -0
  69. package/dist/commands/spec.js.map +1 -0
  70. package/dist/commands/start.d.ts +28 -0
  71. package/dist/commands/start.d.ts.map +1 -0
  72. package/dist/commands/start.js +18 -0
  73. package/dist/commands/start.js.map +1 -0
  74. package/dist/commands/status.d.ts +9 -3
  75. package/dist/commands/status.d.ts.map +1 -1
  76. package/dist/commands/status.js +10 -3
  77. package/dist/commands/status.js.map +1 -1
  78. package/dist/commands/stop.d.ts +28 -0
  79. package/dist/commands/stop.d.ts.map +1 -0
  80. package/dist/commands/stop.js +18 -0
  81. package/dist/commands/stop.js.map +1 -0
  82. package/dist/create-workspace.d.ts +36 -0
  83. package/dist/create-workspace.d.ts.map +1 -1
  84. package/dist/create-workspace.js +366 -8
  85. package/dist/create-workspace.js.map +1 -1
  86. package/dist/studio-events.d.ts +9 -0
  87. package/dist/studio-events.d.ts.map +1 -0
  88. package/dist/studio-events.js +30 -0
  89. package/dist/studio-events.js.map +1 -0
  90. package/package.json +15 -6
  91. package/template/AGENTS.md +25 -21
  92. package/template/README.md +31 -12
  93. package/template/apps/web/e2e/README.md +7 -0
  94. package/template/apps/web/package.json +4 -2
  95. package/template/apps/web/playwright.config.ts +4 -3
  96. package/template/apps/web/src/document.css +5 -0
  97. package/template/apps/web/src/main.tsx +48 -3
  98. package/template/apps/web/src/user-end/tailwind.css +5 -0
  99. package/template/apps/web/test/loopback.test.ts +8 -2
  100. package/template/apps/web/test/standard-user-surfaces.typecheck.tsx +27 -0
  101. package/template/apps/web/vite.config.ts +5 -1
  102. package/template/appspec/app.md +56 -0
  103. package/template/openxiangda.config.ts +50 -25
  104. package/template/package.json +4 -4
  105. package/template/packages/contracts/package.json +1 -1
  106. package/template/packages/contracts/src/generated.ts +143 -2
  107. package/template/apps/server/Dockerfile +0 -20
  108. package/template/apps/server/package.json +0 -27
  109. package/template/apps/server/src/app.module.ts +0 -43
  110. package/template/apps/server/src/main.ts +0 -5
  111. package/template/apps/server/test/smoke.test.ts +0 -16
  112. package/template/apps/server/tsconfig.json +0 -9
  113. package/template/apps/web/data-api-live.e2e.html +0 -15
  114. package/template/apps/web/e2e/client-fixture.ts +0 -5
  115. package/template/apps/web/e2e/data-api-live-fixture.tsx +0 -146
  116. package/template/apps/web/e2e/data-api-live.spec.ts +0 -138
  117. package/template/apps/web/e2e/field-protocol-fixture.tsx +0 -347
  118. package/template/apps/web/e2e/field-protocol.spec.ts +0 -186
  119. package/template/apps/web/e2e/resources.spec.ts +0 -285
  120. package/template/apps/web/e2e/workflow.spec.ts +0 -329
  121. package/template/apps/web/field-protocol.e2e.html +0 -15
  122. package/template/apps/web/scripts/check.mjs +0 -43
  123. package/template/apps/web/test/contracts.test.ts +0 -99
  124. package/template/scripts/verify-template-budget.mjs +0 -49
@@ -1,99 +0,0 @@
1
- import assert from 'node:assert/strict';
2
- import { readFileSync, readdirSync } from 'node:fs';
3
- import test from 'node:test';
4
- import { readRuntimeMount, resolveApplicationBasename } from 'openxiangda/core';
5
- import {
6
- resourceCodes,
7
- resourceDefinitions,
8
- } from '../../../packages/contracts/src/generated.js';
9
-
10
- test('clean template contains only application declarations and one React entry', () => {
11
- const config = readFileSync(
12
- new URL('../../../openxiangda.config.ts', import.meta.url),
13
- 'utf8'
14
- );
15
- const source = readFileSync(new URL('../src/main.tsx', import.meta.url), 'utf8');
16
- const productionSources = readdirSync(new URL('../src', import.meta.url), {
17
- withFileTypes: true,
18
- })
19
- .filter(entry => entry.isFile())
20
- .map(entry => entry.name)
21
- .sort();
22
- assert.deepEqual(productionSources, ['main.tsx']);
23
- assert.deepEqual(Object.keys(resourceDefinitions).sort(), [...resourceCodes].sort());
24
- assert.match(config, /data:\s*\{\s*resources:/);
25
- assert.match(source, /OpenXiangdaApplication/);
26
- assert.match(source, /from 'openxiangda\/react'/);
27
- assert.match(source, /openxiangda\/react\/styles\.css/);
28
- const legacyMarkers = [
29
- 'instruments',
30
- 'colleges',
31
- '仪器' + '资源管理',
32
- '学院' + '字典',
33
- 'HGY',
34
- 'Instrument',
35
- ];
36
- assert.doesNotMatch(`${config}\n${source}`, new RegExp(legacyMarkers.join('|')));
37
- });
38
-
39
- test('application manifests expose one direct OpenXiangda dependency', () => {
40
- for (const relative of [
41
- '../../../package.json',
42
- '../package.json',
43
- '../../server/package.json',
44
- ]) {
45
- const manifest = JSON.parse(
46
- readFileSync(new URL(relative, import.meta.url), 'utf8')
47
- ) as Record<string, Record<string, string>>;
48
- const dependencies = Object.entries({
49
- ...(manifest.dependencies || {}),
50
- ...(manifest.devDependencies || {}),
51
- ...(manifest.peerDependencies || {}),
52
- }).filter(([name]) =>
53
- name === 'openxiangda' || name.startsWith('openxiangda-')
54
- );
55
- assert.deepEqual(
56
- dependencies.map(([name]) => name),
57
- dependencies.length ? ['openxiangda'] : []
58
- );
59
- }
60
- });
61
-
62
- test('runtime metadata stays mount-scoped', () => {
63
- const mount = readRuntimeMount(
64
- name =>
65
- ({
66
- 'openxiangda-runtime-base': '/view/example-app/',
67
- 'openxiangda-app-code': 'example-app',
68
- 'openxiangda-environment': 'preproduction',
69
- })[name]
70
- );
71
- assert.equal(resolveApplicationBasename(mount), '/view/example-app');
72
- });
73
-
74
- test('resource E2E harness owns the standard export download response', () => {
75
- const source = readFileSync(
76
- new URL('../e2e/resources.spec.ts', import.meta.url),
77
- 'utf8'
78
- );
79
- assert.match(source, /\/native\\\/data\\\/\(\[\^\/\]\+\)\\\/export\$/);
80
- assert.match(source, /content-disposition/);
81
- assert.match(source, /text\/csv/);
82
- });
83
-
84
- test('published E2E harnesses do not write evidence into the platform source repository', () => {
85
- const workflowSource = readFileSync(
86
- new URL('../e2e/workflow.spec.ts', import.meta.url),
87
- 'utf8'
88
- );
89
- assert.doesNotMatch(workflowSource, /docs\/architecture|evidenceDirectory/);
90
- });
91
-
92
- test('the platform package owns Web build verification policy', () => {
93
- const verifier = readFileSync(
94
- new URL('../scripts/verify-build.mjs', import.meta.url),
95
- 'utf8'
96
- );
97
- assert.match(verifier, /verifyOpenXiangdaWebBuild/);
98
- assert.doesNotMatch(verifier, /2_650_000|800_000|600_000/);
99
- });
@@ -1,49 +0,0 @@
1
- import { readFileSync, readdirSync, statSync } from 'node:fs';
2
- import { join, relative, resolve } from 'node:path';
3
-
4
- const root = resolve(import.meta.dirname, '..');
5
- const generated = /(?:^|\/)(?:node_modules|dist|coverage|playwright-report|test-results|\.openxiangda|\.turbo|\.turbopack|\.umi|\.umi-production)(?:\/|$)/;
6
- const sourceExtensions = /\.(?:[cm]?[jt]sx?|css|html|json|md|ya?ml)$/;
7
- const files = [];
8
- function visit(directory) {
9
- for (const entry of readdirSync(directory, { withFileTypes: true })) {
10
- const path = join(directory, entry.name);
11
- const name = relative(root, path).replaceAll('\\', '/');
12
- if (
13
- generated.test(name) ||
14
- name === 'pnpm-lock.yaml' ||
15
- name === 'packages/contracts/src/generated.ts'
16
- ) continue;
17
- if (entry.isDirectory()) visit(path);
18
- else if (entry.isFile() && sourceExtensions.test(name)) files.push(path);
19
- }
20
- }
21
- visit(root);
22
- const bytes = files.reduce((total, file) => total + statSync(file).size, 0);
23
- if (files.length > 50) throw new Error(`TEMPLATE_SOURCE_FILE_BUDGET_EXCEEDED:${files.length}>50`);
24
- if (bytes > 500_000) throw new Error(`TEMPLATE_SOURCE_BYTE_BUDGET_EXCEEDED:${bytes}>500000`);
25
- const productionFiles = files.filter(file => {
26
- const name = relative(root, file).replaceAll('\\', '/');
27
- return (
28
- name === 'package.json' ||
29
- name === 'openxiangda.config.ts' ||
30
- name.startsWith('platform/') ||
31
- (name.startsWith('apps/') &&
32
- !name.includes('/test/') &&
33
- !name.includes('/e2e/') &&
34
- !name.includes('/scripts/'))
35
- );
36
- });
37
- const source = productionFiles.map(file => readFileSync(file, 'utf8')).join('\n');
38
- const agents = readFileSync(resolve(root, 'AGENTS.md'), 'utf8');
39
- if (!agents.includes('pnpm openxiangda')) throw new Error('TEMPLATE_AGENT_PINNED_CLI_MISSING');
40
- if (
41
- !agents.includes("union of that user's application roles") ||
42
- !agents.includes('does not transmit a RoleSession header')
43
- ) {
44
- throw new Error('TEMPLATE_AGENT_ROLE_UNION_BOUNDARY_MISSING');
45
- }
46
- for (const marker of ['@umijs/', 'openxiangda-' + 'admin', 'openxiangda-' + 'user', 'instrument_query', 'instrument_save', 'function.invoke', 'departmentScopeKey', 'instrumentScopeKey', 'adminUserIds', 'college-' + 'am', 'user-' + 'wang', 'dept-' + 'am-test']) {
47
- if (source.includes(marker)) throw new Error(`TEMPLATE_FORBIDDEN_MARKER:${marker}`);
48
- }
49
- process.stdout.write(`Verified compact template: ${files.length} source files, ${bytes} bytes.\n`);