@mulmoclaude/core 3.6.0 → 3.7.0
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/collection/registry/server/index.cjs +19 -19
- package/dist/collection/registry/server/index.cjs.map +1 -1
- package/dist/collection/registry/server/index.js +2 -2
- package/dist/collection/server/host.d.ts +11 -0
- package/dist/collection/server/index.cjs +72 -59
- package/dist/collection/server/index.d.ts +4 -0
- package/dist/collection/server/index.js +3 -3
- package/dist/collection/server/manageTool.d.ts +4 -0
- package/dist/collection/server/publish.d.ts +56 -0
- package/dist/collection/server/publishChecks.d.ts +29 -0
- package/dist/collection/server/publishManifest.d.ts +181 -0
- package/dist/collection/server/publishProject.d.ts +86 -0
- package/dist/collection/server/validate.d.ts +12 -0
- package/dist/collection-watchers/index.cjs +15 -15
- package/dist/collection-watchers/index.cjs.map +1 -1
- package/dist/collection-watchers/index.js +2 -2
- package/dist/feeds/server/index.cjs +10 -10
- package/dist/feeds/server/index.cjs.map +1 -1
- package/dist/feeds/server/index.js +2 -2
- package/dist/google/index.cjs +12 -12
- package/dist/google/index.cjs.map +1 -1
- package/dist/google/index.js +1 -1
- package/dist/{server-DdHaX_Uu.js → server-B48Jyxcj.js} +1079 -228
- package/dist/server-B48Jyxcj.js.map +1 -0
- package/dist/{server-9mFaGLdq.cjs → server-CWZyg8fn.cjs} +1318 -389
- package/dist/server-CWZyg8fn.cjs.map +1 -0
- package/dist/{discovery-Cw5xWzZD.cjs → store-5_P_NsGa.cjs} +1947 -1947
- package/dist/store-5_P_NsGa.cjs.map +1 -0
- package/dist/{discovery-CdkaURVY.js → store-_61sO8K8.js} +1948 -1948
- package/dist/store-_61sO8K8.js.map +1 -0
- package/dist/whisper/index.cjs +1 -1
- package/dist/whisper/index.js +1 -1
- package/package.json +1 -1
- package/dist/discovery-CdkaURVY.js.map +0 -1
- package/dist/discovery-Cw5xWzZD.cjs.map +0 -1
- package/dist/server-9mFaGLdq.cjs.map +0 -1
- package/dist/server-DdHaX_Uu.js.map +0 -1
|
@@ -121,6 +121,17 @@ export interface CollectionHost {
|
|
|
121
121
|
export interface FirestoreHandle {
|
|
122
122
|
docs: FirestoreDocs;
|
|
123
123
|
email: string;
|
|
124
|
+
/** The signed-in Firebase uid.
|
|
125
|
+
*
|
|
126
|
+
* The EMAIL is the principal the roster is keyed by, and it is what every
|
|
127
|
+
* record operation needs. The uid is needed by exactly one caller —
|
|
128
|
+
* `publish` — because the app document's `owner` is a uid: the rules
|
|
129
|
+
* require `owner == request.auth.uid` when the app is created and require
|
|
130
|
+
* it unchanged afterwards. Required rather than optional so a host cannot
|
|
131
|
+
* wire a session that can read and write records but silently cannot
|
|
132
|
+
* create an app; the failure would surface as a permission denial with
|
|
133
|
+
* nothing in it about identity. */
|
|
134
|
+
uid: string;
|
|
124
135
|
}
|
|
125
136
|
/** A collection's records changed on disk. Carries the `slug` so the host can
|
|
126
137
|
* publish on a per-collection channel; `ids` lists the affected record ids
|
|
@@ -1,102 +1,115 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_root = require("../../root-rPH6FGDT.cjs");
|
|
3
3
|
const require_calendarGrid = require("../../calendarGrid-DGILaVxI.cjs");
|
|
4
|
-
const
|
|
4
|
+
const require_store = require("../../store-5_P_NsGa.cjs");
|
|
5
|
+
const require_server = require("../../server-CWZyg8fn.cjs");
|
|
5
6
|
const require_templatePath = require("../../templatePath-27vUZowm.cjs");
|
|
6
|
-
|
|
7
|
-
exports.APP_MANIFEST_FILE =
|
|
8
|
-
exports.
|
|
9
|
-
exports.
|
|
7
|
+
exports.APPS_COLLECTION = require_server.APPS_COLLECTION;
|
|
8
|
+
exports.APP_MANIFEST_FILE = require_store.APP_MANIFEST_FILE;
|
|
9
|
+
exports.APP_ROLES = require_server.APP_ROLES;
|
|
10
|
+
exports.AuthoredAppZ = require_server.AuthoredAppZ;
|
|
11
|
+
exports.BackendUnavailableError = require_store.BackendUnavailableError;
|
|
12
|
+
exports.COLLECTION_ROOT_REQUIRED = require_store.COLLECTION_ROOT_REQUIRED;
|
|
10
13
|
exports.COMPUTED_TYPES = require_calendarGrid.COMPUTED_TYPES;
|
|
11
|
-
exports.CollectionQueryZ =
|
|
12
|
-
exports.CollectionSchemaZ =
|
|
13
|
-
exports.DEFAULT_QUERY_ROWS =
|
|
14
|
-
exports.MAX_CSV_ROWS =
|
|
15
|
-
exports.MAX_QUERY_ROWS =
|
|
14
|
+
exports.CollectionQueryZ = require_store.CollectionQueryZ;
|
|
15
|
+
exports.CollectionSchemaZ = require_store.CollectionSchemaZ;
|
|
16
|
+
exports.DEFAULT_QUERY_ROWS = require_store.DEFAULT_QUERY_ROWS;
|
|
17
|
+
exports.MAX_CSV_ROWS = require_store.MAX_CSV_ROWS;
|
|
18
|
+
exports.MAX_QUERY_ROWS = require_store.MAX_QUERY_ROWS;
|
|
19
|
+
exports.MAX_RECORD_ISSUES = require_server.MAX_RECORD_ISSUES;
|
|
16
20
|
exports.MAX_SCHEMA_ISSUES = require_server.MAX_SCHEMA_ISSUES;
|
|
17
21
|
exports.MAX_UNSELECTIVE_ITEMS = require_server.MAX_UNSELECTIVE_ITEMS;
|
|
18
|
-
exports.
|
|
19
|
-
exports.
|
|
22
|
+
exports.PUBLIC_CONFIG_DOC = require_server.PUBLIC_CONFIG_DOC;
|
|
23
|
+
exports.SCHEMA_FILE = require_store.SCHEMA_FILE;
|
|
24
|
+
exports.STORE_UNREADABLE = require_server.STORE_UNREADABLE;
|
|
25
|
+
exports.acceptParsedSchema = require_store.acceptParsedSchema;
|
|
20
26
|
exports.advanceTriggerDate = require_server.advanceTriggerDate;
|
|
21
|
-
exports.
|
|
27
|
+
exports.appConfigPath = require_server.appConfigPath;
|
|
28
|
+
exports.appManifestReason = require_store.appManifestReason;
|
|
29
|
+
exports.appSchemasPath = require_server.appSchemasPath;
|
|
22
30
|
exports.applyMutateAction = require_server.applyMutateAction;
|
|
31
|
+
exports.bindsSubmitterIdentity = require_server.bindsSubmitterIdentity;
|
|
23
32
|
exports.buildActionSeedPrompt = require_server.buildActionSeedPrompt;
|
|
24
33
|
exports.buildCollectionActionSeedPrompt = require_server.buildCollectionActionSeedPrompt;
|
|
25
34
|
exports.buildWorkspaceOntology = require_server.buildWorkspaceOntology;
|
|
26
35
|
exports.canonicalRoot = require_root.canonicalRoot;
|
|
27
|
-
exports.collectionChangeKey =
|
|
28
|
-
exports.collectionChangePayload =
|
|
29
|
-
exports.collectionWritable =
|
|
30
|
-
exports.compileCsvQuery =
|
|
31
|
-
exports.compileJsonlQuery =
|
|
36
|
+
exports.collectionChangeKey = require_store.collectionChangeKey;
|
|
37
|
+
exports.collectionChangePayload = require_store.collectionChangePayload;
|
|
38
|
+
exports.collectionWritable = require_store.collectionWritable;
|
|
39
|
+
exports.compileCsvQuery = require_store.compileCsvQuery;
|
|
40
|
+
exports.compileJsonlQuery = require_store.compileJsonlQuery;
|
|
32
41
|
exports.compileRecordZ = require_server.compileRecordZ;
|
|
33
42
|
exports.computeCollectionIcon = require_server.computeCollectionIcon;
|
|
34
43
|
exports.computeSuccessor = require_server.computeSuccessor;
|
|
35
|
-
exports.configureCollectionHost =
|
|
36
|
-
exports.csvRowToItem =
|
|
44
|
+
exports.configureCollectionHost = require_store.configureCollectionHost;
|
|
45
|
+
exports.csvRowToItem = require_store.csvRowToItem;
|
|
37
46
|
exports.daysInMonth = require_server.daysInMonth;
|
|
38
|
-
exports.decodeCsvRecordId =
|
|
39
|
-
exports.dedupeByRecordId =
|
|
47
|
+
exports.decodeCsvRecordId = require_store.decodeCsvRecordId;
|
|
48
|
+
exports.dedupeByRecordId = require_store.dedupeByRecordId;
|
|
40
49
|
exports.deleteCollection = require_server.deleteCollection;
|
|
41
50
|
exports.deleteCollectionRefusalMessage = require_server.deleteCollectionRefusalMessage;
|
|
42
51
|
exports.deleteCustomView = require_server.deleteCustomView;
|
|
43
|
-
exports.deleteItem =
|
|
44
|
-
exports.discoverCollections =
|
|
45
|
-
exports.encodeCsvRecordId =
|
|
52
|
+
exports.deleteItem = require_store.deleteItem;
|
|
53
|
+
exports.discoverCollections = require_store.discoverCollections;
|
|
54
|
+
exports.encodeCsvRecordId = require_store.encodeCsvRecordId;
|
|
46
55
|
exports.enrichItems = require_server.enrichItems;
|
|
47
|
-
exports.firestoreHandle =
|
|
56
|
+
exports.firestoreHandle = require_store.firestoreHandle;
|
|
48
57
|
exports.firstMutateParamProblem = require_server.firstMutateParamProblem;
|
|
49
58
|
exports.formatCivil = require_server.formatCivil;
|
|
50
|
-
exports.generateItemId =
|
|
51
|
-
exports.getWorkspaceRoot =
|
|
52
|
-
exports.isBackendUnavailable =
|
|
53
|
-
exports.isContainedInRoot =
|
|
54
|
-
exports.isRegularFile =
|
|
59
|
+
exports.generateItemId = require_store.generateItemId;
|
|
60
|
+
exports.getWorkspaceRoot = require_store.getWorkspaceRoot;
|
|
61
|
+
exports.isBackendUnavailable = require_store.isBackendUnavailable;
|
|
62
|
+
exports.isContainedInRoot = require_store.isContainedInRoot;
|
|
63
|
+
exports.isRegularFile = require_store.isRegularFile;
|
|
55
64
|
exports.isSafeActionTemplatePath = require_templatePath.isSafeActionTemplatePath;
|
|
56
65
|
exports.isSafeCustomViewI18nPath = require_templatePath.isSafeCustomViewI18nPath;
|
|
57
66
|
exports.isSafeCustomViewPath = require_templatePath.isSafeCustomViewPath;
|
|
58
67
|
exports.isSafeTemplatePath = require_templatePath.isSafeTemplatePath;
|
|
59
68
|
exports.isTriggerDue = require_server.isTriggerDue;
|
|
60
|
-
exports.itemFilePath =
|
|
61
|
-
exports.listItems =
|
|
62
|
-
exports.loadAppManifest =
|
|
63
|
-
exports.loadCollection =
|
|
64
|
-
exports.localCollectionKey =
|
|
65
|
-
exports.log =
|
|
69
|
+
exports.itemFilePath = require_store.itemFilePath;
|
|
70
|
+
exports.listItems = require_store.listItems;
|
|
71
|
+
exports.loadAppManifest = require_store.loadAppManifest;
|
|
72
|
+
exports.loadCollection = require_store.loadCollection;
|
|
73
|
+
exports.localCollectionKey = require_store.localCollectionKey;
|
|
74
|
+
exports.log = require_store.log;
|
|
66
75
|
exports.makeManageCollectionTool = require_server.makeManageCollectionTool;
|
|
67
76
|
exports.maybeSpawnSuccessor = require_server.maybeSpawnSuccessor;
|
|
68
|
-
exports.normalizeCsvValue =
|
|
69
|
-
exports.pageFromFullRead =
|
|
70
|
-
exports.parseAppManifest =
|
|
77
|
+
exports.normalizeCsvValue = require_store.normalizeCsvValue;
|
|
78
|
+
exports.pageFromFullRead = require_store.pageFromFullRead;
|
|
79
|
+
exports.parseAppManifest = require_store.parseAppManifest;
|
|
80
|
+
exports.parseAuthoredApp = require_server.parseAuthoredApp;
|
|
71
81
|
exports.parseCivil = require_server.parseCivil;
|
|
72
|
-
exports.peekWorkspaceRoot =
|
|
73
|
-
exports.
|
|
82
|
+
exports.peekWorkspaceRoot = require_store.peekWorkspaceRoot;
|
|
83
|
+
exports.projectApp = require_server.projectApp;
|
|
84
|
+
exports.projectItemFields = require_store.projectItemFields;
|
|
74
85
|
exports.promptPathsFor = require_server.promptPathsFor;
|
|
75
|
-
exports.
|
|
86
|
+
exports.publishApp = require_server.publishApp;
|
|
87
|
+
exports.publishCollectionChange = require_store.publishCollectionChange;
|
|
88
|
+
exports.publishProblems = require_server.publishProblems;
|
|
76
89
|
exports.readCustomViewHtml = require_server.readCustomViewHtml;
|
|
77
90
|
exports.readCustomViewI18n = require_server.readCustomViewI18n;
|
|
78
|
-
exports.readItem =
|
|
79
|
-
exports.readOnlyRefusal =
|
|
91
|
+
exports.readItem = require_store.readItem;
|
|
92
|
+
exports.readOnlyRefusal = require_store.readOnlyRefusal;
|
|
80
93
|
exports.readSkillTemplate = require_server.readSkillTemplate;
|
|
81
94
|
exports.recordFieldProblem = require_server.recordFieldProblem;
|
|
82
|
-
exports.resolveCreateItemId =
|
|
83
|
-
exports.resolveDataDir =
|
|
95
|
+
exports.resolveCreateItemId = require_store.resolveCreateItemId;
|
|
96
|
+
exports.resolveDataDir = require_store.resolveDataDir;
|
|
84
97
|
exports.resolveEvery = require_server.resolveEvery;
|
|
85
|
-
exports.resolvePrimaryField =
|
|
86
|
-
exports.resolveTemplatePath =
|
|
98
|
+
exports.resolvePrimaryField = require_store.resolvePrimaryField;
|
|
99
|
+
exports.resolveTemplatePath = require_store.resolveTemplatePath;
|
|
87
100
|
exports.runCollectionQuery = require_server.runCollectionQuery;
|
|
88
101
|
exports.runQueryOverRows = require_server.runQueryOverRows;
|
|
89
|
-
exports.safeRecordId =
|
|
90
|
-
exports.safeSlugName =
|
|
102
|
+
exports.safeRecordId = require_store.safeRecordId;
|
|
103
|
+
exports.safeSlugName = require_store.safeSlugName;
|
|
91
104
|
exports.schemaRelations = require_server.schemaRelations;
|
|
92
|
-
exports.setCollectionChangePublisher =
|
|
93
|
-
exports.setFirestoreAccessor =
|
|
94
|
-
exports.sharedCollectionChangePayload =
|
|
95
|
-
exports.sharedItemsPath =
|
|
96
|
-
exports.storeFor =
|
|
105
|
+
exports.setCollectionChangePublisher = require_store.setCollectionChangePublisher;
|
|
106
|
+
exports.setFirestoreAccessor = require_store.setFirestoreAccessor;
|
|
107
|
+
exports.sharedCollectionChangePayload = require_store.sharedCollectionChangePayload;
|
|
108
|
+
exports.sharedItemsPath = require_store.sharedItemsPath;
|
|
109
|
+
exports.storeFor = require_store.storeFor;
|
|
97
110
|
exports.successorId = require_server.successorId;
|
|
98
|
-
exports.toDetail =
|
|
99
|
-
exports.toSummary =
|
|
111
|
+
exports.toDetail = require_store.toDetail;
|
|
112
|
+
exports.toSummary = require_store.toSummary;
|
|
100
113
|
exports.validateCollectionRecords = require_server.validateCollectionRecords;
|
|
101
114
|
exports.validateRecordObject = require_server.validateRecordObject;
|
|
102
|
-
exports.writeItem =
|
|
115
|
+
exports.writeItem = require_store.writeItem;
|
|
@@ -2,6 +2,10 @@ export { configureCollectionHost, canonicalRoot, getWorkspaceRoot, peekWorkspace
|
|
|
2
2
|
export type { FirestoreDoc, FirestoreDocs } from './firestoreDocs';
|
|
3
3
|
export { sharedItemsPath } from './firestoreStore';
|
|
4
4
|
export { loadAppManifest, parseAppManifest, appManifestReason, APP_MANIFEST_FILE, type AppManifest, type AppManifestResult } from './appManifest';
|
|
5
|
+
export { AuthoredAppZ, parseAuthoredApp, APP_ROLES, type AuthoredApp, type AuthoredCollectionConfig, type AuthoredMail, type AuthoredSubmit, } from './publishManifest';
|
|
6
|
+
export { projectApp, APPS_COLLECTION, PUBLIC_CONFIG_DOC, appConfigPath, appSchemasPath, type PublishStamp, type PublishedApp, type PublishedConfigDoc, type PublishedSchemaDoc, } from './publishProject';
|
|
7
|
+
export { publishProblems, bindsSubmitterIdentity, type PublishableCollection } from './publishChecks';
|
|
8
|
+
export { publishApp, type PublishOptions, type PublishResult } from './publish';
|
|
5
9
|
export type { LoadedCollection } from './discoveredCollection';
|
|
6
10
|
export * from './paths';
|
|
7
11
|
export * from './templatePath';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as canonicalRoot } from "../../root-BMroU_mB.js";
|
|
2
2
|
import { j as COMPUTED_TYPES } from "../../calendarGrid-CQ8MVSRb.js";
|
|
3
|
-
import { A as
|
|
3
|
+
import { A as toSummary, B as SCHEMA_FILE, C as resolveCreateItemId, D as loadCollection, E as discoverCollections, F as loadAppManifest, G as safeRecordId, H as itemFilePath, I as parseAppManifest, J as isBackendUnavailable, K as safeSlugName, L as sharedItemsPath, N as APP_MANIFEST_FILE, O as resolvePrimaryField, P as appManifestReason, Q as collectionChangePayload, R as pageFromFullRead, S as readItem, T as acceptParsedSchema, U as resolveDataDir, V as isContainedInRoot, W as resolveTemplatePath, Y as COLLECTION_ROOT_REQUIRED, Z as collectionChangeKey, _ as MAX_QUERY_ROWS, a as MAX_CSV_ROWS, at as log, b as isRegularFile, c as decodeCsvRecordId, ct as publishCollectionChange, d as normalizeCsvValue, dt as sharedCollectionChangePayload, et as configureCollectionHost, g as DEFAULT_QUERY_ROWS, h as CollectionQueryZ, it as localCollectionKey, j as CollectionSchemaZ, k as toDetail, l as dedupeByRecordId, lt as setCollectionChangePublisher, m as compileJsonlQuery, n as readOnlyRefusal, nt as getWorkspaceRoot, ot as peekWorkspaceRoot, p as compileCsvQuery, q as BackendUnavailableError, r as storeFor, s as csvRowToItem, t as collectionWritable, tt as firestoreHandle, u as encodeCsvRecordId, ut as setFirestoreAccessor, v as deleteItem, w as writeItem, x as listItems, y as generateItemId, z as projectItemFields } from "../../store-_61sO8K8.js";
|
|
4
|
+
import { A as readSkillTemplate, B as APPS_COLLECTION, C as enrichItems, D as promptPathsFor, E as buildCollectionActionSeedPrompt, F as validateRecordObject, G as APP_ROLES, H as appConfigPath, I as compileRecordZ, K as AuthoredAppZ, L as recordFieldProblem, M as MAX_RECORD_ISSUES, N as STORE_UNREADABLE, O as readCustomViewHtml, P as validateCollectionRecords, R as bindsSubmitterIdentity, S as runCollectionQuery, T as buildActionSeedPrompt, U as appSchemasPath, V as PUBLIC_CONFIG_DOC, W as projectApp, _ as computeCollectionIcon, a as deleteCollection, b as applyMutateAction, c as computeSuccessor, d as isTriggerDue, f as maybeSpawnSuccessor, h as successorId, i as deleteCustomView, j as publishApp, k as readCustomViewI18n, l as daysInMonth, m as resolveEvery, n as MAX_UNSELECTIVE_ITEMS, o as deleteCollectionRefusalMessage, p as parseCivil, q as parseAuthoredApp, r as makeManageCollectionTool, s as advanceTriggerDate, t as MAX_SCHEMA_ISSUES, u as formatCivil, v as buildWorkspaceOntology, w as runQueryOverRows, x as firstMutateParamProblem, y as schemaRelations, z as publishProblems } from "../../server-B48Jyxcj.js";
|
|
4
5
|
import { i as isSafeTemplatePath, n as isSafeCustomViewI18nPath, r as isSafeCustomViewPath, t as isSafeActionTemplatePath } from "../../templatePath-k_WNbL_Q.js";
|
|
5
|
-
|
|
6
|
-
export { APP_MANIFEST_FILE, BackendUnavailableError, COLLECTION_ROOT_REQUIRED, COMPUTED_TYPES, CollectionQueryZ, CollectionSchemaZ, DEFAULT_QUERY_ROWS, MAX_CSV_ROWS, MAX_QUERY_ROWS, MAX_SCHEMA_ISSUES, MAX_UNSELECTIVE_ITEMS, SCHEMA_FILE, acceptParsedSchema, advanceTriggerDate, appManifestReason, applyMutateAction, buildActionSeedPrompt, buildCollectionActionSeedPrompt, buildWorkspaceOntology, canonicalRoot, collectionChangeKey, collectionChangePayload, collectionWritable, compileCsvQuery, compileJsonlQuery, compileRecordZ, computeCollectionIcon, computeSuccessor, configureCollectionHost, csvRowToItem, daysInMonth, decodeCsvRecordId, dedupeByRecordId, deleteCollection, deleteCollectionRefusalMessage, deleteCustomView, deleteItem, discoverCollections, encodeCsvRecordId, enrichItems, firestoreHandle, firstMutateParamProblem, formatCivil, generateItemId, getWorkspaceRoot, isBackendUnavailable, isContainedInRoot, isRegularFile, isSafeActionTemplatePath, isSafeCustomViewI18nPath, isSafeCustomViewPath, isSafeTemplatePath, isTriggerDue, itemFilePath, listItems, loadAppManifest, loadCollection, localCollectionKey, log, makeManageCollectionTool, maybeSpawnSuccessor, normalizeCsvValue, pageFromFullRead, parseAppManifest, parseCivil, peekWorkspaceRoot, projectItemFields, promptPathsFor, publishCollectionChange, readCustomViewHtml, readCustomViewI18n, readItem, readOnlyRefusal, readSkillTemplate, recordFieldProblem, resolveCreateItemId, resolveDataDir, resolveEvery, resolvePrimaryField, resolveTemplatePath, runCollectionQuery, runQueryOverRows, safeRecordId, safeSlugName, schemaRelations, setCollectionChangePublisher, setFirestoreAccessor, sharedCollectionChangePayload, sharedItemsPath, storeFor, successorId, toDetail, toSummary, validateCollectionRecords, validateRecordObject, writeItem };
|
|
6
|
+
export { APPS_COLLECTION, APP_MANIFEST_FILE, APP_ROLES, AuthoredAppZ, BackendUnavailableError, COLLECTION_ROOT_REQUIRED, COMPUTED_TYPES, CollectionQueryZ, CollectionSchemaZ, DEFAULT_QUERY_ROWS, MAX_CSV_ROWS, MAX_QUERY_ROWS, MAX_RECORD_ISSUES, MAX_SCHEMA_ISSUES, MAX_UNSELECTIVE_ITEMS, PUBLIC_CONFIG_DOC, SCHEMA_FILE, STORE_UNREADABLE, acceptParsedSchema, advanceTriggerDate, appConfigPath, appManifestReason, appSchemasPath, applyMutateAction, bindsSubmitterIdentity, buildActionSeedPrompt, buildCollectionActionSeedPrompt, buildWorkspaceOntology, canonicalRoot, collectionChangeKey, collectionChangePayload, collectionWritable, compileCsvQuery, compileJsonlQuery, compileRecordZ, computeCollectionIcon, computeSuccessor, configureCollectionHost, csvRowToItem, daysInMonth, decodeCsvRecordId, dedupeByRecordId, deleteCollection, deleteCollectionRefusalMessage, deleteCustomView, deleteItem, discoverCollections, encodeCsvRecordId, enrichItems, firestoreHandle, firstMutateParamProblem, formatCivil, generateItemId, getWorkspaceRoot, isBackendUnavailable, isContainedInRoot, isRegularFile, isSafeActionTemplatePath, isSafeCustomViewI18nPath, isSafeCustomViewPath, isSafeTemplatePath, isTriggerDue, itemFilePath, listItems, loadAppManifest, loadCollection, localCollectionKey, log, makeManageCollectionTool, maybeSpawnSuccessor, normalizeCsvValue, pageFromFullRead, parseAppManifest, parseAuthoredApp, parseCivil, peekWorkspaceRoot, projectApp, projectItemFields, promptPathsFor, publishApp, publishCollectionChange, publishProblems, readCustomViewHtml, readCustomViewI18n, readItem, readOnlyRefusal, readSkillTemplate, recordFieldProblem, resolveCreateItemId, resolveDataDir, resolveEvery, resolvePrimaryField, resolveTemplatePath, runCollectionQuery, runQueryOverRows, safeRecordId, safeSlugName, schemaRelations, setCollectionChangePublisher, setFirestoreAccessor, sharedCollectionChangePayload, sharedItemsPath, storeFor, successorId, toDetail, toSummary, validateCollectionRecords, validateRecordObject, writeItem };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { DiscoveryOptions } from './discovery';
|
|
2
|
+
import { PublishedApp } from './publishProject';
|
|
3
|
+
export interface PublishOptions extends DiscoveryOptions {
|
|
4
|
+
/** Proceed even though existing records fail the schemas about to be
|
|
5
|
+
* published. Never a default: the pre-check is the migration gate, and a
|
|
6
|
+
* gate that opens itself is a log line. */
|
|
7
|
+
confirm?: boolean | undefined;
|
|
8
|
+
/** Wall clock, injectable so a test can assert an exact document. */
|
|
9
|
+
now?: (() => number) | undefined;
|
|
10
|
+
/** Resolve the commit the declaration is being published from. Injectable
|
|
11
|
+
* for the same reason, and because a repository without git is a normal
|
|
12
|
+
* state rather than a failure. */
|
|
13
|
+
resolveCommit?: ((root: string) => Promise<{
|
|
14
|
+
commit?: string | undefined;
|
|
15
|
+
dirty?: boolean | undefined;
|
|
16
|
+
}>) | undefined;
|
|
17
|
+
}
|
|
18
|
+
export type PublishResult = {
|
|
19
|
+
ok: false;
|
|
20
|
+
problems: string[];
|
|
21
|
+
/** Did any document reach Firestore before this failed?
|
|
22
|
+
*
|
|
23
|
+
* Almost every refusal happens before the first write, and saying so is
|
|
24
|
+
* most of the value of refusing. But a write that fails part-way is a
|
|
25
|
+
* DIFFERENT state — the roster and configuration are live while the
|
|
26
|
+
* schemas are one publish behind — and it is the state a caller most
|
|
27
|
+
* needs to hear about. Carried as a field rather than left for the
|
|
28
|
+
* caller to infer from prose, because a caller that guesses will guess
|
|
29
|
+
* "nothing was written": that is what every other failure means. */
|
|
30
|
+
partial: boolean;
|
|
31
|
+
} | {
|
|
32
|
+
ok: true;
|
|
33
|
+
aid: string;
|
|
34
|
+
cids: string[];
|
|
35
|
+
created: boolean;
|
|
36
|
+
commit?: string | undefined;
|
|
37
|
+
dirty: boolean;
|
|
38
|
+
/** How many live records the pre-check found that the published schemas
|
|
39
|
+
* reject — and whether that number is a FLOOR.
|
|
40
|
+
*
|
|
41
|
+
* `validateCollectionRecords` stops at its own cap per collection, so a
|
|
42
|
+
* full batch means "at least this many". The count and the cap travel
|
|
43
|
+
* together because they are read together: a caller that reports the
|
|
44
|
+
* number without the flag understates how much repair is owed, on the
|
|
45
|
+
* one path (a confirmed publish) where the damage is already done. */
|
|
46
|
+
recordIssues: number;
|
|
47
|
+
recordIssuesCapped: boolean;
|
|
48
|
+
published: PublishedApp;
|
|
49
|
+
};
|
|
50
|
+
/** Publish this repository's declaration to its app.
|
|
51
|
+
*
|
|
52
|
+
* Everything variable is a parameter or comes from the host binding, so the
|
|
53
|
+
* whole path is exercisable against an in-memory `FirestoreDocs` with no
|
|
54
|
+
* network and no API key — which is the only way the conversion table gets
|
|
55
|
+
* tested as a table. */
|
|
56
|
+
export declare function publishApp(opts?: PublishOptions): Promise<PublishResult>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { AuthoredApp, AuthoredSubmit } from './publishManifest';
|
|
2
|
+
/** What publish knows about a shared collection in this repository, as far as
|
|
3
|
+
* these checks are concerned: its cid and the schema key its records are
|
|
4
|
+
* identified by. The whole schema is deliberately not threaded in — these
|
|
5
|
+
* checks are about the DECLARATION, and the primary key is the one part of
|
|
6
|
+
* the schema the declaration can contradict. */
|
|
7
|
+
export interface PublishableCollection {
|
|
8
|
+
cid: string;
|
|
9
|
+
primaryKey: string;
|
|
10
|
+
}
|
|
11
|
+
/** Does this submit declaration bind a record to the submitter's identity?
|
|
12
|
+
*
|
|
13
|
+
* The condition for requiring `submitOnly`, and deliberately NOT "declares an
|
|
14
|
+
* `audience`": `audience` appears only in the rules' public-create branch, so
|
|
15
|
+
* an owner or editor never meets it and can add records freely. `immutable`
|
|
16
|
+
* is the wrong condition too — a survey's responses are not immutable and
|
|
17
|
+
* can be padded exactly the same way.
|
|
18
|
+
*
|
|
19
|
+
* What these four have in common is that each one makes the record MEAN "the
|
|
20
|
+
* person who submitted it said this": a per-uid id, a per-uid+field id, a
|
|
21
|
+
* row stamped with the submitter's verified address, or a submission
|
|
22
|
+
* restricted to a named participant. A record created through the writer
|
|
23
|
+
* branch carries the same shape and none of that meaning. */
|
|
24
|
+
export declare function bindsSubmitterIdentity(submit: AuthoredSubmit): boolean;
|
|
25
|
+
/** Everything publish refuses, as lines the author can act on.
|
|
26
|
+
*
|
|
27
|
+
* All of them, every time. Publish is a manual step with a human waiting on
|
|
28
|
+
* it; stopping at the first problem turns one review into five. */
|
|
29
|
+
export declare function publishProblems(app: AuthoredApp, collections: readonly PublishableCollection[], publisherEmail: string): string[];
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/** The four roles the deployed rules understand. `participant` is the layer
|
|
3
|
+
* that is NAMED but reads only its own rows — see `readerOf` vs `listedIn`. */
|
|
4
|
+
export declare const APP_ROLES: readonly ["owner", "editor", "viewer", "participant"];
|
|
5
|
+
/** The declarative mail queue, as the rules re-derive it: a transition of the
|
|
6
|
+
* status field, a recipient read off the RECORD, and a fixed template. */
|
|
7
|
+
declare const MailZ: z.ZodObject<{
|
|
8
|
+
toField: z.ZodString;
|
|
9
|
+
on: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
10
|
+
from: z.ZodArray<z.ZodString>;
|
|
11
|
+
to: z.ZodString;
|
|
12
|
+
}, z.core.$strict>>;
|
|
13
|
+
dataFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
14
|
+
}, z.core.$strict>;
|
|
15
|
+
/** What the rules read out of `collections[cid]`. NOT the schema — the schema
|
|
16
|
+
* is published beside it, untouched, for clients to render from. */
|
|
17
|
+
declare const CollectionConfigZ: z.ZodObject<{
|
|
18
|
+
statusField: z.ZodOptional<z.ZodString>;
|
|
19
|
+
transitions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
|
|
20
|
+
immutable: z.ZodOptional<z.ZodBoolean>;
|
|
21
|
+
submitOnly: z.ZodOptional<z.ZodBoolean>;
|
|
22
|
+
peerVisibility: z.ZodOptional<z.ZodEnum<{
|
|
23
|
+
public: "public";
|
|
24
|
+
hidden: "hidden";
|
|
25
|
+
}>>;
|
|
26
|
+
revealGated: z.ZodOptional<z.ZodBoolean>;
|
|
27
|
+
gatedFrom: z.ZodOptional<z.ZodString>;
|
|
28
|
+
revealBy: z.ZodOptional<z.ZodString>;
|
|
29
|
+
mail: z.ZodOptional<z.ZodObject<{
|
|
30
|
+
toField: z.ZodString;
|
|
31
|
+
on: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
32
|
+
from: z.ZodArray<z.ZodString>;
|
|
33
|
+
to: z.ZodString;
|
|
34
|
+
}, z.core.$strict>>;
|
|
35
|
+
dataFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
36
|
+
}, z.core.$strict>>;
|
|
37
|
+
aggregate: z.ZodOptional<z.ZodObject<{
|
|
38
|
+
by: z.ZodArray<z.ZodString>;
|
|
39
|
+
}, z.core.$strict>>;
|
|
40
|
+
}, z.core.$strict>;
|
|
41
|
+
declare const SubmitZ: z.ZodObject<{
|
|
42
|
+
auth: z.ZodEnum<{
|
|
43
|
+
none: "none";
|
|
44
|
+
anonymous: "anonymous";
|
|
45
|
+
verifiedEmail: "verifiedEmail";
|
|
46
|
+
}>;
|
|
47
|
+
emailField: z.ZodOptional<z.ZodString>;
|
|
48
|
+
createFields: z.ZodArray<z.ZodString>;
|
|
49
|
+
initialStatus: z.ZodOptional<z.ZodString>;
|
|
50
|
+
idFrom: z.ZodOptional<z.ZodEnum<{
|
|
51
|
+
auto: "auto";
|
|
52
|
+
"auth.uid": "auth.uid";
|
|
53
|
+
"auth.uid+field": "auth.uid+field";
|
|
54
|
+
}>>;
|
|
55
|
+
idField: z.ZodOptional<z.ZodString>;
|
|
56
|
+
validate: z.ZodOptional<z.ZodObject<{
|
|
57
|
+
required: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
58
|
+
keyFields: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
59
|
+
field: z.ZodString;
|
|
60
|
+
values: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
|
|
61
|
+
}, z.core.$strict>>>;
|
|
62
|
+
}, z.core.$strict>>;
|
|
63
|
+
window: z.ZodOptional<z.ZodObject<{
|
|
64
|
+
from: z.ZodOptional<z.ZodISODateTime>;
|
|
65
|
+
until: z.ZodOptional<z.ZodISODateTime>;
|
|
66
|
+
}, z.core.$strict>>;
|
|
67
|
+
selfUpdate: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
|
|
68
|
+
selfTransitions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
|
|
69
|
+
finalize: z.ZodOptional<z.ZodBoolean>;
|
|
70
|
+
audience: z.ZodOptional<z.ZodLiteral<"participant">>;
|
|
71
|
+
gateOn: z.ZodOptional<z.ZodObject<{
|
|
72
|
+
phase: z.ZodString;
|
|
73
|
+
match: z.ZodString;
|
|
74
|
+
}, z.core.$strict>>;
|
|
75
|
+
}, z.core.$strict>;
|
|
76
|
+
/** The whole authored declaration.
|
|
77
|
+
*
|
|
78
|
+
* `owner` is accepted but is NOT the published value — publish stamps the
|
|
79
|
+
* publisher's uid (or carries the existing one forward, which is what the
|
|
80
|
+
* rules require on update) and refuses a declaration that disagrees. It is
|
|
81
|
+
* accepted rather than banned because the sample app.json in the design note
|
|
82
|
+
* shows it, and a hard refusal on a key the samples contain would be a worse
|
|
83
|
+
* first experience than a message naming the mismatch. */
|
|
84
|
+
export declare const AuthoredAppZ: z.ZodObject<{
|
|
85
|
+
aid: z.ZodString;
|
|
86
|
+
name: z.ZodOptional<z.ZodString>;
|
|
87
|
+
aidEnv: z.ZodOptional<z.ZodString>;
|
|
88
|
+
owner: z.ZodOptional<z.ZodString>;
|
|
89
|
+
members: z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodUnion<readonly [z.ZodLiteral<"*">, z.ZodString]>, z.ZodEnum<{
|
|
90
|
+
owner: "owner";
|
|
91
|
+
editor: "editor";
|
|
92
|
+
viewer: "viewer";
|
|
93
|
+
participant: "participant";
|
|
94
|
+
}>>>;
|
|
95
|
+
collections: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
96
|
+
statusField: z.ZodOptional<z.ZodString>;
|
|
97
|
+
transitions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
|
|
98
|
+
immutable: z.ZodOptional<z.ZodBoolean>;
|
|
99
|
+
submitOnly: z.ZodOptional<z.ZodBoolean>;
|
|
100
|
+
peerVisibility: z.ZodOptional<z.ZodEnum<{
|
|
101
|
+
public: "public";
|
|
102
|
+
hidden: "hidden";
|
|
103
|
+
}>>;
|
|
104
|
+
revealGated: z.ZodOptional<z.ZodBoolean>;
|
|
105
|
+
gatedFrom: z.ZodOptional<z.ZodString>;
|
|
106
|
+
revealBy: z.ZodOptional<z.ZodString>;
|
|
107
|
+
mail: z.ZodOptional<z.ZodObject<{
|
|
108
|
+
toField: z.ZodString;
|
|
109
|
+
on: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
110
|
+
from: z.ZodArray<z.ZodString>;
|
|
111
|
+
to: z.ZodString;
|
|
112
|
+
}, z.core.$strict>>;
|
|
113
|
+
dataFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
114
|
+
}, z.core.$strict>>;
|
|
115
|
+
aggregate: z.ZodOptional<z.ZodObject<{
|
|
116
|
+
by: z.ZodArray<z.ZodString>;
|
|
117
|
+
}, z.core.$strict>>;
|
|
118
|
+
}, z.core.$strict>>>;
|
|
119
|
+
participantRead: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
120
|
+
public: z.ZodOptional<z.ZodObject<{
|
|
121
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
122
|
+
read: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
123
|
+
submit: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
124
|
+
auth: z.ZodEnum<{
|
|
125
|
+
none: "none";
|
|
126
|
+
anonymous: "anonymous";
|
|
127
|
+
verifiedEmail: "verifiedEmail";
|
|
128
|
+
}>;
|
|
129
|
+
emailField: z.ZodOptional<z.ZodString>;
|
|
130
|
+
createFields: z.ZodArray<z.ZodString>;
|
|
131
|
+
initialStatus: z.ZodOptional<z.ZodString>;
|
|
132
|
+
idFrom: z.ZodOptional<z.ZodEnum<{
|
|
133
|
+
auto: "auto";
|
|
134
|
+
"auth.uid": "auth.uid";
|
|
135
|
+
"auth.uid+field": "auth.uid+field";
|
|
136
|
+
}>>;
|
|
137
|
+
idField: z.ZodOptional<z.ZodString>;
|
|
138
|
+
validate: z.ZodOptional<z.ZodObject<{
|
|
139
|
+
required: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
140
|
+
keyFields: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
141
|
+
field: z.ZodString;
|
|
142
|
+
values: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
|
|
143
|
+
}, z.core.$strict>>>;
|
|
144
|
+
}, z.core.$strict>>;
|
|
145
|
+
window: z.ZodOptional<z.ZodObject<{
|
|
146
|
+
from: z.ZodOptional<z.ZodISODateTime>;
|
|
147
|
+
until: z.ZodOptional<z.ZodISODateTime>;
|
|
148
|
+
}, z.core.$strict>>;
|
|
149
|
+
selfUpdate: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
|
|
150
|
+
selfTransitions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
|
|
151
|
+
finalize: z.ZodOptional<z.ZodBoolean>;
|
|
152
|
+
audience: z.ZodOptional<z.ZodLiteral<"participant">>;
|
|
153
|
+
gateOn: z.ZodOptional<z.ZodObject<{
|
|
154
|
+
phase: z.ZodString;
|
|
155
|
+
match: z.ZodString;
|
|
156
|
+
}, z.core.$strict>>;
|
|
157
|
+
}, z.core.$strict>>>;
|
|
158
|
+
}, z.core.$strict>>;
|
|
159
|
+
}, z.core.$strict>;
|
|
160
|
+
export type AuthoredApp = z.infer<typeof AuthoredAppZ>;
|
|
161
|
+
export type AuthoredCollectionConfig = z.infer<typeof CollectionConfigZ>;
|
|
162
|
+
export type AuthoredSubmit = z.infer<typeof SubmitZ>;
|
|
163
|
+
export type AuthoredMail = z.infer<typeof MailZ>;
|
|
164
|
+
export type AuthoredAppResult = {
|
|
165
|
+
ok: true;
|
|
166
|
+
app: AuthoredApp;
|
|
167
|
+
} | {
|
|
168
|
+
ok: false;
|
|
169
|
+
problems: string[];
|
|
170
|
+
};
|
|
171
|
+
/** Parse the authored declaration out of `app.json`'s text.
|
|
172
|
+
*
|
|
173
|
+
* Returns a LIST of problems rather than throwing, for the same reason
|
|
174
|
+
* `loadAppManifest` returns a failure: the caller is a gate whose entire job
|
|
175
|
+
* is to hand the author something to act on. Every problem is reported at
|
|
176
|
+
* once — publish is a manual step, and a parser that stops at the first key
|
|
177
|
+
* makes it N round trips. */
|
|
178
|
+
export declare function parseAuthoredApp(raw: string): AuthoredAppResult;
|
|
179
|
+
/** zod issues as one actionable line each: `public.submit.responses.auth: …`. */
|
|
180
|
+
export declare function authoredProblems(error: z.ZodError): string[];
|
|
181
|
+
export {};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { CollectionSchema } from '../core/schema';
|
|
2
|
+
import { AuthoredApp } from './publishManifest';
|
|
3
|
+
/** Who and when. Threaded in rather than read from a clock inside the
|
|
4
|
+
* projection so the projection stays pure and the tests can assert on an
|
|
5
|
+
* exact document. */
|
|
6
|
+
export interface PublishStamp {
|
|
7
|
+
/** The publisher's Firebase uid. The rules require `owner ==
|
|
8
|
+
* request.auth.uid` on CREATE and `owner` unchanged on UPDATE, so this is
|
|
9
|
+
* used only when the app document does not exist yet. */
|
|
10
|
+
uid: string;
|
|
11
|
+
/** The publisher's verified email — the principal the roster is keyed by. */
|
|
12
|
+
email: string;
|
|
13
|
+
/** Wall-clock millis of this publish. */
|
|
14
|
+
publishedAt: number;
|
|
15
|
+
/** The git commit the declaration was read from, when the host could
|
|
16
|
+
* resolve one. Absent is a normal state (a dirty tree, a repository
|
|
17
|
+
* without git), and absent is more honest than a fabricated value. */
|
|
18
|
+
commit?: string | undefined;
|
|
19
|
+
}
|
|
20
|
+
/** One collection's published schema document (`apps/{aid}/collections/{cid}`).
|
|
21
|
+
*
|
|
22
|
+
* The rules never read `publishedSchema` — `schemaRead` gates the whole
|
|
23
|
+
* document and stops there. It is here for the CLIENTS: a member's host
|
|
24
|
+
* renders from it, and a public webview has no other way to know the fields.
|
|
25
|
+
* The whole schema is published rather than a projection of it, because
|
|
26
|
+
* every attempt to guess "the part a view needs" is a guess about a view
|
|
27
|
+
* that has not been written yet. */
|
|
28
|
+
export interface PublishedSchemaDoc extends Record<string, unknown> {
|
|
29
|
+
publishedSchema: CollectionSchema;
|
|
30
|
+
publishedAt: number;
|
|
31
|
+
publishedBy: string;
|
|
32
|
+
publishedCommit?: string;
|
|
33
|
+
}
|
|
34
|
+
/** The public settings document (`apps/{aid}/config/public`).
|
|
35
|
+
*
|
|
36
|
+
* `allow read: if true` — this is the one document an anonymous visitor can
|
|
37
|
+
* read, and it is the reason `apps/{aid}` itself is reader-only: a
|
|
38
|
+
* participant reading the app document would see their classmates'
|
|
39
|
+
* addresses. So the roster is NOT here, and neither is `owner`. What is here
|
|
40
|
+
* is what a public form needs in order to render itself and to tell a visitor
|
|
41
|
+
* "this closed yesterday" instead of failing a write with no explanation. */
|
|
42
|
+
export interface PublishedConfigDoc extends Record<string, unknown> {
|
|
43
|
+
name?: string;
|
|
44
|
+
enabled: boolean;
|
|
45
|
+
read: string[];
|
|
46
|
+
submit: Record<string, Record<string, unknown>>;
|
|
47
|
+
publishedAt: number;
|
|
48
|
+
}
|
|
49
|
+
/** Everything one publish writes. Separate documents because they live at
|
|
50
|
+
* separate paths with separate rules — and in the order given: the app
|
|
51
|
+
* document authorizes the other two, so it goes first. */
|
|
52
|
+
export interface PublishedApp {
|
|
53
|
+
app: Record<string, unknown>;
|
|
54
|
+
schemas: {
|
|
55
|
+
cid: string;
|
|
56
|
+
doc: PublishedSchemaDoc;
|
|
57
|
+
}[];
|
|
58
|
+
config: PublishedConfigDoc;
|
|
59
|
+
}
|
|
60
|
+
/** The document id under `apps/{aid}/config`. One document, named, rather than
|
|
61
|
+
* a spread of them: a second public document is a second thing to keep in
|
|
62
|
+
* step, and nothing yet needs one. */
|
|
63
|
+
export declare const PUBLIC_CONFIG_DOC = "public";
|
|
64
|
+
/** Project the authored declaration into the documents publish writes.
|
|
65
|
+
*
|
|
66
|
+
* `existing` is the app document as it is in Firestore right now, or null on
|
|
67
|
+
* a first publish. Two things need it, both required by the rules:
|
|
68
|
+
* - `owner` must be UNCHANGED on update. Re-stamping the publisher's uid
|
|
69
|
+
* would be refused for any app whose owner ever signed in as a different
|
|
70
|
+
* account, and would silently transfer ownership if it were not.
|
|
71
|
+
* - `previousPublished` is that document, so a rollback has something to
|
|
72
|
+
* put back.
|
|
73
|
+
*
|
|
74
|
+
* Pure: no clock, no filesystem, no Firestore. Everything variable arrives as
|
|
75
|
+
* a parameter, which is what makes the conversion table testable as a table. */
|
|
76
|
+
export declare function projectApp(authored: AuthoredApp, schemas: {
|
|
77
|
+
cid: string;
|
|
78
|
+
schema: CollectionSchema;
|
|
79
|
+
}[], stamp: PublishStamp, existing: Record<string, unknown> | null): PublishedApp;
|
|
80
|
+
/** The app documents' parent path — the `FirestoreDocs` seam takes a
|
|
81
|
+
* collection path plus a document id, and the app document's id is the aid. */
|
|
82
|
+
export declare const APPS_COLLECTION = "apps";
|
|
83
|
+
/** The collection (schema) documents' parent path. */
|
|
84
|
+
export declare const appSchemasPath: (aid: string) => string;
|
|
85
|
+
/** The public-config documents' parent path. */
|
|
86
|
+
export declare const appConfigPath: (aid: string) => string;
|
|
@@ -8,6 +8,18 @@ export interface RecordIssue {
|
|
|
8
8
|
/** Human-readable problem, written to be actionable by the LLM. */
|
|
9
9
|
problem: string;
|
|
10
10
|
}
|
|
11
|
+
/** Don't flood the result; the first batch is enough to act on. Exported
|
|
12
|
+
* because a caller that REPORTS a count has to know the count is a floor —
|
|
13
|
+
* `publish` presents a full batch as "at least N" rather than as a total. */
|
|
14
|
+
export declare const MAX_RECORD_ISSUES = 25;
|
|
15
|
+
/** The `file` of the pseudo-issue reported when the backend could not be read
|
|
16
|
+
* at all.
|
|
17
|
+
*
|
|
18
|
+
* Exported because it is a DIFFERENT KIND of answer from "this record is
|
|
19
|
+
* invalid", and a caller that treats the two alike gets it wrong in the
|
|
20
|
+
* direction that matters: `publish` lets the user override invalid records,
|
|
21
|
+
* and overriding this one would mean publishing without ever having looked. */
|
|
22
|
+
export declare const STORE_UNREADABLE = "(store)";
|
|
11
23
|
export declare function validateCollectionRecords(collection: LoadedCollection, opts?: {
|
|
12
24
|
workspaceRoot?: string | undefined;
|
|
13
25
|
}): Promise<RecordIssue[]>;
|