openxiangda 1.0.55 → 1.0.57
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/openxiangda-skills/skills/openxiangda-app/SKILL.md +3 -0
- package/openxiangda-skills/skills/openxiangda-core/SKILL.md +16 -0
- package/openxiangda-skills/skills/openxiangda-form/SKILL.md +9 -1
- package/package.json +1 -1
- package/packages/sdk/dist/build/index.cjs.map +1 -1
- package/packages/sdk/dist/build/index.d.mts +4 -1
- package/packages/sdk/dist/build/index.d.ts +4 -1
- package/packages/sdk/dist/build/index.mjs.map +1 -1
- package/packages/sdk/dist/runtime/index.cjs +19 -6
- package/packages/sdk/dist/runtime/index.cjs.map +1 -1
- package/packages/sdk/dist/runtime/index.mjs +18 -6
- package/packages/sdk/dist/runtime/index.mjs.map +1 -1
- package/packages/sdk/dist/runtime/react.cjs +9 -1
- package/packages/sdk/dist/runtime/react.cjs.map +1 -1
- package/packages/sdk/dist/runtime/react.mjs +9 -1
- package/packages/sdk/dist/runtime/react.mjs.map +1 -1
- package/packages/sdk/src/build-source/scripts/publish-all.mjs +19 -4
- package/packages/sdk/src/build-source/scripts/utils/load-config.mjs +10 -0
- package/templates/openxiangda-react-spa/app-workspace.config.ts +1 -0
- package/templates/sy-lowcode-app-workspace/src/types/app-workspace.types.ts +5 -0
|
@@ -65,6 +65,8 @@ openxiangda runtime deploy --profile <name>
|
|
|
65
65
|
```
|
|
66
66
|
|
|
67
67
|
`runtime deploy` builds and activates the app-level SPA release for `/view/:appType/*`.
|
|
68
|
+
Publish React SPA forms separately with `openxiangda workspace publish --form <formCode>`;
|
|
69
|
+
with `runtimeMode: "react-spa"` this is schema-only and does not require OSS.
|
|
68
70
|
|
|
69
71
|
Bind to an existing app only when the user explicitly provides `appType` or asks to reuse an existing platform app:
|
|
70
72
|
|
|
@@ -99,6 +101,7 @@ openxiangda workspace bind --profile <name> --app-type APP_XXX
|
|
|
99
101
|
- Use logical local codes for forms, pages, workflows, automations, and menus.
|
|
100
102
|
- Before scaffolding a new business app, read `../../references/best-practices.md` and pick an architecture from the initialized `examples/best-practices/` catalog. Do not generate a large single-file app page when a template pattern already covers the scenario.
|
|
101
103
|
- For Phase 6 React SPA apps, use `--runtime react-spa`. The generated app owns routing/layouts/menus with React Router and Tailwind CSS; platform permissions still come from backend runtime bootstrap and route checks.
|
|
104
|
+
- React SPA form publish is schema-only by default. Do not add OSS credentials or old embedded form bundles unless explicitly maintaining legacy compatibility with `--legacy-form-bundle`.
|
|
102
105
|
- When publishing after app edits, prefer targeted commands (`workspace publish --changed --dry-run`, then `--changed`, `--page`, `--form`, or `--only`). Do not publish all forms/pages just because one page changed.
|
|
103
106
|
- Use `openxiangda app snapshot <APP_XXX> --profile <name> --json` before changing an existing app.
|
|
104
107
|
|
|
@@ -45,6 +45,20 @@ openxiangda runtime deploy --profile <name>
|
|
|
45
45
|
|
|
46
46
|
`runtime deploy` builds the Vite app with a release-specific asset base, uploads `dist/` to the platform runtime release store, and activates the release unless `--no-activate` is passed.
|
|
47
47
|
|
|
48
|
+
For React SPA forms, still use targeted form publish to create/bind the form and
|
|
49
|
+
sync schema:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
openxiangda workspace publish --profile <name> --form <formCode> --dry-run
|
|
53
|
+
openxiangda workspace publish --profile <name> --form <formCode>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
When `app-workspace.config.ts` has `runtimeMode: "react-spa"`, form publish is
|
|
57
|
+
schema-only by default: it does not build or upload the legacy form page bundle
|
|
58
|
+
to OSS. The React SPA renders form submit/detail/list routes through
|
|
59
|
+
`openxiangda/runtime` default pages. Use `--legacy-form-bundle` only when a
|
|
60
|
+
React SPA app intentionally needs the old embedded form page bundle.
|
|
61
|
+
|
|
48
62
|
## DO NOT
|
|
49
63
|
|
|
50
64
|
- ❌ `pnpm publish:all` / `pnpm publish:oss` / `pnpm register` / `lowcode-workspace publish-*` directly. They are workspace internals and miss `OPENXIANGDA_PROFILE / BASE_URL / ACCESS_TOKEN / APP_TYPE` injection.
|
|
@@ -147,6 +161,8 @@ menus, and route permission checks. Do not publish React SPA pages through the
|
|
|
147
161
|
old custom-page app-shell path unless explicitly maintaining a legacy app.
|
|
148
162
|
Use `openxiangda resource publish` for roles/menus/page permission groups and
|
|
149
163
|
`openxiangda runtime deploy` for the SPA frontend release.
|
|
164
|
+
Use `openxiangda workspace publish --form <formCode>` only for schema/form shell
|
|
165
|
+
sync; it is schema-only by default and does not require OSS credentials.
|
|
150
166
|
|
|
151
167
|
Local workspace state is authoritative. If `.openxiangda/state.json` already contains an app binding for the target profile, use it. If there is no local binding, create a new app with `workspace init --app-name`; do not search platform apps for similar names.
|
|
152
168
|
|
|
@@ -85,6 +85,14 @@ openxiangda workspace publish --profile <name> --form <formCode>
|
|
|
85
85
|
|
|
86
86
|
The workspace publish script receives `OPENXIANGDA_BASE_URL`, `OPENXIANGDA_ACCESS_TOKEN`, and `OPENXIANGDA_APP_TYPE` from the CLI. It creates/binds the platform form shell only when needed, syncs form metadata, builds the React form page bundle, uploads assets, and registers the bundle.
|
|
87
87
|
|
|
88
|
+
For Phase 6 React SPA workspaces, `app-workspace.config.ts` should declare
|
|
89
|
+
`runtimeMode: "react-spa"`. In that mode, `workspace publish --form <code>` is
|
|
90
|
+
schema-only by default: it creates/binds the form and syncs schema, but skips
|
|
91
|
+
the legacy form page bundle, OSS upload, and bundle register. The app-level
|
|
92
|
+
React runtime renders submit/detail/list pages. Pass `--legacy-form-bundle`
|
|
93
|
+
only when intentionally maintaining compatibility with an old embedded form
|
|
94
|
+
page bundle.
|
|
95
|
+
|
|
88
96
|
## Low-level Commands
|
|
89
97
|
|
|
90
98
|
Use these only for diagnosis, binding existing resources, or repairing a broken publish state:
|
|
@@ -131,7 +139,7 @@ Read these references only when writing or reviewing schema:
|
|
|
131
139
|
- Put validation on field-level `rules`; never generate old top-level validation arrays under `schema.rules`. Top-level `rules` is only for `FormEffect[]` with `when` and `then`.
|
|
132
140
|
- Always provide `options` for option components. `SelectField`, `MultiSelectField`, `RadioField`, `CheckboxField`, and `CascadeSelectField` must not be emitted with `options` undefined. See `../../references/component-guide.md` for the full list and `../../references/platform-data-model.md` for the `{label, value}` storage contract.
|
|
133
141
|
- Do not emit raw native form controls in app/workspace source. For basic entry use `TextField`, `TextAreaField`, `NumberField`, `DateField`, `SelectField`, `RadioField`, etc.; for platform-specific entry use `UserSelectField`, `DepartmentSelectField`, `AttachmentField`, `ImageField`, `EditorField`, `DigitalSignatureField`, and `LocationField`.
|
|
134
|
-
- Workflow form pages use the same workspace form structure plus workflow v3 configuration
|
|
142
|
+
- Workflow form pages use the same workspace form structure plus workflow v3 configuration. In legacy workspaces, publish the form page bundle through workspace publish before treating it as complete. In React SPA workspaces, `workspace publish --form` syncs schema only, and the SPA default process pages render through `runtime deploy`.
|
|
135
143
|
- After editing one form, use `workspace publish --form <formCode>` or preview `--changed --dry-run`; do not run full workspace publish by default.
|
|
136
144
|
- Use `openxiangda form pull` or app snapshot before overwriting an existing form.
|
|
137
145
|
- Before assuming a value shape (e.g. dates, attachments, member fields, option fields), verify against `../../references/platform-data-model.md` instead of guessing.
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/build/index.ts"],"sourcesContent":["export type CssIsolation = 'namespace' | 'shadow' | 'none';\n\nexport interface AppWorkspaceConfig {\n appType?: string;\n appName?: string;\n platformUrl?: string;\n servicePrefix?: string;\n appKey?: string;\n appSecret?: string;\n userId?: string;\n version?: string;\n buildId?: string;\n oss?: {\n region?: string;\n bucket?: string;\n accessKeyId?: string;\n accessKeySecret?: string;\n pathPrefix?: string;\n corsOrigins?: string[];\n skipCors?: boolean;\n };\n defaults?: {\n protocolVersion?: string;\n frameworkVersion?: string;\n cssIsolation?: CssIsolation;\n formMenuParentId?: string;\n formMenuIcon?: string;\n pageMenuParentId?: string;\n pageMenuIcon?: string;\n formBuilderVersion?: string;\n };\n forms?: { dir?: string };\n pages?: { dir?: string };\n}\n\nexport function defineAppWorkspaceConfig<T extends AppWorkspaceConfig>(config: T): T {\n return config;\n}\n\nconst DEFAULT_NAMESPACE_PREFIX = '.sy-app-workspace';\n\nfunction splitCssSelectors(selector: string) {\n const selectors: string[] = [];\n let depth = 0;\n let quote = '';\n let current = '';\n for (const char of selector) {\n if (quote) {\n current += char;\n if (char === quote) quote = '';\n continue;\n }\n if (char === '\"' || char === \"'\") {\n quote = char;\n current += char;\n continue;\n }\n if (char === '(' || char === '[') depth += 1;\n if (char === ')' || char === ']') depth -= 1;\n if (char === ',' && depth === 0) {\n selectors.push(current.trim());\n current = '';\n continue;\n }\n current += char;\n }\n if (current.trim()) selectors.push(current.trim());\n return selectors;\n}\n\nfunction shouldSkipNamespace(selector: string, prefix: string) {\n if (!selector || selector.includes(prefix)) return true;\n if (/^(html|body|:root)(\\b|:|\\[|$)/.test(selector)) return true;\n if (/^(@|from\\b|to\\b|\\d+%)/.test(selector)) return true;\n if (/^\\.(ant|sy-ant|anticon|adm)-/.test(selector)) return true;\n return false;\n}\n\nfunction createAntdSelectorAlias(selector: string) {\n const aliased = selector\n .replace(/(^|[^A-Za-z0-9_-])\\.ant-/g, '$1.sy-ant-')\n .replace(/(^|[^A-Za-z0-9_-])\\.anticon-/g, '$1.sy-anticon-')\n .replace(/(^|[^A-Za-z0-9_-])\\.anticon(?=$|[^A-Za-z0-9_-])/g, '$1.sy-anticon');\n return aliased === selector ? null : aliased;\n}\n\nexport function createOpenXiangdaNamespaceCssPlugin(\n prefix = DEFAULT_NAMESPACE_PREFIX,\n) {\n return {\n postcssPlugin: 'openxiangda-namespace-css',\n Rule(rule: { selector?: string; parent?: any }) {\n if (!rule.selector) return;\n let parent = rule.parent;\n while (parent) {\n if (parent.type === 'atrule' && /keyframes$/i.test(parent.name)) {\n return;\n }\n parent = parent.parent;\n }\n rule.selector = Array.from(\n new Set(\n splitCssSelectors(rule.selector).flatMap((selector) => {\n const scopedSelector = shouldSkipNamespace(selector, prefix)\n ? selector\n : `${prefix} ${selector}`;\n const antdAlias = createAntdSelectorAlias(scopedSelector);\n return antdAlias ? [scopedSelector, antdAlias] : [scopedSelector];\n }),\n ),\n ).join(', ');\n },\n };\n}\n\n(createOpenXiangdaNamespaceCssPlugin as any).postcss = true;\n\nexport const createNamespaceCssPlugin = createOpenXiangdaNamespaceCssPlugin;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
1
|
+
{"version":3,"sources":["../../src/build/index.ts"],"sourcesContent":["export type CssIsolation = 'namespace' | 'shadow' | 'none';\nexport type WorkspaceRuntimeMode = 'legacy' | 'react-spa';\n\nexport interface AppWorkspaceConfig {\n appType?: string;\n appName?: string;\n runtimeMode?: WorkspaceRuntimeMode;\n platformUrl?: string;\n servicePrefix?: string;\n appKey?: string;\n appSecret?: string;\n userId?: string;\n version?: string;\n buildId?: string;\n oss?: {\n region?: string;\n bucket?: string;\n accessKeyId?: string;\n accessKeySecret?: string;\n pathPrefix?: string;\n corsOrigins?: string[];\n skipCors?: boolean;\n };\n defaults?: {\n protocolVersion?: string;\n frameworkVersion?: string;\n cssIsolation?: CssIsolation;\n formMenuParentId?: string;\n formMenuIcon?: string;\n pageMenuParentId?: string;\n pageMenuIcon?: string;\n formBuilderVersion?: string;\n };\n forms?: { dir?: string; publishLegacyBundle?: boolean };\n pages?: { dir?: string };\n}\n\nexport function defineAppWorkspaceConfig<T extends AppWorkspaceConfig>(config: T): T {\n return config;\n}\n\nconst DEFAULT_NAMESPACE_PREFIX = '.sy-app-workspace';\n\nfunction splitCssSelectors(selector: string) {\n const selectors: string[] = [];\n let depth = 0;\n let quote = '';\n let current = '';\n for (const char of selector) {\n if (quote) {\n current += char;\n if (char === quote) quote = '';\n continue;\n }\n if (char === '\"' || char === \"'\") {\n quote = char;\n current += char;\n continue;\n }\n if (char === '(' || char === '[') depth += 1;\n if (char === ')' || char === ']') depth -= 1;\n if (char === ',' && depth === 0) {\n selectors.push(current.trim());\n current = '';\n continue;\n }\n current += char;\n }\n if (current.trim()) selectors.push(current.trim());\n return selectors;\n}\n\nfunction shouldSkipNamespace(selector: string, prefix: string) {\n if (!selector || selector.includes(prefix)) return true;\n if (/^(html|body|:root)(\\b|:|\\[|$)/.test(selector)) return true;\n if (/^(@|from\\b|to\\b|\\d+%)/.test(selector)) return true;\n if (/^\\.(ant|sy-ant|anticon|adm)-/.test(selector)) return true;\n return false;\n}\n\nfunction createAntdSelectorAlias(selector: string) {\n const aliased = selector\n .replace(/(^|[^A-Za-z0-9_-])\\.ant-/g, '$1.sy-ant-')\n .replace(/(^|[^A-Za-z0-9_-])\\.anticon-/g, '$1.sy-anticon-')\n .replace(/(^|[^A-Za-z0-9_-])\\.anticon(?=$|[^A-Za-z0-9_-])/g, '$1.sy-anticon');\n return aliased === selector ? null : aliased;\n}\n\nexport function createOpenXiangdaNamespaceCssPlugin(\n prefix = DEFAULT_NAMESPACE_PREFIX,\n) {\n return {\n postcssPlugin: 'openxiangda-namespace-css',\n Rule(rule: { selector?: string; parent?: any }) {\n if (!rule.selector) return;\n let parent = rule.parent;\n while (parent) {\n if (parent.type === 'atrule' && /keyframes$/i.test(parent.name)) {\n return;\n }\n parent = parent.parent;\n }\n rule.selector = Array.from(\n new Set(\n splitCssSelectors(rule.selector).flatMap((selector) => {\n const scopedSelector = shouldSkipNamespace(selector, prefix)\n ? selector\n : `${prefix} ${selector}`;\n const antdAlias = createAntdSelectorAlias(scopedSelector);\n return antdAlias ? [scopedSelector, antdAlias] : [scopedSelector];\n }),\n ),\n ).join(', ');\n },\n };\n}\n\n(createOpenXiangdaNamespaceCssPlugin as any).postcss = true;\n\nexport const createNamespaceCssPlugin = createOpenXiangdaNamespaceCssPlugin;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAqCO,SAAS,yBAAuD,QAAc;AACnF,SAAO;AACT;AAEA,IAAM,2BAA2B;AAEjC,SAAS,kBAAkB,UAAkB;AAC3C,QAAM,YAAsB,CAAC;AAC7B,MAAI,QAAQ;AACZ,MAAI,QAAQ;AACZ,MAAI,UAAU;AACd,aAAW,QAAQ,UAAU;AAC3B,QAAI,OAAO;AACT,iBAAW;AACX,UAAI,SAAS,MAAO,SAAQ;AAC5B;AAAA,IACF;AACA,QAAI,SAAS,OAAO,SAAS,KAAK;AAChC,cAAQ;AACR,iBAAW;AACX;AAAA,IACF;AACA,QAAI,SAAS,OAAO,SAAS,IAAK,UAAS;AAC3C,QAAI,SAAS,OAAO,SAAS,IAAK,UAAS;AAC3C,QAAI,SAAS,OAAO,UAAU,GAAG;AAC/B,gBAAU,KAAK,QAAQ,KAAK,CAAC;AAC7B,gBAAU;AACV;AAAA,IACF;AACA,eAAW;AAAA,EACb;AACA,MAAI,QAAQ,KAAK,EAAG,WAAU,KAAK,QAAQ,KAAK,CAAC;AACjD,SAAO;AACT;AAEA,SAAS,oBAAoB,UAAkB,QAAgB;AAC7D,MAAI,CAAC,YAAY,SAAS,SAAS,MAAM,EAAG,QAAO;AACnD,MAAI,gCAAgC,KAAK,QAAQ,EAAG,QAAO;AAC3D,MAAI,wBAAwB,KAAK,QAAQ,EAAG,QAAO;AACnD,MAAI,+BAA+B,KAAK,QAAQ,EAAG,QAAO;AAC1D,SAAO;AACT;AAEA,SAAS,wBAAwB,UAAkB;AACjD,QAAM,UAAU,SACb,QAAQ,6BAA6B,YAAY,EACjD,QAAQ,iCAAiC,gBAAgB,EACzD,QAAQ,oDAAoD,eAAe;AAC9E,SAAO,YAAY,WAAW,OAAO;AACvC;AAEO,SAAS,oCACd,SAAS,0BACT;AACA,SAAO;AAAA,IACL,eAAe;AAAA,IACf,KAAK,MAA2C;AAC9C,UAAI,CAAC,KAAK,SAAU;AACpB,UAAI,SAAS,KAAK;AAClB,aAAO,QAAQ;AACb,YAAI,OAAO,SAAS,YAAY,cAAc,KAAK,OAAO,IAAI,GAAG;AAC/D;AAAA,QACF;AACA,iBAAS,OAAO;AAAA,MAClB;AACA,WAAK,WAAW,MAAM;AAAA,QACpB,IAAI;AAAA,UACF,kBAAkB,KAAK,QAAQ,EAAE,QAAQ,CAAC,aAAa;AACrD,kBAAM,iBAAiB,oBAAoB,UAAU,MAAM,IACvD,WACA,GAAG,MAAM,IAAI,QAAQ;AACzB,kBAAM,YAAY,wBAAwB,cAAc;AACxD,mBAAO,YAAY,CAAC,gBAAgB,SAAS,IAAI,CAAC,cAAc;AAAA,UAClE,CAAC;AAAA,QACH;AAAA,MACF,EAAE,KAAK,IAAI;AAAA,IACb;AAAA,EACF;AACF;AAEC,oCAA4C,UAAU;AAEhD,IAAM,2BAA2B;","names":[]}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
type CssIsolation = 'namespace' | 'shadow' | 'none';
|
|
2
|
+
type WorkspaceRuntimeMode = 'legacy' | 'react-spa';
|
|
2
3
|
interface AppWorkspaceConfig {
|
|
3
4
|
appType?: string;
|
|
4
5
|
appName?: string;
|
|
6
|
+
runtimeMode?: WorkspaceRuntimeMode;
|
|
5
7
|
platformUrl?: string;
|
|
6
8
|
servicePrefix?: string;
|
|
7
9
|
appKey?: string;
|
|
@@ -30,6 +32,7 @@ interface AppWorkspaceConfig {
|
|
|
30
32
|
};
|
|
31
33
|
forms?: {
|
|
32
34
|
dir?: string;
|
|
35
|
+
publishLegacyBundle?: boolean;
|
|
33
36
|
};
|
|
34
37
|
pages?: {
|
|
35
38
|
dir?: string;
|
|
@@ -45,4 +48,4 @@ declare function createOpenXiangdaNamespaceCssPlugin(prefix?: string): {
|
|
|
45
48
|
};
|
|
46
49
|
declare const createNamespaceCssPlugin: typeof createOpenXiangdaNamespaceCssPlugin;
|
|
47
50
|
|
|
48
|
-
export { type AppWorkspaceConfig, type CssIsolation, createNamespaceCssPlugin, createOpenXiangdaNamespaceCssPlugin, defineAppWorkspaceConfig };
|
|
51
|
+
export { type AppWorkspaceConfig, type CssIsolation, type WorkspaceRuntimeMode, createNamespaceCssPlugin, createOpenXiangdaNamespaceCssPlugin, defineAppWorkspaceConfig };
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
type CssIsolation = 'namespace' | 'shadow' | 'none';
|
|
2
|
+
type WorkspaceRuntimeMode = 'legacy' | 'react-spa';
|
|
2
3
|
interface AppWorkspaceConfig {
|
|
3
4
|
appType?: string;
|
|
4
5
|
appName?: string;
|
|
6
|
+
runtimeMode?: WorkspaceRuntimeMode;
|
|
5
7
|
platformUrl?: string;
|
|
6
8
|
servicePrefix?: string;
|
|
7
9
|
appKey?: string;
|
|
@@ -30,6 +32,7 @@ interface AppWorkspaceConfig {
|
|
|
30
32
|
};
|
|
31
33
|
forms?: {
|
|
32
34
|
dir?: string;
|
|
35
|
+
publishLegacyBundle?: boolean;
|
|
33
36
|
};
|
|
34
37
|
pages?: {
|
|
35
38
|
dir?: string;
|
|
@@ -45,4 +48,4 @@ declare function createOpenXiangdaNamespaceCssPlugin(prefix?: string): {
|
|
|
45
48
|
};
|
|
46
49
|
declare const createNamespaceCssPlugin: typeof createOpenXiangdaNamespaceCssPlugin;
|
|
47
50
|
|
|
48
|
-
export { type AppWorkspaceConfig, type CssIsolation, createNamespaceCssPlugin, createOpenXiangdaNamespaceCssPlugin, defineAppWorkspaceConfig };
|
|
51
|
+
export { type AppWorkspaceConfig, type CssIsolation, type WorkspaceRuntimeMode, createNamespaceCssPlugin, createOpenXiangdaNamespaceCssPlugin, defineAppWorkspaceConfig };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/build/index.ts"],"sourcesContent":["export type CssIsolation = 'namespace' | 'shadow' | 'none';\n\nexport interface AppWorkspaceConfig {\n appType?: string;\n appName?: string;\n platformUrl?: string;\n servicePrefix?: string;\n appKey?: string;\n appSecret?: string;\n userId?: string;\n version?: string;\n buildId?: string;\n oss?: {\n region?: string;\n bucket?: string;\n accessKeyId?: string;\n accessKeySecret?: string;\n pathPrefix?: string;\n corsOrigins?: string[];\n skipCors?: boolean;\n };\n defaults?: {\n protocolVersion?: string;\n frameworkVersion?: string;\n cssIsolation?: CssIsolation;\n formMenuParentId?: string;\n formMenuIcon?: string;\n pageMenuParentId?: string;\n pageMenuIcon?: string;\n formBuilderVersion?: string;\n };\n forms?: { dir?: string };\n pages?: { dir?: string };\n}\n\nexport function defineAppWorkspaceConfig<T extends AppWorkspaceConfig>(config: T): T {\n return config;\n}\n\nconst DEFAULT_NAMESPACE_PREFIX = '.sy-app-workspace';\n\nfunction splitCssSelectors(selector: string) {\n const selectors: string[] = [];\n let depth = 0;\n let quote = '';\n let current = '';\n for (const char of selector) {\n if (quote) {\n current += char;\n if (char === quote) quote = '';\n continue;\n }\n if (char === '\"' || char === \"'\") {\n quote = char;\n current += char;\n continue;\n }\n if (char === '(' || char === '[') depth += 1;\n if (char === ')' || char === ']') depth -= 1;\n if (char === ',' && depth === 0) {\n selectors.push(current.trim());\n current = '';\n continue;\n }\n current += char;\n }\n if (current.trim()) selectors.push(current.trim());\n return selectors;\n}\n\nfunction shouldSkipNamespace(selector: string, prefix: string) {\n if (!selector || selector.includes(prefix)) return true;\n if (/^(html|body|:root)(\\b|:|\\[|$)/.test(selector)) return true;\n if (/^(@|from\\b|to\\b|\\d+%)/.test(selector)) return true;\n if (/^\\.(ant|sy-ant|anticon|adm)-/.test(selector)) return true;\n return false;\n}\n\nfunction createAntdSelectorAlias(selector: string) {\n const aliased = selector\n .replace(/(^|[^A-Za-z0-9_-])\\.ant-/g, '$1.sy-ant-')\n .replace(/(^|[^A-Za-z0-9_-])\\.anticon-/g, '$1.sy-anticon-')\n .replace(/(^|[^A-Za-z0-9_-])\\.anticon(?=$|[^A-Za-z0-9_-])/g, '$1.sy-anticon');\n return aliased === selector ? null : aliased;\n}\n\nexport function createOpenXiangdaNamespaceCssPlugin(\n prefix = DEFAULT_NAMESPACE_PREFIX,\n) {\n return {\n postcssPlugin: 'openxiangda-namespace-css',\n Rule(rule: { selector?: string; parent?: any }) {\n if (!rule.selector) return;\n let parent = rule.parent;\n while (parent) {\n if (parent.type === 'atrule' && /keyframes$/i.test(parent.name)) {\n return;\n }\n parent = parent.parent;\n }\n rule.selector = Array.from(\n new Set(\n splitCssSelectors(rule.selector).flatMap((selector) => {\n const scopedSelector = shouldSkipNamespace(selector, prefix)\n ? selector\n : `${prefix} ${selector}`;\n const antdAlias = createAntdSelectorAlias(scopedSelector);\n return antdAlias ? [scopedSelector, antdAlias] : [scopedSelector];\n }),\n ),\n ).join(', ');\n },\n };\n}\n\n(createOpenXiangdaNamespaceCssPlugin as any).postcss = true;\n\nexport const createNamespaceCssPlugin = createOpenXiangdaNamespaceCssPlugin;\n"],"mappings":";
|
|
1
|
+
{"version":3,"sources":["../../src/build/index.ts"],"sourcesContent":["export type CssIsolation = 'namespace' | 'shadow' | 'none';\nexport type WorkspaceRuntimeMode = 'legacy' | 'react-spa';\n\nexport interface AppWorkspaceConfig {\n appType?: string;\n appName?: string;\n runtimeMode?: WorkspaceRuntimeMode;\n platformUrl?: string;\n servicePrefix?: string;\n appKey?: string;\n appSecret?: string;\n userId?: string;\n version?: string;\n buildId?: string;\n oss?: {\n region?: string;\n bucket?: string;\n accessKeyId?: string;\n accessKeySecret?: string;\n pathPrefix?: string;\n corsOrigins?: string[];\n skipCors?: boolean;\n };\n defaults?: {\n protocolVersion?: string;\n frameworkVersion?: string;\n cssIsolation?: CssIsolation;\n formMenuParentId?: string;\n formMenuIcon?: string;\n pageMenuParentId?: string;\n pageMenuIcon?: string;\n formBuilderVersion?: string;\n };\n forms?: { dir?: string; publishLegacyBundle?: boolean };\n pages?: { dir?: string };\n}\n\nexport function defineAppWorkspaceConfig<T extends AppWorkspaceConfig>(config: T): T {\n return config;\n}\n\nconst DEFAULT_NAMESPACE_PREFIX = '.sy-app-workspace';\n\nfunction splitCssSelectors(selector: string) {\n const selectors: string[] = [];\n let depth = 0;\n let quote = '';\n let current = '';\n for (const char of selector) {\n if (quote) {\n current += char;\n if (char === quote) quote = '';\n continue;\n }\n if (char === '\"' || char === \"'\") {\n quote = char;\n current += char;\n continue;\n }\n if (char === '(' || char === '[') depth += 1;\n if (char === ')' || char === ']') depth -= 1;\n if (char === ',' && depth === 0) {\n selectors.push(current.trim());\n current = '';\n continue;\n }\n current += char;\n }\n if (current.trim()) selectors.push(current.trim());\n return selectors;\n}\n\nfunction shouldSkipNamespace(selector: string, prefix: string) {\n if (!selector || selector.includes(prefix)) return true;\n if (/^(html|body|:root)(\\b|:|\\[|$)/.test(selector)) return true;\n if (/^(@|from\\b|to\\b|\\d+%)/.test(selector)) return true;\n if (/^\\.(ant|sy-ant|anticon|adm)-/.test(selector)) return true;\n return false;\n}\n\nfunction createAntdSelectorAlias(selector: string) {\n const aliased = selector\n .replace(/(^|[^A-Za-z0-9_-])\\.ant-/g, '$1.sy-ant-')\n .replace(/(^|[^A-Za-z0-9_-])\\.anticon-/g, '$1.sy-anticon-')\n .replace(/(^|[^A-Za-z0-9_-])\\.anticon(?=$|[^A-Za-z0-9_-])/g, '$1.sy-anticon');\n return aliased === selector ? null : aliased;\n}\n\nexport function createOpenXiangdaNamespaceCssPlugin(\n prefix = DEFAULT_NAMESPACE_PREFIX,\n) {\n return {\n postcssPlugin: 'openxiangda-namespace-css',\n Rule(rule: { selector?: string; parent?: any }) {\n if (!rule.selector) return;\n let parent = rule.parent;\n while (parent) {\n if (parent.type === 'atrule' && /keyframes$/i.test(parent.name)) {\n return;\n }\n parent = parent.parent;\n }\n rule.selector = Array.from(\n new Set(\n splitCssSelectors(rule.selector).flatMap((selector) => {\n const scopedSelector = shouldSkipNamespace(selector, prefix)\n ? selector\n : `${prefix} ${selector}`;\n const antdAlias = createAntdSelectorAlias(scopedSelector);\n return antdAlias ? [scopedSelector, antdAlias] : [scopedSelector];\n }),\n ),\n ).join(', ');\n },\n };\n}\n\n(createOpenXiangdaNamespaceCssPlugin as any).postcss = true;\n\nexport const createNamespaceCssPlugin = createOpenXiangdaNamespaceCssPlugin;\n"],"mappings":";AAqCO,SAAS,yBAAuD,QAAc;AACnF,SAAO;AACT;AAEA,IAAM,2BAA2B;AAEjC,SAAS,kBAAkB,UAAkB;AAC3C,QAAM,YAAsB,CAAC;AAC7B,MAAI,QAAQ;AACZ,MAAI,QAAQ;AACZ,MAAI,UAAU;AACd,aAAW,QAAQ,UAAU;AAC3B,QAAI,OAAO;AACT,iBAAW;AACX,UAAI,SAAS,MAAO,SAAQ;AAC5B;AAAA,IACF;AACA,QAAI,SAAS,OAAO,SAAS,KAAK;AAChC,cAAQ;AACR,iBAAW;AACX;AAAA,IACF;AACA,QAAI,SAAS,OAAO,SAAS,IAAK,UAAS;AAC3C,QAAI,SAAS,OAAO,SAAS,IAAK,UAAS;AAC3C,QAAI,SAAS,OAAO,UAAU,GAAG;AAC/B,gBAAU,KAAK,QAAQ,KAAK,CAAC;AAC7B,gBAAU;AACV;AAAA,IACF;AACA,eAAW;AAAA,EACb;AACA,MAAI,QAAQ,KAAK,EAAG,WAAU,KAAK,QAAQ,KAAK,CAAC;AACjD,SAAO;AACT;AAEA,SAAS,oBAAoB,UAAkB,QAAgB;AAC7D,MAAI,CAAC,YAAY,SAAS,SAAS,MAAM,EAAG,QAAO;AACnD,MAAI,gCAAgC,KAAK,QAAQ,EAAG,QAAO;AAC3D,MAAI,wBAAwB,KAAK,QAAQ,EAAG,QAAO;AACnD,MAAI,+BAA+B,KAAK,QAAQ,EAAG,QAAO;AAC1D,SAAO;AACT;AAEA,SAAS,wBAAwB,UAAkB;AACjD,QAAM,UAAU,SACb,QAAQ,6BAA6B,YAAY,EACjD,QAAQ,iCAAiC,gBAAgB,EACzD,QAAQ,oDAAoD,eAAe;AAC9E,SAAO,YAAY,WAAW,OAAO;AACvC;AAEO,SAAS,oCACd,SAAS,0BACT;AACA,SAAO;AAAA,IACL,eAAe;AAAA,IACf,KAAK,MAA2C;AAC9C,UAAI,CAAC,KAAK,SAAU;AACpB,UAAI,SAAS,KAAK;AAClB,aAAO,QAAQ;AACb,YAAI,OAAO,SAAS,YAAY,cAAc,KAAK,OAAO,IAAI,GAAG;AAC/D;AAAA,QACF;AACA,iBAAS,OAAO;AAAA,MAClB;AACA,WAAK,WAAW,MAAM;AAAA,QACpB,IAAI;AAAA,UACF,kBAAkB,KAAK,QAAQ,EAAE,QAAQ,CAAC,aAAa;AACrD,kBAAM,iBAAiB,oBAAoB,UAAU,MAAM,IACvD,WACA,GAAG,MAAM,IAAI,QAAQ;AACzB,kBAAM,YAAY,wBAAwB,cAAc;AACxD,mBAAO,YAAY,CAAC,gBAAgB,SAAS,IAAI,CAAC,cAAc;AAAA,UAClE,CAAC;AAAA,QACH;AAAA,MACF,EAAE,KAAK,IAAI;AAAA,IACb;AAAA,EACF;AACF;AAEC,oCAA4C,UAAU;AAEhD,IAAM,2BAA2B;","names":[]}
|
|
@@ -3316,6 +3316,15 @@ var usePageRoute = () => {
|
|
|
3316
3316
|
// packages/sdk/src/runtime/react/openxiangdaProvider.tsx
|
|
3317
3317
|
init_cjs_shims();
|
|
3318
3318
|
var import_react7 = require("react");
|
|
3319
|
+
|
|
3320
|
+
// packages/sdk/src/runtime/core/fetch.ts
|
|
3321
|
+
init_cjs_shims();
|
|
3322
|
+
var createBoundFetch = (fetchImpl) => {
|
|
3323
|
+
const baseFetch = fetchImpl || globalThis.fetch;
|
|
3324
|
+
return ((input, init) => baseFetch.call(globalThis, input, init));
|
|
3325
|
+
};
|
|
3326
|
+
|
|
3327
|
+
// packages/sdk/src/runtime/react/openxiangdaProvider.tsx
|
|
3319
3328
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
3320
3329
|
var OpenXiangdaRuntimeContext = (0, import_react7.createContext)(null);
|
|
3321
3330
|
var OpenXiangdaProvider = ({
|
|
@@ -3324,7 +3333,7 @@ var OpenXiangdaProvider = ({
|
|
|
3324
3333
|
fetchImpl,
|
|
3325
3334
|
children
|
|
3326
3335
|
}) => {
|
|
3327
|
-
const resolvedFetch = fetchImpl
|
|
3336
|
+
const resolvedFetch = (0, import_react7.useMemo)(() => createBoundFetch(fetchImpl), [fetchImpl]);
|
|
3328
3337
|
const resolvedAppType = (0, import_react7.useMemo)(
|
|
3329
3338
|
() => appType || resolveAppTypeFromLocation(),
|
|
3330
3339
|
[appType]
|
|
@@ -3579,7 +3588,7 @@ var parseJsonResponse = async (response) => {
|
|
|
3579
3588
|
};
|
|
3580
3589
|
var createBrowserPageBridge = (options = {}) => {
|
|
3581
3590
|
const servicePrefix = options.servicePrefix || getDefaultServicePrefix();
|
|
3582
|
-
const fetchImpl = options.fetchImpl
|
|
3591
|
+
const fetchImpl = createBoundFetch(options.fetchImpl);
|
|
3583
3592
|
const request = async (payload) => {
|
|
3584
3593
|
if (!payload?.path) {
|
|
3585
3594
|
throw new Error("transport.request \u9700\u8981 path");
|
|
@@ -3705,6 +3714,7 @@ var createBrowserPageContext = (bootstrap, options = {}) => {
|
|
|
3705
3714
|
};
|
|
3706
3715
|
};
|
|
3707
3716
|
var resolveRuntimeAssets = async (bootstrap, fetchImpl = fetch) => {
|
|
3717
|
+
const boundFetch = createBoundFetch(fetchImpl);
|
|
3708
3718
|
const fallback = {
|
|
3709
3719
|
entryUrl: bootstrap.runtimeAssets?.entryUrl || bootstrap.asset?.entryUrl || "",
|
|
3710
3720
|
cssUrls: bootstrap.runtimeAssets?.cssUrls || bootstrap.asset?.cssAssets || [],
|
|
@@ -3717,7 +3727,7 @@ var resolveRuntimeAssets = async (bootstrap, fetchImpl = fetch) => {
|
|
|
3717
3727
|
return fallback;
|
|
3718
3728
|
}
|
|
3719
3729
|
try {
|
|
3720
|
-
const response = await
|
|
3730
|
+
const response = await boundFetch(bootstrap.asset.manifestUrl, {
|
|
3721
3731
|
credentials: "omit"
|
|
3722
3732
|
});
|
|
3723
3733
|
if (!response.ok) return fallback;
|
|
@@ -3752,7 +3762,8 @@ var fetchBrowserRuntimeBootstrap = async ({
|
|
|
3752
3762
|
const path = bootstrapPath || `/openxiangda-api/v1/apps/${encodeURIComponent(
|
|
3753
3763
|
appType
|
|
3754
3764
|
)}/pages/${encodeURIComponent(pageKey)}/bootstrap`;
|
|
3755
|
-
const
|
|
3765
|
+
const boundFetch = createBoundFetch(fetchImpl);
|
|
3766
|
+
const response = await boundFetch(
|
|
3756
3767
|
joinServicePath(servicePrefix || getDefaultServicePrefix(), path),
|
|
3757
3768
|
{
|
|
3758
3769
|
method: "GET",
|
|
@@ -3787,7 +3798,8 @@ var resolveBrowserRuntimeRoute = async ({
|
|
|
3787
3798
|
const endpoint = resolvePath || `/openxiangda-api/v1/apps/${encodeURIComponent(
|
|
3788
3799
|
appType
|
|
3789
3800
|
)}/runtime/routes/resolve`;
|
|
3790
|
-
const
|
|
3801
|
+
const boundFetch = createBoundFetch(fetchImpl);
|
|
3802
|
+
const response = await boundFetch(
|
|
3791
3803
|
joinServicePath(servicePrefix || getDefaultServicePrefix(), endpoint),
|
|
3792
3804
|
{
|
|
3793
3805
|
method: "POST",
|
|
@@ -50116,6 +50128,7 @@ var parseRuntimeResponse = async (response) => {
|
|
|
50116
50128
|
return await response.json();
|
|
50117
50129
|
};
|
|
50118
50130
|
var createBuiltinRouteRequest = (servicePrefix = DEFAULT_SERVICE_PREFIX, fetchImpl = fetch) => async (config3) => {
|
|
50131
|
+
const boundFetch = createBoundFetch(fetchImpl);
|
|
50119
50132
|
const headers = new Headers(config3.headers);
|
|
50120
50133
|
let body;
|
|
50121
50134
|
if (config3.data !== void 0) {
|
|
@@ -50126,7 +50139,7 @@ var createBuiltinRouteRequest = (servicePrefix = DEFAULT_SERVICE_PREFIX, fetchIm
|
|
|
50126
50139
|
body = JSON.stringify(config3.data);
|
|
50127
50140
|
}
|
|
50128
50141
|
}
|
|
50129
|
-
const response = await
|
|
50142
|
+
const response = await boundFetch(appendQuery3(joinServicePath2(servicePrefix, config3.url), config3.params), {
|
|
50130
50143
|
method: normalizeMethod3(config3.method),
|
|
50131
50144
|
headers,
|
|
50132
50145
|
body,
|