primitive-admin 1.1.0-alpha.47 → 1.1.0-alpha.49

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 (74) hide show
  1. package/dist/bin/primitive.js +2 -0
  2. package/dist/bin/primitive.js.map +1 -1
  3. package/dist/src/commands/apps.js +54 -2
  4. package/dist/src/commands/apps.js.map +1 -1
  5. package/dist/src/commands/databases.js +31 -10
  6. package/dist/src/commands/databases.js.map +1 -1
  7. package/dist/src/commands/documents.js +77 -0
  8. package/dist/src/commands/documents.js.map +1 -1
  9. package/dist/src/commands/guides.d.ts +15 -12
  10. package/dist/src/commands/guides.js +22 -15
  11. package/dist/src/commands/guides.js.map +1 -1
  12. package/dist/src/commands/settings.d.ts +15 -0
  13. package/dist/src/commands/settings.js +102 -0
  14. package/dist/src/commands/settings.js.map +1 -0
  15. package/dist/src/commands/sync-app-settings.d.ts +105 -0
  16. package/dist/src/commands/sync-app-settings.js +339 -0
  17. package/dist/src/commands/sync-app-settings.js.map +1 -0
  18. package/dist/src/commands/sync.d.ts +34 -19
  19. package/dist/src/commands/sync.js +373 -200
  20. package/dist/src/commands/sync.js.map +1 -1
  21. package/dist/src/commands/workflows.js +32 -10
  22. package/dist/src/commands/workflows.js.map +1 -1
  23. package/dist/src/lib/api-client.d.ts +2 -0
  24. package/dist/src/lib/api-client.js +6 -0
  25. package/dist/src/lib/api-client.js.map +1 -1
  26. package/dist/src/lib/app-settings-descriptor.d.ts +108 -0
  27. package/dist/src/lib/app-settings-descriptor.js +250 -0
  28. package/dist/src/lib/app-settings-descriptor.js.map +1 -0
  29. package/dist/src/lib/codegen-shared/generatedFiles.d.ts +15 -0
  30. package/dist/src/lib/codegen-shared/generatedFiles.js +27 -10
  31. package/dist/src/lib/codegen-shared/generatedFiles.js.map +1 -1
  32. package/dist/src/lib/db-codegen/dbGenerator.d.ts +11 -83
  33. package/dist/src/lib/db-codegen/dbGenerator.js +93 -556
  34. package/dist/src/lib/db-codegen/dbGenerator.js.map +1 -1
  35. package/dist/src/lib/db-codegen/dbNaming.d.ts +15 -7
  36. package/dist/src/lib/db-codegen/dbNaming.js +25 -13
  37. package/dist/src/lib/db-codegen/dbNaming.js.map +1 -1
  38. package/dist/src/lib/db-codegen/dbTemplates.d.ts +55 -4
  39. package/dist/src/lib/db-codegen/dbTemplates.js +169 -40
  40. package/dist/src/lib/db-codegen/dbTemplates.js.map +1 -1
  41. package/dist/src/lib/db-codegen/dbTypeIR.d.ts +146 -0
  42. package/dist/src/lib/db-codegen/dbTypeIR.js +517 -0
  43. package/dist/src/lib/db-codegen/dbTypeIR.js.map +1 -0
  44. package/dist/src/lib/db-codegen/generated-operation-def-descriptor.d.ts +101 -0
  45. package/dist/src/lib/db-codegen/generated-operation-def-descriptor.js +200 -0
  46. package/dist/src/lib/db-codegen/generated-operation-def-descriptor.js.map +1 -0
  47. package/dist/src/lib/swift-codegen/dbGenerator.d.ts +68 -0
  48. package/dist/src/lib/swift-codegen/dbGenerator.js +380 -0
  49. package/dist/src/lib/swift-codegen/dbGenerator.js.map +1 -0
  50. package/dist/src/lib/swift-codegen/dbSwiftTypes.d.ts +42 -0
  51. package/dist/src/lib/swift-codegen/dbSwiftTypes.js +100 -0
  52. package/dist/src/lib/swift-codegen/dbSwiftTypes.js.map +1 -0
  53. package/dist/src/lib/swift-codegen/generator.d.ts +84 -0
  54. package/dist/src/lib/swift-codegen/generator.js +178 -0
  55. package/dist/src/lib/swift-codegen/generator.js.map +1 -0
  56. package/dist/src/lib/swift-codegen/schemaToSwift.d.ts +72 -0
  57. package/dist/src/lib/swift-codegen/schemaToSwift.js +644 -0
  58. package/dist/src/lib/swift-codegen/schemaToSwift.js.map +1 -0
  59. package/dist/src/lib/swift-codegen/swiftNaming.d.ts +85 -0
  60. package/dist/src/lib/swift-codegen/swiftNaming.js +198 -0
  61. package/dist/src/lib/swift-codegen/swiftNaming.js.map +1 -0
  62. package/dist/src/lib/sync-resource-types.d.ts +225 -0
  63. package/dist/src/lib/sync-resource-types.js +394 -0
  64. package/dist/src/lib/sync-resource-types.js.map +1 -0
  65. package/dist/src/lib/template.d.ts +1 -1
  66. package/dist/src/lib/template.js +6 -3
  67. package/dist/src/lib/template.js.map +1 -1
  68. package/dist/src/lib/workflow-codegen/generator.d.ts +18 -5
  69. package/dist/src/lib/workflow-codegen/generator.js +116 -41
  70. package/dist/src/lib/workflow-codegen/generator.js.map +1 -1
  71. package/dist/src/lib/workflow-codegen/invokerIR.d.ts +85 -0
  72. package/dist/src/lib/workflow-codegen/invokerIR.js +71 -0
  73. package/dist/src/lib/workflow-codegen/invokerIR.js.map +1 -0
  74. package/package.json +4 -2
@@ -0,0 +1,178 @@
1
+ /**
2
+ * `workflows codegen --lang swift` orchestrator (issue #1547, Phases 2-3).
3
+ *
4
+ * The Swift counterpart of `workflow-codegen/generator.ts`. Reads the SAME
5
+ * synced workflow TOMLs (`.primitive/sync/<env>/<appId>/workflows/*.toml`) and
6
+ * emits ONE `<key>.generated.swift` per workflow. Each file carries the
7
+ * workflow's `<Key>Input`/`<Key>Output` Swift `Codable` types (Phase 1's
8
+ * `renderSwiftRootType`) plus — Phase 3 — a typed invoker factory: a free
9
+ * function `func <key>(_ client:) -> <Key>Workflow` returning a struct with
10
+ * `async throws` `runSync`/`start`/`getStatus` methods (Fork 2 = A). The
11
+ * factory binds `<Key>Input`/`<Key>Output` over the additive generic overloads
12
+ * on `WorkflowsAPI` (the only published SDK surface).
13
+ *
14
+ * Design decisions realized (maintainer decision, issue #1547):
15
+ * - Schemas are interpreted through the SAME drift-guarded descriptor the TS
16
+ * emitter reads (Fork 1 = A), via `renderSwiftRootType`, so a generated
17
+ * Swift type can never promise a shape the runtime validator rejects.
18
+ * - Operation metadata (key, `syncCallable`, required-vs-optional `input`) is
19
+ * read from the SHARED `describeWorkflowInvoker` IR — the SAME source the TS
20
+ * invoker uses. The Swift renderer reconstructs none of it (#1547 binding 5),
21
+ * so the two clients can never disagree on which operations a workflow
22
+ * exposes or whether its input is required.
23
+ * - `runSync` is emitted ONLY for `syncCallable: true` workflows (the server
24
+ * rejects run-sync otherwise), matching the TS factory. `start` + `getStatus`
25
+ * are emitted for every non-reserved workflow.
26
+ * - Disk lifecycle (write / `--check` / orphan cleanup) delegates to the shared
27
+ * `writeOrCheckGeneratedFiles`, scoped by an ownership BANNER (the "banner
28
+ * namespacing" edge case) so a shared Swift output dir stays safe.
29
+ */
30
+ import * as path from "path";
31
+ import { writeOrCheckGeneratedFiles, } from "../codegen-shared/generatedFiles.js";
32
+ import { fingerprintToml } from "../db-codegen/dbFingerprint.js";
33
+ import { describeWorkflowInvoker } from "../workflow-codegen/invokerIR.js";
34
+ import { renderSwiftRootType } from "./schemaToSwift.js";
35
+ import { structTypeName, workflowSwiftFactoryName } from "./swiftNaming.js";
36
+ /** Suffix identifying a generated Swift file. */
37
+ export const GENERATED_SWIFT_FILE_SUFFIX = ".generated.swift";
38
+ /**
39
+ * Banner prefix stamped at the top of every CLI-emitted `.generated.swift`
40
+ * file. Deliberately DISTINCT from the Swift model codegen's
41
+ * `// Generated by swift-bao-codegen` header so that:
42
+ * - the model codegen's stale-sweep (which only removes files starting with
43
+ * its own header) never deletes these; and
44
+ * - this generator's cleanup (scoped to this prefix) never deletes a
45
+ * model-codegen file that shares the `.generated.swift` suffix.
46
+ * The prefix is common to every workflow file, so it is a safe ownership key.
47
+ */
48
+ export const SWIFT_BANNER_PREFIX = "// AUTO-GENERATED FROM workflows/";
49
+ /** The Swift module the generated types + invoker import (`JSONValue`,
50
+ * `JsBaoClient`, the `WorkflowsAPI` generics, and the typed result structs all
51
+ * live there). */
52
+ const CLIENT_MODULE = "JsBaoClient";
53
+ const INDENT = " ";
54
+ /** PascalCase, sanitized, non-keyword base type name for a workflow key.
55
+ * `create-checkout-session` → `CreateCheckoutSession`; `123-job` → `_123Job`
56
+ * (digit-leading prefixed, parity with the TS `ensureValidIdentifierStart`). */
57
+ export function workflowSwiftTypeBaseName(key) {
58
+ return structTypeName(key);
59
+ }
60
+ /**
61
+ * Parse a single workflow TOML into the data the Swift emitter needs. The
62
+ * operation metadata comes from the SHARED `describeWorkflowInvoker` IR (the
63
+ * SAME source the TS invoker uses); only the Swift-specific naming +
64
+ * type-declaration rendering happens here. Throws on malformed schema JSON
65
+ * (fail-and-exit). Returns null for a reserved workflow.
66
+ */
67
+ function parseWorkflow(input) {
68
+ const ir = describeWorkflowInvoker({
69
+ fileStem: input.fileStem,
70
+ tomlContent: input.tomlContent,
71
+ });
72
+ if (!ir)
73
+ return null; // reserved workflow
74
+ const base = workflowSwiftTypeBaseName(ir.key);
75
+ const inputTypeName = `${base}Input`;
76
+ const outputTypeName = `${base}Output`;
77
+ const sourceFile = `workflows/${ir.key}.toml`;
78
+ return {
79
+ key: ir.key,
80
+ base,
81
+ inputTypeName,
82
+ outputTypeName,
83
+ syncCallable: ir.syncCallable,
84
+ inputRequired: ir.inputRequired,
85
+ inputDecl: renderSwiftRootType(inputTypeName, ir.inputSchema, { sourceFile }),
86
+ outputDecl: renderSwiftRootType(outputTypeName, ir.outputSchema, {
87
+ sourceFile,
88
+ }),
89
+ };
90
+ }
91
+ /** A Swift string literal for the workflow key (runtime call passes it verbatim). */
92
+ function swiftKeyLiteral(key) {
93
+ const escaped = key
94
+ .replace(/\\/g, "\\\\")
95
+ .replace(/"/g, '\\"')
96
+ .replace(/\n/g, "\\n")
97
+ .replace(/\r/g, "\\r")
98
+ .replace(/\t/g, "\\t");
99
+ return `"${escaped}"`;
100
+ }
101
+ /**
102
+ * Render the typed Swift invoker for one workflow (Fork 2 = A): a free function
103
+ * returning a small struct with `async throws` methods, mirroring the JS
104
+ * factory. `runSync` is emitted only when the shared IR says `syncCallable`;
105
+ * `start` + `getStatus` always. The `input` argument is required or optional
106
+ * per the shared IR's `inputRequired` (the SAME decision the TS factory makes).
107
+ *
108
+ * Each method delegates to the additive generic overloads on `WorkflowsAPI`
109
+ * (`runSync<Input,Output>` / `start<Input>` / `getStatus<Output>`), binding
110
+ * `<Key>Input`/`<Key>Output`. Those overloads are the only published SDK
111
+ * surface; this generated struct is app-target code.
112
+ */
113
+ function renderInvoker(wf) {
114
+ const structName = `${wf.base}Workflow`;
115
+ const factoryName = workflowSwiftFactoryName(wf.key);
116
+ const keyLiteral = swiftKeyLiteral(wf.key);
117
+ // Required `input` → `input: <Key>Input`; optional → `input: <Key>Input? = nil`.
118
+ // The generic overloads take `Input?`, so a required value auto-promotes and
119
+ // an omitted optional sends the server `{}` (parity with the JS `input ?? {}`).
120
+ const inputParam = wf.inputRequired
121
+ ? `input: ${wf.inputTypeName}`
122
+ : `input: ${wf.inputTypeName}? = nil`;
123
+ const lines = [];
124
+ lines.push(`/// Typed invoker for the \`${wf.key}\` workflow. Bind its \`${wf.inputTypeName}\` /`, `/// \`${wf.outputTypeName}\` over the generic \`WorkflowsAPI\` overloads. Obtain one`, `/// with \`${factoryName}(client)\`.`, `public struct ${structName}: Sendable {`, `${INDENT}public let client: JsBaoClient`, ``, `${INDENT}public init(client: JsBaoClient) {`, `${INDENT}${INDENT}self.client = client`, `${INDENT}}`);
125
+ if (wf.syncCallable) {
126
+ lines.push(``, `${INDENT}/// Run the workflow synchronously and wait for its terminal status.`, `${INDENT}/// Emitted only because \`${wf.key}\` is \`syncCallable\` (parity with JS).`, `${INDENT}public func runSync(`, `${INDENT}${INDENT}${inputParam},`, `${INDENT}${INDENT}runKey: String? = nil,`, `${INDENT}${INDENT}contextDocId: String? = nil,`, `${INDENT}${INDENT}meta: [String: Any]? = nil,`, `${INDENT}${INDENT}timeoutMs: Int? = nil`, `${INDENT}) async throws -> RunSyncResult<${wf.outputTypeName}> {`, `${INDENT}${INDENT}try await client.workflows.runSync(`, `${INDENT}${INDENT}${INDENT}workflowKey: ${keyLiteral},`, `${INDENT}${INDENT}${INDENT}input: input,`, `${INDENT}${INDENT}${INDENT}runKey: runKey,`, `${INDENT}${INDENT}${INDENT}contextDocId: contextDocId,`, `${INDENT}${INDENT}${INDENT}meta: meta,`, `${INDENT}${INDENT}${INDENT}timeoutMs: timeoutMs`, `${INDENT}${INDENT})`, `${INDENT}}`);
127
+ }
128
+ lines.push(``, `${INDENT}/// Start the workflow asynchronously; returns the run handle.`, `${INDENT}@discardableResult`, `${INDENT}public func start(`, `${INDENT}${INDENT}${inputParam},`, `${INDENT}${INDENT}runKey: String? = nil,`, `${INDENT}${INDENT}contextDocId: String? = nil,`, `${INDENT}${INDENT}meta: [String: Any]? = nil,`, `${INDENT}${INDENT}forceRerun: Bool? = nil`, `${INDENT}) async throws -> StartWorkflowResult {`, `${INDENT}${INDENT}try await client.workflows.start(`, `${INDENT}${INDENT}${INDENT}workflowKey: ${keyLiteral},`, `${INDENT}${INDENT}${INDENT}input: input,`, `${INDENT}${INDENT}${INDENT}runKey: runKey,`, `${INDENT}${INDENT}${INDENT}contextDocId: contextDocId,`, `${INDENT}${INDENT}${INDENT}meta: meta,`, `${INDENT}${INDENT}${INDENT}forceRerun: forceRerun`, `${INDENT}${INDENT})`, `${INDENT}}`);
129
+ lines.push(``, `${INDENT}/// Fetch a run's status with a typed \`output\` bound to \`${wf.outputTypeName}\`.`, `${INDENT}public func getStatus(`, `${INDENT}${INDENT}runKey: String,`, `${INDENT}${INDENT}contextDocId: String? = nil`, `${INDENT}) async throws -> WorkflowStatus<${wf.outputTypeName}> {`, `${INDENT}${INDENT}try await client.workflows.getStatus(`, `${INDENT}${INDENT}${INDENT}workflowKey: ${keyLiteral},`, `${INDENT}${INDENT}${INDENT}runKey: runKey,`, `${INDENT}${INDENT}${INDENT}contextDocId: contextDocId`, `${INDENT}${INDENT})`, `${INDENT}}`);
130
+ lines.push(`}`);
131
+ // The free-function factory (Fork 2 = A call shape: `<key>(client).runSync(...)`).
132
+ lines.push(``, `/// Typed invoker factory for the \`${wf.key}\` workflow.`, `public func ${factoryName}(_ client: JsBaoClient) -> ${structName} {`, `${INDENT}${structName}(client: client)`, `}`);
133
+ return lines.join("\n");
134
+ }
135
+ /**
136
+ * Render the full `<key>.generated.swift` content for a single workflow TOML.
137
+ * Returns null for a reserved (`__internal.*`) workflow. Pure — exported so
138
+ * tests can assert on the string directly.
139
+ */
140
+ export function renderWorkflowSwiftFile(input) {
141
+ const wf = parseWorkflow(input);
142
+ if (!wf)
143
+ return null;
144
+ const fingerprint = fingerprintToml(input.tomlContent);
145
+ const banner = [
146
+ `// AUTO-GENERATED FROM workflows/${wf.key}.toml — DO NOT EDIT.`,
147
+ "// Run `primitive workflows codegen --lang swift` to regenerate.",
148
+ `// fingerprint: ${fingerprint}`,
149
+ ].join("\n");
150
+ const imports = ["import Foundation", `import ${CLIENT_MODULE}`].join("\n");
151
+ const content = [banner, imports, wf.inputDecl, wf.outputDecl, renderInvoker(wf)].join("\n\n") + "\n";
152
+ return { key: wf.key, content };
153
+ }
154
+ /**
155
+ * Run Swift workflow codegen end-to-end. One `<key>.generated.swift` per
156
+ * workflow; delegates the disk lifecycle to the shared writer/checker with
157
+ * banner-scoped ownership so a shared Swift output dir stays safe.
158
+ */
159
+ export async function generateWorkflowSwiftTypes(options) {
160
+ const outAbs = path.resolve(options.outputDir);
161
+ const filesToWrite = new Map();
162
+ for (const input of options.inputs) {
163
+ const rendered = renderWorkflowSwiftFile(input);
164
+ if (!rendered)
165
+ continue; // reserved workflow — no file
166
+ const filePath = path.join(outAbs, `${rendered.key}${GENERATED_SWIFT_FILE_SUFFIX}`);
167
+ filesToWrite.set(filePath, rendered.content);
168
+ }
169
+ return await writeOrCheckGeneratedFiles({
170
+ outputDir: outAbs,
171
+ filesToWrite,
172
+ check: options.check,
173
+ fullOwnership: options.singleWorkflow !== true,
174
+ generatedSuffix: GENERATED_SWIFT_FILE_SUFFIX,
175
+ ownershipBanner: SWIFT_BANNER_PREFIX,
176
+ });
177
+ }
178
+ //# sourceMappingURL=generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../src/lib/swift-codegen/generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * JSON-Schema → Swift `Codable` converter for `swift-codegen` (issue #1547,
3
+ * Phase 1). The Swift counterpart of `workflow-codegen/schemaToTs.ts`.
4
+ *
5
+ * Both emitters read the SAME drift-guarded interpretation of the JSON-Schema
6
+ * subset the workflow platform supports — the vendored `SchemaDescriptor`
7
+ * (`workflow-codegen/generated-schema-descriptor.ts`, a byte copy of the server
8
+ * validator). Only the emitted syntax differs, so a generated Swift type can
9
+ * never promise a shape the runtime validator rejects. See the design and
10
+ * maintainer decision on issue #1547.
11
+ *
12
+ * Where Swift diverges from TypeScript:
13
+ *
14
+ * - **Named types, not anonymous.** TS renders nested object/enum/`oneOf`
15
+ * types inline; Swift `Codable` needs a NAMED `struct`/`enum` for each, so
16
+ * this emitter declares nested types inside their enclosing type.
17
+ * - **Scalars** (Fork 4, maintainer-confirmed): `string`→`String`,
18
+ * `number`→`Double`, `integer`→`Int` (ergonomic divergence from TS
19
+ * `number`), `boolean`→`Bool`.
20
+ * - **Un-descended nodes** (`$ref`, `allOf`, `format`, tuple `items`,
21
+ * `patternProperties`, numeric constraints, multi-scalar non-null unions,
22
+ * mixed-type enums, open-object extra values) → `JSONValue`, the Swift
23
+ * analog of TS `unknown`.
24
+ * - **`never`** (an uninhabitable enum after the type gate) → a strict codegen
25
+ * error, since the field can never be constructed (Fork 4).
26
+ * - **Scalar `enum`, all strings** → a nested `enum … : String, Codable,
27
+ * CaseIterable, Sendable`, the same form the Swift model codegen emits.
28
+ * - **`oneOf` discriminated union** → an `enum` with associated values plus a
29
+ * generated `init(from:)`/`encode(to:)` keyed on the discriminator.
30
+ *
31
+ * Codable semantics adopted from the maintainer decision (binding item 4):
32
+ *
33
+ * - Every generated `struct` gets a generated **public memberwise
34
+ * initializer** (Swift's synthesized memberwise init is not `public` across
35
+ * module boundaries).
36
+ * - A **required-nullable** property (required, but its value may be `null`)
37
+ * is encoded with an EXPLICIT null (not omitted) so server-side
38
+ * required-key validation still sees the key; decode is lenient (a missing
39
+ * key decodes to `nil`).
40
+ * - An **open object** stores unknown keys in an `extra: [String: JSONValue]`
41
+ * catch-all via custom Codable that separates known keys from extras; a key
42
+ * that collides with a known property is owned by the known property (the
43
+ * extra copy is dropped on encode, and never captured on decode).
44
+ * - A `oneOf` branch `struct` CARRIES the discriminator as a single-case
45
+ * `String` enum property, so decoding a branch rejects a conflicting
46
+ * discriminator value, and encoding re-emits the tag from the branch.
47
+ *
48
+ * Errors are named (`SwiftCodegenError`) and carry the source file and schema
49
+ * path for diagnostics (binding item 6).
50
+ */
51
+ import { schemaRejectsEmptyObject } from "../workflow-codegen/schemaToTs.js";
52
+ /** Re-exported so the invoker phases share ONE required-vs-optional decision. */
53
+ export { schemaRejectsEmptyObject };
54
+ /** A named codegen error carrying the source file + schema path (binding 6). */
55
+ export declare class SwiftCodegenError extends Error {
56
+ readonly sourceFile?: string;
57
+ readonly schemaPath?: string;
58
+ constructor(message: string, opts?: {
59
+ sourceFile?: string;
60
+ schemaPath?: string;
61
+ });
62
+ }
63
+ export interface SwiftCodegenContext {
64
+ /** The `.toml`/schema file this type was generated from, for diagnostics. */
65
+ sourceFile?: string;
66
+ }
67
+ /**
68
+ * Render a full Swift type declaration for a ROOT schema (e.g. a workflow's
69
+ * `<Key>Input`/`<Key>Output`), including every nested type it needs. Returns the
70
+ * Swift source for the type only — the CLI adds the import/banner (Phase 2).
71
+ */
72
+ export declare function renderSwiftRootType(rootTypeName: string, schema: any, ctx?: SwiftCodegenContext): string;