@sequenceholdings/orm 2.7.0 → 2.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -131,6 +131,37 @@ Execute uses the `/_data/v2` endpoint by default. Set
131
131
  `SEQUENCE_ORM_ATLAS_EXECUTE_V2=1` to opt into Atlas's `/api/data/v2` endpoint.
132
132
  This client rollout switch does not bypass server feature flags or authorization.
133
133
 
134
+ ## Internal synced dependencies
135
+
136
+ Use `internal: true` on a typed, keyed `defineSyncedTable` when its rows are
137
+ inputs to a managed view and must not be queried directly. The reflected source
138
+ and its read policy remain available inside the view. Internal sources are
139
+ excluded from GraphQL roots and links, default SQL, and registered SQL object
140
+ ceilings. A missing persisted operation alone does not make a source private.
141
+ Authoring rejects declared links targeting an internal synced source and
142
+ rejects exporting it. This also prevents dynamic predicates from reaching it
143
+ through hidden intermediate relations or cross-namespace links.
144
+
145
+ ```ts
146
+ const privacy = defineSyncedTable("privacy", {
147
+ uid: t.text().primaryKey(),
148
+ restricted: t.boolean().notNull(),
149
+ }, { source: "gold.customer_privacy", internal: true, policies: { read: "true" } });
150
+ if (privacy.config.internal !== true) {
151
+ throw new Error("Upgrade the ORM SDK: internal synced dependencies are required.");
152
+ }
153
+ ```
154
+
155
+ Publish only the permitted projection through `defineView`, with its own read
156
+ policy. Declaring `internal` does not grant access to the source or change row
157
+ policies. The existing unkeyed-source restrictions remain in force.
158
+
159
+ This authoring addition needs a released SDK containing the option. The existing
160
+ Atlas internal-object exclusion remains the runtime boundary; do not replace
161
+ the declaration with casts or edits to generated canonical JSON. ORM releases
162
+ use the separate [Studio CLI chain release workflow](https://github.com/sequenceholdings/studio/blob/main/.changeset/README.md#studio-cli-chain-releases);
163
+ chain packages do not use Changesets.
164
+
134
165
  ## Default read-only SQL (introduced in 2.6.0)
135
166
 
136
167
  With the matching SDK and Atlas rollout, every active v2 namespace supports
@@ -387,6 +387,7 @@ function defineSyncedTable(name2, columnsOrConfig, maybeConfig) {
387
387
  if (config.primaryKey !== void 0) tableConfig.primaryKey = config.primaryKey;
388
388
  if (config.links !== void 0) tableConfig.links = config.links;
389
389
  if (config.policies !== void 0) tableConfig.policies = { read: config.policies.read };
390
+ if (config.internal === true) tableConfig.internal = true;
390
391
  const table = {
391
392
  kind: TABLE_BRAND,
392
393
  tableName: name2,
@@ -2748,6 +2749,11 @@ function serializeNamespace(input) {
2748
2749
  enumsByName.set(ref.name, ref);
2749
2750
  }
2750
2751
  const canonicalTables = tables.map((table) => buildCanonicalTable({ table, relationsByName, enumsByName }));
2752
+ for (const table of tables) {
2753
+ if (table.source !== void 0 && table.config.internal === true && config.exports && Object.hasOwn(config.exports, table.tableName)) {
2754
+ throw new OrmDefinitionError(`internal synced source "${table.tableName}" cannot be exported; export a permitted managed view instead`, table.file);
2755
+ }
2756
+ }
2751
2757
  const canonicalEnums = [...enumsByName.values()].map((ref) => ({
2752
2758
  name: ref.name,
2753
2759
  values: [...ref.values]
@@ -3081,6 +3087,9 @@ function buildCanonicalLink({
3081
3087
  if (!relationsByName.has(targetName)) {
3082
3088
  return fail(`targets ${relationKind(target)} "${targetName}" which is not part of this namespace`);
3083
3089
  }
3090
+ if (isSeqTable(target) && target.source !== void 0 && target.config.internal === true) {
3091
+ return fail(`targets internal synced source "${targetName}"; expose a permitted managed view instead`);
3092
+ }
3084
3093
  if (link.enforce && (!isSeqTable(relation) || !isSeqTable(target))) {
3085
3094
  return fail("cannot enforce a PostgreSQL foreign key involving a view");
3086
3095
  }