jason810496 commented on code in PR #73436:
URL: https://github.com/apache/airflow/pull/73436#discussion_r4089837288


##########
ts-sdk/src/sdk/dag.ts:
##########
@@ -32,31 +38,58 @@ function isPlainRecord(value: unknown): value is 
Record<string, unknown> {
   return prototype === Object.prototype || prototype === null;
 }
 
-function validateEmptySpec(name: string, value: unknown): void {
-  if (!isPlainRecord(value) || Reflect.ownKeys(value).length > 0) {
-    throw new Error(`${name} must be an empty object`);
+/**
+ * A copy of `spec` that nothing can change afterwards.
+ *
+ * Nothing reads a spec until the Dag is packed, long after the author's module
+ * has run, so an edit of the object they passed would silently change what
+ * ships. A shallow freeze is not enough: `tags` is an array the author still
+ * holds a reference to.
+ */
+function freezeSpec<TSpec extends object>(spec: TSpec, describe: () => 
string): TSpec {
+  return deepFreeze(spec, describe, new WeakSet()) as TSpec;
+}
+
+function deepFreeze(value: unknown, describe: () => string, seen: 
WeakSet<object>): unknown {
+  if (typeof value !== "object" || value === null) return value;
+  if (seen.has(value)) {
+    throw new Error(`${describe()} refers back to itself, so it cannot be 
recorded`);
   }
+  seen.add(value);
+  if (Array.isArray(value)) {
+    return Object.freeze(value.map((element) => deepFreeze(element, describe, 
seen)));
+  }
+  if (!isPlainRecord(value)) return value;
+  const copy: Record<string, unknown> = {};
+  for (const [key, nested] of Object.entries(value)) {
+    copy[key] = deepFreeze(nested, describe, seen);
+  }

Review Comment:
   Good catch — `startDate` and `endDate` are typed `Date`, so this is 
reachable from the typed API: `deepFreeze` returned the author's Date 
untouched, and `Object.freeze` would not have stopped `setFullYear` anyway. It 
now copies a Date (`new Date(value.getTime())`) and throws for any other 
non-plain object rather than passing it through unfrozen.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to